Extension:WebDAV

WebDAV is a set of extensions to HTTP to support distributed authoring and versioning. It defines some request methods, message headers and XML message bodies which at their most basic, add metadata and locking to HTTP. Because it's based on HTTP and XML, it is quite easy to implement a WebDAV server in CGI or PHP. WebDAV maps very cleanly to file system primitives, so most modern operating systems support mounting WebDAV resources as file systems.

The WebDAV article and the WebDAV home page describe WebDAV in more detail. WebDAV is formally defined in RFC 4918. The WebDAV versioning extension, DeltaV, is defined in RFC 3253.

MediaWiki
This is a project to create a WebDAV interface to MediaWiki. This would let users:
 * Manage wiki articles with WebDAV clients like cadaver.
 * Mount MediaWiki and access articles like file system resources, using for instance fusedav. Users could potentially even manage metadata like file system extended attributes.
 * Edit articles directly using editors with WebDAV support, like Emacs and Eclipse.

This project is based on the WebDAV module I contributed to the Gallery project.

Installation
Execute in the top directory of your MediaWiki installation:

svn co http://svn.freegeek.org/svn/mediawiki-webdav/trunk.

This should checkout "WebDav.php", "webdav.php", "deltav.php" and "lib/". Then point your WebDAV client at "http://.../mediawiki/webdav.php".

Status
Getting articles, putting articles, and directory listings should all work. Right now I'm focusing on support for WebDAV's versioning features, so "history Main_Page" works in the cadaver client. Next I need to figure out how HTTP authentication to MediaWiki works.

I would like to move this project to the MediaWiki Subversion repository.

I would also like to make this project a MediaWiki extension. The trouble is I'm not sure how requests are delegated to a particular extension. Also, most WebDAV clients don't support query strings. If you want to add a resource which doesn't already exist, WebDAV clients predict the URL of the new resource by appending the new resource name to the URL of it's parent: http://.../parent/New_Name

Currently, this project works using an alternate PHP landing to "index.php". "webdav.php" supports requests to URLs of the form "http://.../mediawiki/webdav.php/New_Name". I'm not yet sure how to ship this landing as a MediaWiki extension.

The Gallery module works using Gallery's "URL rewrite" facility, so URLs of the form "http://.../gallery2/w/New_Name" are delegated to the module. I don't know if something similar is feasible in MediaWiki?

As of revision 33, Subversion update functionality is working. All checkouts and updates now use the "send-all" style Subversion communication, available I think since Subversion 1.3? "send-all" includes the bodies of every resource in an update-report in svndiff format. This extension implements svndiff version zero. Version one adds support for zlib compression in the svndiff format, but it is slightly more complicated and I haven't figured out why it's necessary, since an entire update-report can be zlib compressed as an HTTP encoding.

Diffs are not actually calculated yet, svndiff is simply used to encode the replacement of the old text with the new text. This could be optimized by implementing Subversion's binary difference system in PHP, or by serializing MediaWiki's Diff system as svndiff.

The next challenge is to get commit working. This is difficult because Subversion commits multiple pages at a time, using multiple requests and the DeltaV "activity" system. Consequently, this extension needs to store the changes somewhere until they are actually merged into the articles. Does this mean we need to add a table to the database? Semantic MediaWiki does this, so it is possible. Could we reuse some other facility already in MediaWiki?

After discussion with Brion Vibber, a "temporary-queue" table for storing DeltaV / Subversion "activities" seems like the best way to go. Extensions can tie into the updater hooks to maintain their custom tables. Brion tied updater hooks into a couple extensions. "checkuser" might have 'em.

One alternative to distributing this interface as and extension would be an extra front end app.

Subversion
Subversion is close to a DeltaV client and is very pervasive (command line, Emacs VC mode, Subclipse). If it's not too difficult to build a Subversion interface on top of this WebDAV / DeltaV interface, it would enable people to edit MediaWiki using the Emacs VC mode, or Eclipse Subclipse plugin.

One diversion from the DeltaV spec is the Subversion update-report. In this report txdelta values are base64 encodings of the svndiff format defined here: http://svn.collab.net/repos/svn/trunk/notes/svndiff

So we simply need to translate MediaWiki revisions to svndiff format.

Is it a bug for subversion clients to try getting the baseline-collection property from the version-controlled-configuration resource? Ahh, I think it's the Label: header doing this work...

We need a per-MediaWiki installation UUID.

First successful MediaWiki checkout with Subversion: ket% svn co http://ket/~jablko/mediawiki/webdav.php A   webdav.php/Main_Page A   webdav.php/Resume A   webdav.php/Test A   webdav.php/Cover_Letter A   webdav.php/Home.ics Checked out revision 22. ket%

First successful MediaWiki exploration with Subclipse: http://cgi.sfu.ca/~jdbates/tmp/mediawiki/200706110/Screenshot-SVN%20Repository%20Exploring%20-%20Eclipse%20SDK%20.png

Another handy feature of the Subversion interface is if a project maintains documentation in MediaWiki, as many software projects do, and want to distribute documentation with the project, you can use the Subversion externals feature to automatically checkout or export documentation from MediaWiki when the project is retrieved from Subversion. The documentation can then be optionally processed to PDF using XSL_Formatting_Objects as part of the build process.

Experimental Organization
For the time being, I use the following layout, based on Subversion:
 * webdav.php/* - WebDAV landing, everything after webdav.php corresponds to a MediaWiki page title.
 * deltav.php/* - DeltaV landing for versioning features.
 * ver/* - Everything after ver corresponds to a MediaWiki rev_id and is a version resource representing the page at rev_id.
 * vcc/default - The version controlled configuration.
 * bln/* - Everything after bln corresponds to a MediaWiki rev_id and is a baseline resource representing the Wiki at rev_id.
 * bc/* - Everything after bc corresponds to a MediaWiki rev_id and is a baseline collection representing the Wiki at rev_id.

In the future, we might experiment with making these URLs more like existing MediaWiki URLs (though this would require query string support on the part of clients.)

Code / Package Documentation
This interface might also be useful for maintaining code / package documentation, like jQuery: http://docs.jquery.com/action/edit/Events/toggle

One could use the package information in OpenWrt's Subversion repository, for instance, to build a package browser like http://packages.debian.org, based on MediaWiki.

The Wiki could also be used to author package information - package metadata could be retrieved from and maintained in MediaWiki.

I'm not sure jQuery's API documentation syntax is in fact the most elegant. XML / XHTML + Markdown might in fact be cleaner?

TODO

 * Use global $wgTitle where appropriate, possibly in file scope.
 * Support WebDAV server side search, so "search ..." works in the cadaver client.
 * Decide what to do when someone requests a directory listing for a very large wiki. At some point (millions of articles) does this become a denial of service issue?
 * Decide what URL scheme to use for article revisions (".../mediawiki/deltav.php/Article_Name/42"?)