# WebDAV and Autoversioning

WebDAV is an extension to HTTP, and is growing more and more popular as a standard for file-sharing. Today's operating systems are becoming extremely Web-aware, and many have now built-in support for mounting shares exported by WebDAV servers.

If you use Apache/mod_dav_svn as your Subversion network server, then to some extent, you are also running a WebDAV server. This appendix gives some background on the nature of this protocol, how Subversion uses it, and how well Subversion interoperates with other software that is WebDAV-aware.

## Basic WebDAV Concepts

This section provides a very brief, very general overview to the ideas behind WebDAV. It should lay the foundation for understanding WebDAV compatibility issues between clients and servers.

### Just Plain WebDAV

RFC 2518 defines a set of concepts and accompanying extension methods to HTTP 1.1 that make the web into a more universal read/write medium. The basic idea is that a WebDAV-compliant web server can act like a generic file server; clients can mount WebDAV shares that behave much like NFS or SMB shares.

However, it's important to note that RFC 2518 does not provide any sort of model for version control, despite the V in DAV. Basic WebDAV clients and servers assume only one version of each file or directory exists, and can be repeatedly overwritten. For this reason, some people jokingly refer to generic WebDAV clients as WebDA clients!

Here are the new concepts and methods introduced in basic WebDAV:

New write methods

  Beyond the standard HTTP `PUT` method (which creates or overwrites a web resource), WebDAV defines new `COPY` and `MOVE` methods for duplicating or rearranging resources.

Collections

  This is simply the WebDAV term for a grouping of resources (URIs). In most cases, it is analogous to a directory. You can tell something is a collection if it ends with a trailing /. Whereas file resources can be written or created with a `PUT` method, collection resources are created with the new `MKCOL` method.

Properties

  This is the same idea present in Subversion—metadata attached to files and collections. A client can list or retrieve properties attached to a resource with the new `PROPFIND` method, and can change them with the `PROPPATCH` method. Some properties are wholly created and controlled by users (e.g. a property called color), and others are wholly created and controlled by the WebDAV server (e.g. a property that contains the last modification time of a file). The former kind are called dead properties, and the latter kind are called live properties.

Locking

  A WebDAV server may decide to offer a locking feature to clients—this part of the specification is optional, although most WebDAV servers do offer the feature. If present, then clients can use the new `LOCK` and `UNLOCK` methods to mediate access to a resource. In most cases these methods are used to create exclusive write locks (as discussed in ), although shared write locks are also possible.

### DeltaV Extensions

Because RFC 2518 left out versioning concepts, another capable group was left with the responsibility of writing RFC 3253, which adds versioning to WebDAV. WebDAV/DeltaV clients and servers are often called just DeltaV clients and servers, since DeltaV implies the existence of basic WebDAV.

DeltaV introduces a whole slew of new acronyms, but don't be intimidated. The ideas are fairly straightforward. Here are the new concepts and methods introduced in DeltaV:

Per-resource versioning

  Like CVS and other version-control systems, DeltaV assumes that each resource has a potentially infinite number of states. A client begins by placing a resource under version control using the new `VERSION-CONTROL` method. This creates a new Version Controlled Resource (VCR). Every time you change the VCR (via `PUT`, `PROPPATCH`, etc.), a new state of the resource is created, called a Version Resource (VR). VCRs and VRs are still ordinary web resources, defined by URLs. Specific VRs can have human-friendly names as well.

Server-side working-copy model

  Some DeltaV servers support the ability to create a virtual workspace on the server, where all of your work is performed. Clients use the `MKWORKSPACE` method to create a private area, then indicate they want to change specific VCRs by checking them out into the workspace, editing them, and checking them in again. In HTTP terms, the sequence of methods would be `CHECKOUT`, `PUT`, `CHECKIN`. After each `CHECKIN`, a new VR is created, and the edited VCR's contents now point to the latest VR. Each VCR has also has a history resource which tracks and orders its various VR states.

