Mercurial > public > mercurial-scm > hg-stable
comparison mercurial/hgweb/protocol.py @ 5993:948a41e77902
hgweb: explicit response status
author | Dirkjan Ochtman <dirkjan@ochtman.nl> |
---|---|
date | Fri, 01 Feb 2008 10:31:13 +0100 |
parents | 5be210afe1b8 |
children | c050548307a4 |
comparison
equal
deleted
inserted
replaced
5992:30c40ba10963 | 5993:948a41e77902 |
---|---|
7 | 7 |
8 import cStringIO, zlib, bz2, tempfile, errno, os, sys | 8 import cStringIO, zlib, bz2, tempfile, errno, os, sys |
9 from mercurial import util, streamclone | 9 from mercurial import util, streamclone |
10 from mercurial.i18n import gettext as _ | 10 from mercurial.i18n import gettext as _ |
11 from mercurial.node import * | 11 from mercurial.node import * |
12 from common import HTTP_OK, HTTP_NOT_FOUND, HTTP_SERVER_ERROR | |
12 | 13 |
13 # __all__ is populated with the allowed commands. Be sure to add to it if | 14 # __all__ is populated with the allowed commands. Be sure to add to it if |
14 # you're adding a new command, or the new command won't work. | 15 # you're adding a new command, or the new command won't work. |
15 | 16 |
16 __all__ = [ | 17 __all__ = [ |
17 'lookup', 'heads', 'branches', 'between', 'changegroup', | 18 'lookup', 'heads', 'branches', 'between', 'changegroup', |
18 'changegroupsubset', 'capabilities', 'unbundle', 'stream_out', | 19 'changegroupsubset', 'capabilities', 'unbundle', 'stream_out', |
19 ] | 20 ] |
21 | |
22 HGTYPE = 'application/mercurial-0.1' | |
20 | 23 |
21 def lookup(web, req): | 24 def lookup(web, req): |
22 try: | 25 try: |
23 r = hex(web.repo.lookup(req.form['key'][0])) | 26 r = hex(web.repo.lookup(req.form['key'][0])) |
24 success = 1 | 27 success = 1 |
25 except Exception,inst: | 28 except Exception,inst: |
26 r = str(inst) | 29 r = str(inst) |
27 success = 0 | 30 success = 0 |
28 resp = "%s %s\n" % (success, r) | 31 resp = "%s %s\n" % (success, r) |
29 req.httphdr("application/mercurial-0.1", length=len(resp)) | 32 req.respond(HTTP_OK, HGTYPE, length=len(resp)) |
30 req.write(resp) | 33 req.write(resp) |
31 | 34 |
32 def heads(web, req): | 35 def heads(web, req): |
33 resp = " ".join(map(hex, web.repo.heads())) + "\n" | 36 resp = " ".join(map(hex, web.repo.heads())) + "\n" |
34 req.httphdr("application/mercurial-0.1", length=len(resp)) | 37 req.respond(HTTP_OK, HGTYPE, length=len(resp)) |
35 req.write(resp) | 38 req.write(resp) |
36 | 39 |
37 def branches(web, req): | 40 def branches(web, req): |
38 nodes = [] | 41 nodes = [] |
39 if 'nodes' in req.form: | 42 if 'nodes' in req.form: |
40 nodes = map(bin, req.form['nodes'][0].split(" ")) | 43 nodes = map(bin, req.form['nodes'][0].split(" ")) |
41 resp = cStringIO.StringIO() | 44 resp = cStringIO.StringIO() |
42 for b in web.repo.branches(nodes): | 45 for b in web.repo.branches(nodes): |
43 resp.write(" ".join(map(hex, b)) + "\n") | 46 resp.write(" ".join(map(hex, b)) + "\n") |
44 resp = resp.getvalue() | 47 resp = resp.getvalue() |
45 req.httphdr("application/mercurial-0.1", length=len(resp)) | 48 req.respond(HTTP_OK, HGTYPE, length=len(resp)) |
46 req.write(resp) | 49 req.write(resp) |
47 | 50 |
48 def between(web, req): | 51 def between(web, req): |
49 if 'pairs' in req.form: | 52 if 'pairs' in req.form: |
50 pairs = [map(bin, p.split("-")) | 53 pairs = [map(bin, p.split("-")) |
51 for p in req.form['pairs'][0].split(" ")] | 54 for p in req.form['pairs'][0].split(" ")] |
52 resp = cStringIO.StringIO() | 55 resp = cStringIO.StringIO() |
53 for b in web.repo.between(pairs): | 56 for b in web.repo.between(pairs): |
54 resp.write(" ".join(map(hex, b)) + "\n") | 57 resp.write(" ".join(map(hex, b)) + "\n") |
55 resp = resp.getvalue() | 58 resp = resp.getvalue() |
56 req.httphdr("application/mercurial-0.1", length=len(resp)) | 59 req.respond(HTTP_OK, HGTYPE, length=len(resp)) |
57 req.write(resp) | 60 req.write(resp) |
58 | 61 |
59 def changegroup(web, req): | 62 def changegroup(web, req): |
60 req.httphdr("application/mercurial-0.1") | 63 req.respond(HTTP_OK, HGTYPE) |
61 nodes = [] | 64 nodes = [] |
62 if not web.allowpull: | 65 if not web.allowpull: |
63 return | 66 return |
64 | 67 |
65 if 'roots' in req.form: | 68 if 'roots' in req.form: |
74 req.write(z.compress(chunk)) | 77 req.write(z.compress(chunk)) |
75 | 78 |
76 req.write(z.flush()) | 79 req.write(z.flush()) |
77 | 80 |
78 def changegroupsubset(web, req): | 81 def changegroupsubset(web, req): |
79 req.httphdr("application/mercurial-0.1") | 82 req.respond(HTTP_OK, HGTYPE) |
80 bases = [] | 83 bases = [] |
81 heads = [] | 84 heads = [] |
82 if not web.allowpull: | 85 if not web.allowpull: |
83 return | 86 return |
84 | 87 |
104 # XXX: make configurable and/or share code with do_unbundle: | 107 # XXX: make configurable and/or share code with do_unbundle: |
105 unbundleversions = ['HG10GZ', 'HG10BZ', 'HG10UN'] | 108 unbundleversions = ['HG10GZ', 'HG10BZ', 'HG10UN'] |
106 if unbundleversions: | 109 if unbundleversions: |
107 caps.append('unbundle=%s' % ','.join(unbundleversions)) | 110 caps.append('unbundle=%s' % ','.join(unbundleversions)) |
108 resp = ' '.join(caps) | 111 resp = ' '.join(caps) |
109 req.httphdr("application/mercurial-0.1", length=len(resp)) | 112 req.respond(HTTP_OK, HGTYPE, length=len(resp)) |
110 req.write(resp) | 113 req.write(resp) |
111 | 114 |
112 def unbundle(web, req): | 115 def unbundle(web, req): |
113 def bail(response, headers={}): | 116 def bail(response, headers={}): |
114 length = int(req.env['CONTENT_LENGTH']) | 117 length = int(req.env['CONTENT_LENGTH']) |
115 for s in util.filechunkiter(req, limit=length): | 118 for s in util.filechunkiter(req, limit=length): |
116 # drain incoming bundle, else client will not see | 119 # drain incoming bundle, else client will not see |
117 # response when run outside cgi script | 120 # response when run outside cgi script |
118 pass | 121 pass |
119 req.httphdr("application/mercurial-0.1", headers=headers) | 122 req.header(headers.items()) |
123 req.respond(HTTP_OK, HGTYPE) | |
120 req.write('0\n') | 124 req.write('0\n') |
121 req.write(response) | 125 req.write(response) |
122 | 126 |
123 # require ssl by default, auth info cannot be sniffed and | 127 # require ssl by default, auth info cannot be sniffed and |
124 # replayed | 128 # replayed |
146 # fail early if possible | 150 # fail early if possible |
147 if not check_heads(): | 151 if not check_heads(): |
148 bail(_('unsynced changes\n')) | 152 bail(_('unsynced changes\n')) |
149 return | 153 return |
150 | 154 |
151 req.httphdr("application/mercurial-0.1") | 155 req.respond(HTTP_OK, HGTYPE) |
152 | 156 |
153 # do not lock repo until all changegroup data is | 157 # do not lock repo until all changegroup data is |
154 # streamed. save to temporary file. | 158 # streamed. save to temporary file. |
155 | 159 |
156 fd, tempname = tempfile.mkstemp(prefix='hg-unbundle-') | 160 fd, tempname = tempfile.mkstemp(prefix='hg-unbundle-') |
230 filename = filename[len(web.repo.root)+1:] | 234 filename = filename[len(web.repo.root)+1:] |
231 else: | 235 else: |
232 filename = '' | 236 filename = '' |
233 error = getattr(inst, 'strerror', 'Unknown error') | 237 error = getattr(inst, 'strerror', 'Unknown error') |
234 if inst.errno == errno.ENOENT: | 238 if inst.errno == errno.ENOENT: |
235 code = 404 | 239 code = HTTP_NOT_FOUND |
236 else: | 240 else: |
237 code = 500 | 241 code = HTTP_SERVER_ERROR |
238 req.respond(code, '%s: %s\n' % (error, filename)) | 242 req.respond(code) |
243 req.write('%s: %s\n' % (error, filename)) | |
239 finally: | 244 finally: |
240 fp.close() | 245 fp.close() |
241 os.unlink(tempname) | 246 os.unlink(tempname) |
242 | 247 |
243 def stream_out(web, req): | 248 def stream_out(web, req): |
244 req.httphdr("application/mercurial-0.1") | 249 req.respond(HTTP_OK, HGTYPE) |
245 streamclone.stream_out(web.repo, req, untrusted=True) | 250 streamclone.stream_out(web.repo, req, untrusted=True) |