Uploaded image for project: 'Subversion'
  1. Subversion
  2. SVN-3515

Mod_dav_svn cannot refresh any locks.



    • Bug
    • Status: Closed
    • Major
    • Resolution: Fixed
    • 1.6.x
    • 1.9.0
    • mod_dav_svn
    • None


      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
      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
      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.


      Original issue reported by pv


        Issue Links



              Unassigned Unassigned
              subversion-importer Subversion Importer
              0 Vote for this issue
              1 Start watching this issue