Client-side working-copy model

  Some DeltaV servers also support the idea that the client may have a private working copy full of specific VRs. (This is how CVS and Subversion work.) When the client wants to commit changes to the server, it begins by creating a temporary server transaction (called an activity) with the `MKACTIVITY` method. The client then performs a `CHECKOUT` on each VR it wishes to change, which creates a number of temporary working resources in the activity, that can be modified using `PUT` and `PROPPATCH` methods. Finally, the client performs a `CHECKIN` on each working resource, which creates a new VR within each VCR, and the entire activity is deleted.

Configurations

  DeltaV allows you define flexible collections of VCRs called configurations, which don't necessarily respond to particular directories. Each VCR's contents can be made to point to a specific VR using the `UPDATE` method. Once the configuration is perfect, the client can create a snapshot of the whole configuration, called a baseline. Clients use the `CHECKOUT` and `CHECKIN` methods to capture specific states of configurations, much like they use these methods to create specific VR states of VCRs.

Extensibility

  DeltaV defines a new method, `REPORT`, which allows the client and server to perform customized data exchanges. The client sends a `REPORT` request with a properly-labeled XML body full of custom data; assuming the server understands the specific report-type, it responds with an equally custom XML body. This technique is very similar to XML-RPC.

Autoversioning

  For many, this is the killer feature of DeltaV. If the DeltaV server supports this feature, then basic WebDAV clients (i.e. those unaware of versioning) can still write to the server, and the server will silently perform versioning anyway. In the simplest example, an ignorant `PUT` from a basic WebDAV client might be translated by the server as a `CHECKOUT`, `PUT`, `CHECKIN`.

## Subversion and DeltaV

So how compatible is Subversion with other DeltaV software? In two words: not very. At least not yet, not in Subversion 1.0.

While libsvn_ra_dav sends DeltaV requests to the server, the Subversion client is not a general-purpose DeltaV client. In fact, it expects some custom features from the server (especially through custom `REPORT` requests). Further, mod_dav_svn is not a general-purpose DeltaV server. It only implements a strict subset of the DeltaV specification. A more general WebDAV or DeltaV client may very well be able to interoperate against it, but only if that client operates within the narrow confines of those features that the server has implemented. The Subversion development team plans to address general WebDAV interoperability in a future release of Subversion.

### Mapping Subversion to DeltaV

Here is a very high-level description of how various Subversion client operations use DeltaV. In many cases, these explanations are gross oversimplifications. They should not be taken as a substitute for reading Subversion's source code or talking with its developers.

svn checkout/list

  Perform a `PROPFIND` of depth 1 on the collection to get a list of immediate children. Perform a `GET` (and possibly a `PROPFIND`) on each child. Recurse into collections and repeat.

svn commit

  Create an activity with `MKACTIVITY`, and do a `CHECKOUT` of each changed item, followed by a `PUT` of new data. Finally, a `MERGE` request causes an implicit `CHECKIN` of all working resources.

svn update/switch/status/merge/diff

  Send a custom `REPORT` request that describes the mixed-revision (and mixed-url) state of the working copy. The server sends a custom response that describes which items need updating and includes binary deltas of file contents. Parses the response. For updates and switches, install the new data in the working copy. For diff and merge commands, compare the data to the working copy, possibly applying changes as local modifications.

### Autoversioning Support

At the time of writing, the truth is that there are very few DeltaV clients in the world; RFC 3253 is still relatively new. However users do have access to generic clients, because almost every modern operating system now has an integrated basic WebDAV client. With this in mind, Subversion developers realized that if Subversion 1.0 was to have any interoperability features, support for DeltaV autoversioning would be the best approach.

To activate autoversioning in mod_dav_svn, use the `SVNAutoversioning` directive within the `httpd.conf` `Location` block, like so:

    <Location /repos>
      DAV svn
      SVNPath /absolute/path/to/repository
      SVNAutoversioning on
    </Location>

Normally, if a generic WebDAV client attempted a `PUT` to a path within your repository location, mod_dav_svn would outright reject the request. (It normally only allows such operations on working resources within DeltaV activities.) With `SVNAutoversioning` turned on, however, the server interprets the `PUT` request as an internal `MKACTIVITY`, `CHECKOUT`, `PUT`, and `CHECKIN`. A generic log message is auto-generated, and a new filesystem revision is created.

