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

Mod_dav_svn cannot refresh any locks.

    XMLWordPrintableJSON

Details

    • Bug
    • Status: Closed
    • Major
    • Resolution: Fixed
    • 1.6.x
    • 1.9.0
    • mod_dav_svn
    • 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

          Activity

            People

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

              Dates

                Created:
                Updated:
                Resolved: