Project

General

Profile

Actions

Feature #1818

closed

add RFC-compliant LOCK support to mod_webdav

Added by Anonymous about 16 years ago. Updated over 5 years ago.

Status:
Fixed
Priority:
Low
Category:
mod_webdav
Target version:
ASK QUESTIONS IN Forums:

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.


Files

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

Updated by gstrauss over 8 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%
Actions #2

Updated by gstrauss over 8 years ago

  • Category changed from core to mod_webdav
Actions #3

Updated by gstrauss over 8 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.

Actions #4

Updated by gstrauss over 8 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%
Actions #5

Updated by gstrauss over 5 years 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%
Actions #6

Updated by gstrauss over 5 years 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" )

Actions #7

Updated by gstrauss over 5 years ago

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

Also available in: Atom