comparison mercurial/hgweb/protocol.py @ 6926:57b954d8d003

hgweb: raise ErrorResponses to communicate protocol errors
author Dirkjan Ochtman <dirkjan@ochtman.nl>
date Tue, 22 Jul 2008 18:23:20 +0200
parents 87abfefafe02
children a42d27bc809d
comparison
equal deleted inserted replaced
6925:87abfefafe02 6926:57b954d8d003
106 req.respond(HTTP_OK, HGTYPE, length=len(rsp)) 106 req.respond(HTTP_OK, HGTYPE, length=len(rsp))
107 yield rsp 107 yield rsp
108 108
109 def unbundle(repo, req): 109 def unbundle(repo, req):
110 110
111 errorfmt = '0\n%s\n'
112 proto = req.env.get('wsgi.url_scheme') or 'http' 111 proto = req.env.get('wsgi.url_scheme') or 'http'
113 their_heads = req.form['heads'][0].split(' ') 112 their_heads = req.form['heads'][0].split(' ')
114 113
115 def check_heads(): 114 def check_heads():
116 heads = map(hex, repo.heads()) 115 heads = map(hex, repo.heads())
121 length = int(req.env.get('CONTENT_LENGTH', 0)) 120 length = int(req.env.get('CONTENT_LENGTH', 0))
122 for s in util.filechunkiter(req, limit=length): 121 for s in util.filechunkiter(req, limit=length):
123 # drain incoming bundle, else client will not see 122 # drain incoming bundle, else client will not see
124 # response when run outside cgi script 123 # response when run outside cgi script
125 pass 124 pass
126 req.respond(HTTP_OK, HGTYPE) 125 raise ErrorResponse(HTTP_OK, 'unsynced changes')
127 return errorfmt % 'unsynced changes',
128
129 req.respond(HTTP_OK, HGTYPE)
130 126
131 # do not lock repo until all changegroup data is 127 # do not lock repo until all changegroup data is
132 # streamed. save to temporary file. 128 # streamed. save to temporary file.
133 129
134 fd, tempname = tempfile.mkstemp(prefix='hg-unbundle-') 130 fd, tempname = tempfile.mkstemp(prefix='hg-unbundle-')
140 136
141 try: 137 try:
142 lock = repo.lock() 138 lock = repo.lock()
143 try: 139 try:
144 if not check_heads(): 140 if not check_heads():
145 return errorfmt % 'unsynced changes', 141 raise ErrorResponse(HTTP_OK, 'unsynced changes')
146 142
147 fp.seek(0) 143 fp.seek(0)
148 header = fp.read(6) 144 header = fp.read(6)
149 if header.startswith('HG') and not header.startswith('HG10'): 145 if header.startswith('HG') and not header.startswith('HG10'):
150 raise ValueError('unknown bundle version') 146 raise ValueError('unknown bundle version')
166 sys.stdout.write("abort: %s\n" % inst) 162 sys.stdout.write("abort: %s\n" % inst)
167 ret = 0 163 ret = 0
168 finally: 164 finally:
169 val = sys.stdout.getvalue() 165 val = sys.stdout.getvalue()
170 sys.stdout, sys.stderr = oldio 166 sys.stdout, sys.stderr = oldio
167 req.respond(HTTP_OK, HGTYPE)
171 return '%d\n%s' % (ret, val), 168 return '%d\n%s' % (ret, val),
172 finally: 169 finally:
173 del lock 170 del lock
174 except ValueError, inst: 171 except ValueError, inst:
175 return errorfmt % inst, 172 raise ErrorResponse(HTTP_OK, inst)
176 except (OSError, IOError), inst: 173 except (OSError, IOError), inst:
177 filename = getattr(inst, 'filename', '') 174 filename = getattr(inst, 'filename', '')
178 # Don't send our filesystem layout to the client 175 # Don't send our filesystem layout to the client
179 if filename.startswith(repo.root): 176 if filename.startswith(repo.root):
180 filename = filename[len(repo.root)+1:] 177 filename = filename[len(repo.root)+1:]
183 error = getattr(inst, 'strerror', 'Unknown error') 180 error = getattr(inst, 'strerror', 'Unknown error')
184 if inst.errno == errno.ENOENT: 181 if inst.errno == errno.ENOENT:
185 code = HTTP_NOT_FOUND 182 code = HTTP_NOT_FOUND
186 else: 183 else:
187 code = HTTP_SERVER_ERROR 184 code = HTTP_SERVER_ERROR
188 req.respond(code) 185 raise ErrorResponse(code, '%s: %s' % (error, filename))
189 return '0\n%s: %s\n' % (error, filename),
190 finally: 186 finally:
191 fp.close() 187 fp.close()
192 os.unlink(tempname) 188 os.unlink(tempname)
193 189
194 def stream_out(repo, req): 190 def stream_out(repo, req):