Project

General

Profile

Feature #1818

add RFC-compliant LOCK support to mod_webdav

Added by Anonymous over 10 years ago. Updated 27 days ago.

Status:
Fixed
Priority:
Low
Assignee:
-
Category:
mod_webdav
Target version:
Start date:
2008-11-09
Due date:
% Done:

100%

Estimated time:
Missing in 1.5.x:

Description

The Litmus WebDAV test suite issues certain PUT requests, which is seemed to not processed by Lighty at all. A wireshark dump (see attachement) shows that the request is send, but Lighty does not respond (neither with mod_dav, nor plainly) in any way. Switching all request/response debugging on did not show any log messages.

The issue was tested and occurs with Litmus 0.11 and 0.12.1. The attached file shows an extract of the Wireshark dump of a Litmus 0.11 session. The LOCK request before the PUT works fine. No response to the PUT request is issued.

litmus_put_request (3.93 KB) litmus_put_request Wireshark dump: PUT request by Litmus 0.11 Anonymous, 2008-11-09 12:34

Associated revisions

Revision 80bb4226 (diff)
Added by gstrauss about 3 years ago

[mod_webdav] improve PROPFIND,PROPPATCH (#1818, #1953)

fix "allprop" propfind request to report all 'live' properties
add "supportedlock" 'live' property, if ./configure --with-webdav-locks
report collections (directory) paths with trailing slash ('/') on path
redirect operations on collections without trailing slash ('/') to URI
with trailing slash ('/')

fix PROPPATCH to work properly and eliminate PROPPATCH memory leak
fix property update after MOVE
move CREATE TABLE statements before any prepare statements to avoid
invalidating the prepare statements when the tables are first created
**thx Uranus Zhou for the explanation:
https://zohead.com/archives/lighty-sqlite-err/?lang=en

x-ref:
"Improve DAV support to be able to handle git as a client"
https://redmine.lighttpd.net/issues/1953
"add RFC-compliant LOCK support to mod_webdav" (still not compliant)
https://redmine.lighttpd.net/issues/1818

Note: this has not been tested whether or not mod_webdav works with git
The (highly) recommended method to support git via HTTP is to use
git-http-backend via CGI. gitolite and gitosis provide other good
alternative ways to access git.

This patch does result in more WebDAV 'Litmus' tests passing, even
though mod_webdav still pretends to implement "If" conditional locking,
granting locks to all requestors and not strictly enforcing locks.

Revision 50aae03c (diff)
Added by gstrauss 27 days ago

[mod_webdav] major rewrite (fixes #1818)

(occurred 3 years ago on experimental branch, and now ported forward)

robustness and performance improvements, including atomic updates on
individual files (e.g. for PUT, COPY, MOVE)

exclusive locks are fully supported
shared locks are partly supported

x-ref:
"add RFC-compliant LOCK support to mod_webdav"
https://redmine.lighttpd.net/issues/1818

Revision eee29b65 (diff)
Added by gstrauss 27 days ago

[mod_webdav] check If-Match, If-Unmodified-Since (#1818)

x-ref:
"add RFC-compliant LOCK support to mod_webdav"
https://redmine.lighttpd.net/issues/1818

Revision 5ac92dca (diff)
Added by gstrauss 26 days ago

[mod_webdav] check If-None-Match (#1818)

x-ref:
"add RFC-compliant LOCK support to mod_webdav"
https://redmine.lighttpd.net/issues/1818

History

#1

Updated by gstrauss about 3 years ago

  • Priority changed from High to Low

Lighttpd 1.4.x mod_webdav does not properly support LOCK -- it fakes it. This is documented in mod_webdav.c. Not supporting LOCK is definitely a bug because lighttpd advertises "DAV: 1,2" in response to an OPTIONS request, and Class 2 is LOCK support. lighttpd is lying when it advertises that it supports LOCK. Attempting to fake LOCK support was apparently(?) done as a minimal effort to support webdav requests from Microsoft Windows XP as webdav client. (Can anyone confirm that?) Changing lighttpd to advertise only "DAV: 1" might break some client (unverified). On the other hand, implementing proper LOCK support in mod_webdav.c is a lot more than a bug fix. Moving this ticket to Low priority.

FYI: most (not all) other Litmus 0.13 tests pass, excepting the LOCK tests, where most of the tests fail.

(BTW, the segmentation fault in /usr/bin/litmus is a bug in /usr/bin/litmus. I'll be submitting a patch upstream to fix that.)

$ /usr/bin/litmus -k http://127.0.0.1:8080/ -d /home/lighttpd/opt/srv/www
-> running `basic':
 0. init.................. pass
 1. begin................. pass
 2. options............... pass
 3. put_get............... pass
 4. put_get_utf8_segment.. pass
 5. put_no_parent......... pass
 6. mkcol_over_plain...... pass
 7. delete................ pass
 8. delete_null........... pass
 9. delete_fragment....... WARNING: DELETE removed collection resource with Request-URI including fragment; unsafe
    ...................... pass (with 1 warning)
10. mkcol................. pass
11. mkcol_again........... pass
12. delete_coll........... pass
13. mkcol_no_parent....... pass
14. mkcol_with_body....... pass
15. finish................ pass
<- summary for `basic': of 16 tests run: 16 passed, 0 failed. 100.0%
-> 1 warning was issued.
-> running `copymove':
 0. init.................. pass
 1. begin................. pass
 2. copy_init............. pass
 3. copy_simple........... pass
 4. copy_overwrite........ WARNING: COPY to existing resource should give 204 (RFC2518:S8.8.5), got 201 Created
    ...................... pass (with 1 warning)
 5. copy_nodestcoll....... pass
 6. copy_cleanup.......... pass
 7. copy_coll............. pass
 8. copy_shallow.......... pass
 9. move.................. WARNING: MOVE to existing collection resource didn't give 204
    ...................... pass (with 1 warning)
10. move_coll............. pass
11. move_cleanup.......... pass
12. finish................ pass
<- summary for `copymove': of 13 tests run: 13 passed, 0 failed. 100.0%
-> 2 warnings were issued.
-> running `props':
 0. init.................. pass
 1. begin................. pass
 2. propfind_invalid...... pass
 3. propfind_invalid2..... FAIL (PROPFIND with invalid namespace declaration in body (see FAQ) got 207 response not 400)
 4. propfind_d0........... pass
 5. propinit.............. pass
 6. propset............... pass
 7. propget............... pass
 8. propextended.......... pass
 9. propmove.............. pass
10. propget............... FAIL (No value given for property {http://example.com/neon/litmus/}prop9)
11. propdeletes........... pass
12. propget............... pass
13. propreplace........... pass
14. propget............... pass
15. propnullns............ pass
16. propget............... pass
17. prophighunicode....... pass
18. propget............... pass
19. propremoveset......... pass
20. propget............... pass
21. propsetremove......... pass
22. propget............... pass
23. propvalnspace......... pass
24. propwformed........... pass
25. propinit.............. pass
26. propmanyns............ pass
27. propget............... pass
28. propcleanup........... pass
29. finish................ pass
<- summary for `props': of 30 tests run: 28 passed, 2 failed. 93.3%
-> running `locks':
 0. init.................. pass
 1. begin................. pass
 2. options............... pass
 3. precond............... pass
 4. init_locks............ pass
 5. put................... pass
 6. lock_excl............. pass
 7. discover.............. pass
 8. refresh............... pass
 9. notowner_modify....... FAIL (DELETE of locked resource should fail)
10. notowner_lock......... FAIL (LOCK on locked resource)
11. owner_modify.......... pass
12. notowner_modify....... FAIL (DELETE of locked resource should fail)
13. notowner_lock......... FAIL (LOCK on locked resource)
14. copy.................. FAIL (could not COPY locked resource:
404 Not Found)
15. cond_put.............. SKIPPED
16. fail_cond_put......... SKIPPED
17. cond_put_with_not..... pass
18. cond_put_corrupt_token FAIL (conditional PUT with invalid lock-token should fail: 200 OK)
19. complex_cond_put...... SKIPPED
20. fail_complex_cond_put. SKIPPED
21. unlock................ FAIL (UNLOCK on `/litmus/lockme': 401 Unauthorized)
22. fail_cond_put_unlocked FAIL (conditional PUT with invalid lock-token should fail: 200 OK)
23. lock_shared........... pass
24. notowner_modify....... FAIL (DELETE of locked resource should fail)
25. notowner_lock......... FAIL (LOCK on locked resource)
26. owner_modify.......... pass
27. double_sharedlock..... FAIL (unlock of second shared lock:
401 Unauthorized)
28. notowner_modify....... FAIL (DELETE of locked resource should fail)
29. notowner_lock......... FAIL (LOCK on locked resource)
30. unlock................ FAIL (UNLOCK on `/litmus/lockme': 401 Unauthorized)
31. prep_collection....... FAILED - segmentation fault
/usr/bin/litmus: line 47: 18368 Segmentation fault      (core dumped) ${tprog} --htdocs ${HTDOCS} "$@" 
-> running `http':
 0. init.................. pass
 1. begin................. pass
 2. expect100............. pass
 3. finish................ pass
<- summary for `http': of 4 tests run: 4 passed, 0 failed. 100.0%
#2

Updated by gstrauss about 3 years ago

  • Category changed from core to mod_webdav
#3

Updated by gstrauss about 3 years ago

  • Tracker changed from Bug to Feature
  • Subject changed from A certain PUT request not handled at all to add RFC-compliant LOCK support to mod_webdav

changed ticket to feature request and updated title

The mod_webdav DAV: 1,2 advertisement was added to minimally support some clients, so removing it risks breaking existing installations.

#4

Updated by gstrauss about 3 years ago

$ /usr/bin/litmus -k http://127.0.0.1:8080/ -d /home/lighttpd/opt/srv/www
-> running `basic':
 0. init.................. pass
 1. begin................. pass
 2. options............... pass
 3. put_get............... pass
 4. put_get_utf8_segment.. pass
 5. put_no_parent......... pass
 6. mkcol_over_plain...... pass
 7. delete................ pass
 8. delete_null........... pass
 9. delete_fragment....... WARNING: DELETE removed collection resource with Request-URI including fragment; unsafe
    ...................... pass (with 1 warning)
10. mkcol................. pass
11. mkcol_again........... pass
12. delete_coll........... pass
13. mkcol_no_parent....... pass
14. mkcol_with_body....... pass
15. finish................ pass
<- summary for `basic': of 16 tests run: 16 passed, 0 failed. 100.0%
-> 1 warning was issued.
-> running `copymove':
 0. init.................. pass
 1. begin................. pass
 2. copy_init............. pass
 3. copy_simple........... pass
 4. copy_overwrite........ WARNING: COPY to existing resource should give 204 (RFC2518:S8.8.5), got 201 Created
    ...................... pass (with 1 warning)
 5. copy_nodestcoll....... pass
 6. copy_cleanup.......... pass
 7. copy_coll............. pass
 8. copy_shallow.......... pass
 9. move.................. WARNING: MOVE to existing collection resource didn't give 204
WARNING: Could not clean up `/litmus/movecoll'
    ...................... pass (with 2 warnings)
10. move_coll............. pass
11. move_cleanup.......... pass
12. finish................ pass
<- summary for `copymove': of 13 tests run: 13 passed, 0 failed. 100.0%
-> 3 warnings were issued.
-> running `props':
 0. init.................. pass
 1. begin................. pass
 2. propfind_invalid...... pass
 3. propfind_invalid2..... FAIL (PROPFIND with invalid namespace declaration in body (see FAQ) got 207 response not 400)
 4. propfind_d0........... pass
 5. propinit.............. pass
 6. propset............... pass
 7. propget............... pass
 8. propextended.......... pass
 9. propmove.............. pass
10. propget............... pass
11. propdeletes........... pass
12. propget............... pass
13. propreplace........... pass
14. propget............... pass
15. propnullns............ pass
16. propget............... pass
17. prophighunicode....... pass
18. propget............... pass
19. propremoveset......... pass
20. propget............... pass
21. propsetremove......... pass
22. propget............... pass
23. propvalnspace......... pass
24. propwformed........... pass
25. propinit.............. pass
26. propmanyns............ pass
27. propget............... pass
28. propcleanup........... pass
29. finish................ pass
<- summary for `props': of 30 tests run: 29 passed, 1 failed. 96.7%
-> running `locks':
 0. init.................. pass
 1. begin................. pass
 2. options............... pass
 3. precond............... pass
 4. init_locks............ pass
 5. put................... pass
 6. lock_excl............. pass
 7. discover.............. pass
 8. refresh............... pass
 9. notowner_modify....... pass
10. notowner_lock......... pass
11. owner_modify.......... pass
12. notowner_modify....... pass
13. notowner_lock......... pass
14. copy.................. pass
15. cond_put.............. SKIPPED
16. fail_cond_put......... SKIPPED
17. cond_put_with_not..... pass
18. cond_put_corrupt_token FAIL (conditional PUT with invalid lock-token should fail: 200 OK)
19. complex_cond_put...... SKIPPED
20. fail_complex_cond_put. SKIPPED
21. unlock................ pass
22. fail_cond_put_unlocked FAIL (conditional PUT with invalid lock-token should fail: 200 OK)
23. lock_shared........... pass
24. notowner_modify....... pass
25. notowner_lock......... pass
26. owner_modify.......... pass
27. double_sharedlock..... FAIL (shared LOCK on locked resource: 423 Locked)
28. notowner_modify....... pass
29. notowner_lock......... pass
30. unlock................ pass
31. prep_collection....... pass
32. lock_collection....... FAIL (LOCK on `/litmus/lockcoll/': 409 Conflict)
33. owner_modify.......... SKIPPED
34. notowner_modify....... SKIPPED
35. refresh............... SKIPPED
36. indirect_refresh...... SKIPPED
37. unlock................ SKIPPED
38. unmapped_lock......... pass
39. unlock................ pass
40. finish................ pass
-> 9 tests were skipped.
<- summary for `locks': of 32 tests run: 28 passed, 4 failed. 87.5%
-> running `http':
 0. init.................. pass
 1. begin................. pass
 2. expect100............. pass
 3. finish................ pass
<- summary for `http': of 4 tests run: 4 passed, 0 failed. 100.0%
#5

Updated by gstrauss 28 days ago

  • Status changed from New to Patch Pending
  • Target version set to 1.4.54

Patches pending on development branch. 'litmus' tests are not perfect and still have some bugs of their own, but are a useful set of tests nonetheless. The only remaining 'litmus' test that fails is something that could probably be caught be a strictly-validating XML parser, and does not affect well-behaved webdav clients.

$ /usr/bin/litmus -k http://127.0.0.1:8080/ -d /home/lighttpd/opt/srv/www
-> running `basic':
 0. init.................. pass
 1. begin................. pass
 2. options............... pass
 3. put_get............... pass
 4. put_get_utf8_segment.. pass
 5. put_no_parent......... pass
 6. mkcol_over_plain...... pass
 7. delete................ pass
 8. delete_null........... pass
 9. delete_fragment....... pass
10. mkcol................. pass
11. mkcol_again........... pass
12. delete_coll........... pass
13. mkcol_no_parent....... pass
14. mkcol_with_body....... pass
15. finish................ pass
<- summary for `basic': of 16 tests run: 16 passed, 0 failed. 100.0%
-> running `copymove':
 0. init.................. pass
 1. begin................. pass
 2. copy_init............. pass
 3. copy_simple........... pass
 4. copy_overwrite........ pass
 5. copy_nodestcoll....... pass
 6. copy_cleanup.......... pass
 7. copy_coll............. pass
 8. copy_shallow.......... pass
 9. move.................. pass
10. move_coll............. pass
11. move_cleanup.......... pass
12. finish................ pass
<- summary for `copymove': of 13 tests run: 13 passed, 0 failed. 100.0%
-> running `props':
 0. init.................. pass
 1. begin................. pass
 2. propfind_invalid...... pass
 3. propfind_invalid2..... FAIL (PROPFIND with invalid namespace declaration in body (see FAQ) got 207 response not 400)
 4. propfind_d0........... pass
 5. propinit.............. pass
 6. propset............... pass
 7. propget............... pass
 8. propextended.......... pass
 9. propmove.............. pass
10. propget............... pass
11. propdeletes........... pass
12. propget............... pass
13. propreplace........... pass
14. propget............... pass
15. propnullns............ pass
16. propget............... pass
17. prophighunicode....... pass
18. propget............... pass
19. propremoveset......... pass
20. propget............... pass
21. propsetremove......... pass
22. propget............... pass
23. propvalnspace......... pass
24. propwformed........... pass
25. propinit.............. pass
26. propmanyns............ pass
27. propget............... pass
28. propcleanup........... pass
29. finish................ pass
<- summary for `props': of 30 tests run: 29 passed, 1 failed. 96.7%
-> running `locks':
 0. init.................. pass
 1. begin................. pass
 2. options............... pass
 3. precond............... pass
 4. init_locks............ pass
 5. put................... pass
 6. lock_excl............. pass
 7. discover.............. pass
 8. refresh............... pass
 9. notowner_modify....... pass
10. notowner_lock......... pass
11. owner_modify.......... pass
12. notowner_modify....... pass
13. notowner_lock......... pass
14. copy.................. pass
15. cond_put.............. pass
16. fail_cond_put......... pass
17. cond_put_with_not..... pass
18. cond_put_corrupt_token pass
19. complex_cond_put...... pass
20. fail_complex_cond_put. pass
21. unlock................ pass
22. fail_cond_put_unlocked pass
23. lock_shared........... pass
24. notowner_modify....... pass
25. notowner_lock......... pass
26. owner_modify.......... pass
27. double_sharedlock..... pass
28. notowner_modify....... pass
29. notowner_lock......... pass
30. unlock................ pass
31. prep_collection....... pass
32. lock_collection....... pass
33. owner_modify.......... pass
34. notowner_modify....... pass
35. refresh............... pass
36. indirect_refresh...... pass
37. unlock................ pass
38. unmapped_lock......... pass
39. unlock................ pass
40. finish................ pass
<- summary for `locks': of 41 tests run: 41 passed, 0 failed. 100.0%
-> running `http':
 0. init.................. pass
 1. begin................. pass
 2. expect100............. pass
 3. finish................ pass
<- summary for `http': of 4 tests run: 4 passed, 0 failed. 100.0%
#6

Updated by gstrauss 27 days ago

For posterity: running the 'litmus' tests requires a little bit of setup. Directory locations for webdav files and webdav db must be writable by the user under which lighttpd will be run, and must be at least readable by the user under which 'litmus' will be run.
.

webdav_dir=/home/lighttpd/opt/srv/www
mkdir -p $webdav_dir
cp /usr/share/litmus/htdocs/foo $webdav_dir/
# directory for webdav db must also exist (wherever you like)
mkdir /home/lighttpd/opt/var/db/
:
/usr/bin/litmus -k http://127.0.0.1:8080/ -d $webdav_dir

lighttpd needs to be running. ETags have to be enabled (default), and there must be a mimetype.assign entry for "" (e.g. "" => "application/octet-stream")

server.document-root = "/home/lighttpd/opt/srv/www" 
server.modules += ( "mod_webdav" )
webdav.activate = "enable" 
webdav.sqlite-db-name = "/home/lighttpd/opt/var/db/webdav.db" 
#mimetype.assign = ( "" => "application/octet-stream" )

#7

Updated by gstrauss 27 days ago

  • Status changed from Patch Pending to Fixed
  • % Done changed from 0 to 100

Also available in: Atom