Because so many operating systems already have integrated WebDAV abilities, the use-case for this feature borders on fantastical: imagine an office of ordinary users running Microsoft Windows or Mac OS. Each computer mounts the Subversion repository, which appears to be an ordinary network share. They use the server as they always do: open files from the server, edit them, and save them back to the server. But in this fantasy, the server is automatically versioning everything. Later on, a sysadmin can use a Subversion client to search and retrieve all older versions.

Is this fantasy real? Not quite. The main snag is that Subversion 1.0 has no support whatsoever for the WebDAV `LOCK` or `UNLOCK` methods. Most operating system DAV clients attempt to `LOCK` a resource opened directly from a DAV-mounted network share. For now, users may have to copy a file from the DAV share to local disk, edit the file, then copy it back again. Not ideal autoversioning, but still doable.

### The mod_dav_lock Alternative

The mod_dav Apache module is a complex beast: it understands and parses all of the WebDAV and DeltaV methods, yet it depends on a back-end provider to access the resources themselves.

In its simplest incarnation, a user can use mod_dav_fs as a provider for mod_dav. mod_dav_fs uses the ordinary filesystem to store files and directories, and only understands vanilla WebDAV methods, not DeltaV.

Subversion, on the other hand, uses mod_dav_svn as a provider for mod_dav. mod_dav_svn understands all WebDAV methods except `LOCK`, and understands a sizable subset of DeltaV methods. It accesses data in the Subversion repository, rather than in the real filesystem. Subversion 1.0 doesn't support locking, because it would actually be quite difficult to implement, since Subversion uses the copy-modify-merge model. Subversion may someday develop a reserved-checkout locking model that can live peaceably with copy-modify-merge, but it probably won't happen soon.

In Apache httpd-2.0, mod_dav supports the `LOCK` method by tracking locks in a private database, assuming that the provider is willing to accept them. In Apache httpd-2.1 or later, however, this locking support has been broken into an independent module, mod_dav_lock. It allows any mod_dav provider to take advantage of the lock database, including mod_dav_svn, even though mod_dav_svn doesn't actually understand locking.

Confused yet?

In a nutshell, you can use mod_dav_lock in Apache httpd-2.1 (or later) to create the illusion that mod_dav_svn is honoring `LOCK` requests. Make sure mod_dav_lock is either compiled into httpd, or being loaded in your `httpd.conf`. Then simply add the `DAVGenericLockDB` directive to your `Location` like so:

    <Location /repos>
      DAV svn
      SVNPath /absolute/path/to/repository
      SVNAutoversioning on
      DavGenericLockDB /path/to/store/locks
    </Location>

This technique is a risky business; in some sense, the mod_dav_svn is now lying to the WebDAV client. It claims to accept the `LOCK` request, but in reality the lock isn't being enforced at all levels. If a second WebDAV client attempts to `LOCK` the same resource, then mod_dav_lock will notice and correctly deny the request. But there's absolutely nothing preventing an ordinary Subversion client from changing the file via a normal `svn commit`! If you use this technique, you're giving users the opportunity to stomp on each others' changes. In particular, a WebDAV client might accidentally overwrite a change committed by regular svn client.

On the other hand, if you set up your environment very carefully, you may mitigate the risk. For example, if all of your users are working though basic WebDAV clients (rather than svn clients), then things should be fine.

## Autoversioning Interoperability

In this section, we'll describe the most common generic WebDAV clients (at the time of writing), and how well they operate against a mod_dav_svn server using the `SVNAutoversioning` directive. RFC 2518 is a bit large, and perhaps a bit too flexible. Every WebDAV client behaves slightly differently, and creates slightly different problems.

### Win32 WebFolders

