Details
-
Bug
-
Status: Closed
-
Major
-
Resolution: Fixed
-
1.6.x
-
None
Description
How to reproduce: 1) Connect to an autoversioning SVN share and open a MS Word document from there or save an entirely new document to the shared location and keep it open. 2) Wait for 3 minutes. (The lock timeout default.) 3) Make some changes into the open document. 4) Try to save (Ctrl-S) the document and notice that "Word did not save the document." The error occurs because Word & mod_dav_svn were unable to refresh the SVN lock for the document, because, as the error.log says, "The precondition(s) specified by the "If:" header did not match this resource. At least one failure is because: a State-token was supplied, but it was not found in the locks on this resource. [412, #0]" By inspecting the Apache (2.2.13) and Subversion (1.6.5) source code files, I have formed the following understanding of what's going on under the hood: Apache receives a LOCK DAV request with the precondition (If:) header specifying an identifier of a previously created lock. However, because there is some invalid hack in the get_locks() of mod_dav_svn/lock.c, the lock couldn't be matched. Therefore any tries to refresh a lock will fail. The following is my reconstruction of the supposed call path on the Apache mod_dav side: modules/dav/main/mod_dav.c : static int dav_method_lock(request_rec *r) -> modules/dav/main/util.c : DAV_DECLARE(dav_error *) dav_validate_request(request_rec *r, ...) -> modules/dav/main/util.c : static dav_error * dav_validate_walker(dav_walk_resource *wres, int calltype) -> modules/dav/main/util.c : static dav_error * dav_validate_resource_state(apr_pool_t *p, ...) ... dav_lock_query(lockdb, resource, &lock_list) ... return dav_new_error(p, HTTP_PRECONDITION_FAILED, 0, apr_psprintf(p, "The precondition(s) specified by the \"If:\" header did not match this resource. At least one failure is because: %s", reason)); And the following is my reconstruction of what happens when dav_lock_query gets called from dav_validate_resource_state: modules/dav/util_lock.c : DAV_DECLARE(dav_error*) dav_lock_query(dav_lockdb *lockdb, ...) -> subversion/mod_dav_svn/lock.c : static dav_error * get_locks(dav_lockdb *lockdb, ...) ... /* The Big Lie: if the client ran 'svn lock', then we have to pretend that there's no existing lock. Otherwise mod_dav will throw '403 Locked' without even attempting to create a new lock. For the --force case, this is required and for the non-force case, we allow the filesystem to produce a better error for svn clients. */ if (info->r->method_number == M_LOCK) { *locks = NULL; return 0; } Currently, as a workaround, I define the DavMinTimeout in httpd.conf to be long enough so that lock refreshes don't have to be done, but obviously that is not a solution. I think one solution would be to check if the request (r?) has any precondition headers and bypass the Big Lie hack condition in such case.
http://subversion.tigris.org/ds/viewMessage.do?dsForumId=462&dsMessageId=2405671
Original issue reported by pv
Attachments
Issue Links
- is duplicated by
-
SVN-4488 LOCK refresh with If: header fails
- Closed