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)