[PATCH] a mercurial extension for minimal DAV support in hgweb
Johan Euphrosine
proppy at aminche.com
Mon Jun 23 15:24:17 UTC 2008
# HG changeset patch
# User Johan Euphrosine <proppy at aminche.com>
# Date 1214234578 0
# Node ID 5fd5e9a241eeeadad51959cb6361418917c69498
# Parent 1fe6f365df2e0ed6dd56b5bd9993812378506174
a mercurial extension for minimal DAV support in hgweb
Allow the following HTTP command:
--
PUT /raw-file/tip/test
Content-length: 7
content
--
to commit the body of the request: 'content' to /test file with tip as
the parent revision.
To enable the extension add this to hgrc:
[extensions]
hgext.webdav =
diff --git a/hgext/webdav.py b/hgext/webdav.py
new file mode 100644
--- /dev/null
+++ b/hgext/webdav.py
@@ -0,0 +1,53 @@
+"""a mercurial extension for minimal DAV support in hgweb
+
+Allow the following HTTP command:
+--
+PUT /raw-file/tip/test
+Content-length: 7
+content
+--
+to commit the body of the request: 'content' to /test file with tip as
+the parent revision.
+
+To enable the extension add this to hgrc:
+
+[extensions]
+hgext.webdav =
+
+-- Johan Euphrosine <proppy at aminche.com>
+"""
+
+from mercurial.hgweb import webcommands, webutil, common
+from mercurial.hgweb.server import _hgwebhandler
+from mercurial import context
+from mercurial.node import hex
+
+_hgwebhandler.do_PUT = _hgwebhandler.do_POST
+
+web_rawfile = webcommands.rawfile
+def rawfile(web, req, tmpl):
+ if req.env['REQUEST_METHOD'] == 'GET':
+ return web_rawfile(web, req, tmpl)
+ elif req.env['REQUEST_METHOD'] == 'PUT':
+ path = webutil.cleanpath(web.repo, req.form.get('file', [''])[0])
+ input = req.env['wsgi.input']
+ length = int(req.env['CONTENT_LENGTH'])
+ body = input.read(length)
+ if length != len(body):
+ raise common.ErrorResponse(common.HTTP_BAD_REQUEST, 'incomplete PUT content-length:%i got:%i' % (length, len(body)))
+ text = "PUT %s" % path
+ date = None
+ author = req.env['REMOTE_ADDR']
+ files = [path]
+ extra = None
+ p1 = req.form['node'][0]
+ p2 = None
+ def getfilectx(repo, memctx, f):
+ return context.memfilectx(f, body, None, None, None)
+ ctx = context.memctx(web.repo, (p1, p2), text, files, getfilectx,
+ author, date, extra)
+ result = web.repo.commitctx(ctx)
+ req.respond(common.HTTP_OK, "application/mercurial")
+ return hex(result)
+
+webcommands.rawfile = rawfile
diff --git a/tests/test-webdav b/tests/test-webdav
new file mode 100755
--- /dev/null
+++ b/tests/test-webdav
@@ -0,0 +1,45 @@
+#!/bin/sh
+
+cat <<EOF >> $HGRCPATH
+[extensions]
+hgext.webdav =
+EOF
+
+hg init test
+cd test
+hg serve -p $HGPORT &> hg.log &
+hgpid=$!
+sleep 1
+cat >put.py <<EOF
+#!/usr/bin/env python
+import httplib
+import sys
+h = httplib.HTTPConnection("localhost:$HGPORT")
+h.request("PUT", "/raw-file/%s/test" % sys.argv[1], sys.stdin.read())
+print h.getresponse().read()
+EOF
+chmod +x put.py
+echo % testing put1
+rev1=`echo test | ./put.py tip`
+("$TESTDIR/get-with-headers.py" localhost:$HGPORT "/raw-file/tip/test") | grep test > /dev/null && echo OK
+echo % testing put2
+rev2=`echo test2 | ./put.py tip`
+("$TESTDIR/get-with-headers.py" localhost:$HGPORT "/raw-file/tip/test") | grep test2 > /dev/null && echo OK
+echo % testing put2.parent == put1
+("$TESTDIR/get-with-headers.py" localhost:$HGPORT "/raw-rev/$rev2") | grep Parent | grep $rev1 > /dev/null && echo OK
+echo % testing put3
+rev3=`echo test3 | ./put.py $rev1`
+("$TESTDIR/get-with-headers.py" localhost:$HGPORT "/raw-file/tip/test") | grep test3 > /dev/null && echo OK
+echo % testing put3.parent == put1
+("$TESTDIR/get-with-headers.py" localhost:$HGPORT "/raw-rev/$rev3") | grep Parent | grep $rev1 > /dev/null && echo OK
+hg status -m -a
+echo % testing incomplete PUT
+nc -w 1 localhost $HGPORT <<EOF
+PUT /raw-file/tip/toto HTTP/1.1
+Content-length: 10
+
+test
+EOF
+sleep 1
+kill $hgpid
+grep "400" hg.log > /dev/null && echo OK
diff --git a/tests/test-webdav.out b/tests/test-webdav.out
new file mode 100644
--- /dev/null
+++ b/tests/test-webdav.out
@@ -0,0 +1,12 @@
+% testing put1
+OK
+% testing put2
+OK
+% testing put2.parent == put1
+OK
+% testing put3
+OK
+% testing put3.parent == put1
+OK
+% testing incomplete PUT
+OK
More information about the Mercurial-devel
mailing list