I spent some time figuring out why webdavfs was not working with file-storage. Mostly it's not so much problems on the OS X side, but it was all annoying to track down. I guess I would make a bad protocol wonk. Mostly I used tcpdump and watched what went back and forth to diagnose problems.
Here is what I found:
Problem 1
The WebDAVFS client wants a Content-Length header on GET or it bails (at least on file create).
GET /dav/fs/43mm.txt HTTP/1.1 User-Agent: WebDAVFS/1.2.7 (01278000) Darwin/7.3.0 (Power Macintosh) Accept: */* Host: g2.xarg.net:8003 Authorization: Basic SasdK88KFKJFJKSDJFKS==
returns:
HTTP/1.1 200 OK Set-Cookie: ad_session_id=50135%2c0%2c0+%7b648+1080641968+778CF7DB0A7EA7DBB4FEB2019E81727893F138A0%7d; Path=/; Max-Age=1200 Last-Modified: Tue, 30 Mar 2004 09:59:28 GMT MIME-Version: 1.0 Date: Tue, 30 Mar 2004 09:59:28 GMT Server: AOLserver/4.0 Content-Type: text/plain Connection: close
There is no Content-Length header provided. Subsequent to that it just PROPFINDs the main dir again so the absence of content-length make it thing the previous PUT failed.
Solution 1
Bashing in the content-length header allows it to proceed. I added:
set size [file size $filename]
if {!$size} {
ns_set put [ns_conn outputheaders] "Content-Length" 0
}
in the file branch of cr_write_content.
Note that this means files stored in the DB won't work I think since the content length header is not sent for them.
Problem 2
OS.X WebDAVFS is unhappy without LOCK and UNLOCK it seems.
Solution 2
I added them to the OPTIONS for tdav which leads immediately to problem number 3
Problem 3
LOCKing does not work.
OS.X LOCKs then PUTs but gets a 423 on PUT even though it sent the correct token back.
LOCK /dav/fs/43mm.txt HTTP/1.1 User-Agent: WebDAVFS/1.2.7 (01278000) Darwin/7.3.0 (Power Macintosh) Accept: */* Host: g2.xarg.net:8003 Depth: 0 Timeout: Second-600 Content-Type: text/xml; charset="utf-8" Content-Length: 213 Authorization: Basic SasdK88KFKJFJKSDJFKS== <?xml version="1.0" encoding="utf-8" ?> <D:lockinfo xmlns:D="DAV:"> <D:lockscope><D:exclusive/></D:lockscope> <D:locktype><D:write/></D:locktype> <D:owner> <D:href>default-owner</D:href> </D:owner> </D:lockinfo>
Gets back:
HTTP/1.1 200 OK
Lock-Token: <opaquelocktoken:551830752>
MIME-Version: 1.0
Date: Tue, 30 Mar 2004 10:00:52 GMT
Server: AOLserver/4.0
Content-Type: text/html; charset=iso8859-1
Content-Length: 332
Connection: close
<?xml version="1.0" encoding="utf-8"?>
<prop xmlns="DAV:">
<lockdiscovery>
<activelock>
<locktype><D:write/></locktype>
<lockscope><D:exclusive/></lockscope>
<depth>0</depth>
<owner></owner><timeout>Second-</timeout>
<locktoken>
<href>opaquelocktoken:551830752</href>
</locktoken>
</activelock>
</lockdiscovery>
</prop>
sends:
GET /dav/fs/43mm.txt HTTP/1.1 User-Agent: WebDAVFS/1.2.7 (01278000) Darwin/7.3.0 (Power Macintosh) Accept: */* Host: g2.xarg.net:8003 Authorization: Basic SasdK88KFKJFJKSDJFKS== If-Modified-Since: Tue, 30 Mar 2004 10:00:51 GMT
gets back:
HTTP/1.1 304 Not Modified Set-Cookie: ad_session_id=50137%2c0%2c0+%7b637+1080642052+9C0BE0849A09203E76F364766FB2557DC80B4DDE%7d; Path=/; Max-Age=1200 Content-Length: 0 Last-Modified: Tue, 30 Mar 2004 10:00:51 GMT MIME-Version: 1.0 Date: Tue, 30 Mar 2004 10:00:52 GMT Server: AOLserver/4.0 Connection: close
The content-length on the 304 is there since I bashed it in, normally I think you would not get it.
Now finally on the actual PUT OSX sends:
PUT /dav/fs/43mm.txt HTTP/1.1 User-Agent: WebDAVFS/1.2.7 (01278000) Darwin/7.3.0 (Power Macintosh) Accept: */* Host: g2.xarg.net:8003 Content-Length: 402 If:(<opaquelocktoken:551830752>) Authorization: Basic SasdK88KFKJFJKSDJFKS==
but sadly gets:
HTTP/1.1 423 Locked MIME-Version: 1.0 Date: Tue, 30 Mar 2004 10:00:52 GMT Server: AOLserver/4.0 Content-Type: text/plain; charset=iso8859-1 Connection: close
At which point it fails. oh dear!
Solution 3
The code for locking has this:
regexp {<http://[^/]+([^>]+)>\s+\(<([^>]+)>\)} $hdr nil hdr_uri token
but the Header is If:(<opaquelocktoken:551830752>, So I changed it to:
regexp {(<http://[^/]+([^>]+)>\s+)?\(<([^>]+)>\)} $hdr nil maybe hdr_uri token
which seemed to the locking issue.
Problem 4
mysterious error creating the content item.
Solution 4
Easy one: oacs_dav::impl::content_revision::put had tmp_filename and tmp_size transposed for the call with item_id provided.
Possible remaining issues
I changed this:
<fullquery
name="oacs_dav::impl::content_folder::propfind.get_properties">
<querytext>
- select coalesce (cr.content_length,4096) as content_length,
+ select coalesce (cr.content_length,0) as content_length,
since I don't understand why you would assume 4096 rather than 0. Is that wrong?
The dav stuff seems to be bad at cleaning up after itself (lots of junk in /tmp and I suspect the data/dav dir is not kept very clean).
There are some remaining mystery failures on the Mac (fails to save stuff) and there are secret mac files which should probably be hidden and which might need to be treated carefully if there were a lot of mac users. cf apache bugzilla. In fact it's probably worth looking at all the Apache WebDAV server bugs.