Windows 98, 2000, and XP have an integrated WebDAV client known as WebFolders. On Windows 98, the feature might need to be explicitly installed; if present, a WebFolders directory appears directly within My Computer. On Windows 2000 and XP, simply open My Network Places, and run the Add Network Place icon. When prompted, enter the WebDAV URL. The shared folder will appear within My Network Places.

Most write operations work fine against an autoversioning mod_dav_svn server, but there are a few problems:

- If a Windows XP computer is a member of an NT Domain, then it seems to be unable to connect to the WebDAV share. It repeatedly asks for a name and password, even when the Apache server isn't issuing an authentication challenge! If the machine isn't part of an NT Domain, then the share is mounted without a problem.

  This problem seems to stem from changes in the way Windows XP creates WebFolder shortcuts ( `.lnk` files). It sometimes replaces the URL of the WebDAV share with a Windows UNC (Universal Naming Convention) path instead. This causes Explorer to attempt a connection using SMB instead of HTTP.

  A workaround for this problem is to create the `.lnk` shortcut on a Windows 2000 computer and then copy this shortcut to the Windows XP computer. It would probably also be possible to fix the shortcut using a HEX editor, if one were to reverse-engineer the `.lnk` file format.

- A file can't be opened for direct editing from the share; it always comes up read-only. The mod_dav_lock technique doesn't help, because WebFolders doesn't use the `LOCK` method at all. The previously mentioned copy, edit, re-copy method does work, however. The file on the share can be successfully overwritten by a locally edited copy.

### Mac OS X

Apple's OS X operating system has an integrated WebDAV client. From the Finder, select the Connect to Server item from the Go menu. Enter a WebDAV URL, and it appears as a disk on the desktop, just like any file server. Unix users can also run `mount -t webdav URL /mountpoint`.

Unfortunately, this client refuses to work against an autoversioning mod_dav_svn because of its lack of `LOCK` support. Mac OS X discovers the missing `LOCK` ability during the initial HTTP `OPTIONS` feature exchange, and thus decides to mount the Subversion repository as a read-only share. After that, no write operations are possible at all. In order to mount the repository as a read-write share, you must use the mod_dav_lock trick discussed previously. Once locking seems to work, the share behaves very nicely: files can be opened directly in read/write mode, although each save operation will cause the client to do a `PUT` to a temporary location, a `DELETE` of original file, and a `MOVE` of the temporary resource to the original filename. That's three new Subversion revisions per save!

One more word of warning: OS X's WebDAV client can be overly sensitive to HTTP redirects. If you're unable to mount the repository at all, you may need to enable the `BrowserMatch` directive in your `httpd.conf`:

    BrowserMatch "^WebDAVFS/1.[012]" redirect-carefully

### Unix: Nautilus 2

Nautilus is the official file manager/browser for the GNOME desktop. Its main home page is at http://www.gnome.org/projects/nautilus/. By simply typing a WebDAV URL into the Nautilus window, the DAV share appears like a local filesystem.

In general, Nautilus 2 works reasonably well against an autoversioning mod_dav_svn, with the following caveats:

- Any files opened directly from the share are treated as read-only. Even the mod_dav_lock trick seems to have no effect. It seems that Nautilus never issues the `LOCK` method at all. The copy locally, edit, copy back trick does work, however. Unfortunately, Nautilus overwrites the old file by issuing a `DELETE` first, which creates an extra revision.

- When overwriting or creating a file , Nautilus first does a `PUT` of an empty file, then overwrites it with a second `PUT`. This creates two Subversion filesystem revisions, rather than one.

- When deleting a collection, it issues an HTTP `DELETE` on each individual child instead of on the collection itself. This creates a whole bunch of new revisions.

### Linux davfs2

Linux davfs2 is a filesystem module for the Linux kernel, whose development is located at http://dav.sourceforge.net/. Once installed, a WebDAV network share can be mounted with the usual Linux `mount` command.

The word on the street is that this DAV client doesn't work at all with mod_dav_svn's autoversioning. Every single attempt to write to the server is preceded by a `LOCK` request, which mod_dav_svn doesn't support. At this time, there is no data indicating whether the use of mod_dav_lock resolves this problem.