Show More
@@ -357,26 +357,18 b' class hgweb(object):' | |||||
357 | query = req.env[r'QUERY_STRING'].partition(r'&')[0] |
|
357 | query = req.env[r'QUERY_STRING'].partition(r'&')[0] | |
358 | query = query.partition(r';')[0] |
|
358 | query = query.partition(r';')[0] | |
359 |
|
359 | |||
360 | # The ``cmd`` request parameter is used by both the wire protocol |
|
360 | # Route it to a wire protocol handler if it looks like a wire protocol | |
361 | # and hgweb. We route all known wire protocol commands to the |
|
361 | # request. | |
362 | # wire protocol handler, even if the command isn't available for |
|
362 | protohandler = wireprotoserver.parsehttprequest(rctx.repo, req, query) | |
363 | # this transport. That's better for machine clients in the case |
|
|||
364 | # of an errant request to an unavailable protocol command. And it |
|
|||
365 | # prevents hgweb from accidentally using ``cmd`` values used by |
|
|||
366 | # the wire protocol. |
|
|||
367 |
|
363 | |||
368 | # process this if it's a protocol request |
|
364 | if protohandler: | |
369 | # protocol bits don't need to create any URLs |
|
365 | cmd = protohandler['cmd'] | |
370 | # and the clients always use the old URL structure |
|
|||
371 |
|
||||
372 | cmd = pycompat.sysbytes(req.form.get(r'cmd', [r''])[0]) |
|
|||
373 | if wireprotoserver.iscmd(cmd): |
|
|||
374 | try: |
|
366 | try: | |
375 | if query: |
|
367 | if query: | |
376 | raise ErrorResponse(HTTP_NOT_FOUND) |
|
368 | raise ErrorResponse(HTTP_NOT_FOUND) | |
377 | if cmd in perms: |
|
369 | if cmd in perms: | |
378 | self.check_perm(rctx, req, perms[cmd]) |
|
370 | self.check_perm(rctx, req, perms[cmd]) | |
379 | return wireprotoserver.callhttp(rctx.repo, req, cmd) |
|
371 | return protohandler['dispatch']() | |
380 | except ErrorResponse as inst: |
|
372 | except ErrorResponse as inst: | |
381 | # A client that sends unbundle without 100-continue will |
|
373 | # A client that sends unbundle without 100-continue will | |
382 | # break if we respond early. |
|
374 | # break if we respond early. | |
@@ -425,6 +417,8 b' class hgweb(object):' | |||||
425 | if fn.endswith(ext): |
|
417 | if fn.endswith(ext): | |
426 | req.form['node'] = [fn[:-len(ext)]] |
|
418 | req.form['node'] = [fn[:-len(ext)]] | |
427 | req.form['type'] = [type_] |
|
419 | req.form['type'] = [type_] | |
|
420 | else: | |||
|
421 | cmd = pycompat.sysbytes(req.form.get(r'cmd', [r''])[0]) | |||
428 |
|
422 | |||
429 | # process the web interface request |
|
423 | # process the web interface request | |
430 |
|
424 |
@@ -208,9 +208,43 b' class webproto(abstractserverproto):' | |||||
208 | def iscmd(cmd): |
|
208 | def iscmd(cmd): | |
209 | return cmd in wireproto.commands |
|
209 | return cmd in wireproto.commands | |
210 |
|
210 | |||
211 |
def |
|
211 | def parsehttprequest(repo, req, query): | |
|
212 | """Parse the HTTP request for a wire protocol request. | |||
|
213 | ||||
|
214 | If the current request appears to be a wire protocol request, this | |||
|
215 | function returns a dict with details about that request, including | |||
|
216 | an ``abstractprotocolserver`` instance suitable for handling the | |||
|
217 | request. Otherwise, ``None`` is returned. | |||
|
218 | ||||
|
219 | ``req`` is a ``wsgirequest`` instance. | |||
|
220 | """ | |||
|
221 | # HTTP version 1 wire protocol requests are denoted by a "cmd" query | |||
|
222 | # string parameter. If it isn't present, this isn't a wire protocol | |||
|
223 | # request. | |||
|
224 | if r'cmd' not in req.form: | |||
|
225 | return None | |||
|
226 | ||||
|
227 | cmd = pycompat.sysbytes(req.form[r'cmd'][0]) | |||
|
228 | ||||
|
229 | # The "cmd" request parameter is used by both the wire protocol and hgweb. | |||
|
230 | # While not all wire protocol commands are available for all transports, | |||
|
231 | # if we see a "cmd" value that resembles a known wire protocol command, we | |||
|
232 | # route it to a protocol handler. This is better than routing possible | |||
|
233 | # wire protocol requests to hgweb because it prevents hgweb from using | |||
|
234 | # known wire protocol commands and it is less confusing for machine | |||
|
235 | # clients. | |||
|
236 | if cmd not in wireproto.commands: | |||
|
237 | return None | |||
|
238 | ||||
212 | proto = webproto(req, repo.ui) |
|
239 | proto = webproto(req, repo.ui) | |
213 |
|
240 | |||
|
241 | return { | |||
|
242 | 'cmd': cmd, | |||
|
243 | 'proto': proto, | |||
|
244 | 'dispatch': lambda: _callhttp(repo, req, proto, cmd), | |||
|
245 | } | |||
|
246 | ||||
|
247 | def _callhttp(repo, req, proto, cmd): | |||
214 | def genversion2(gen, engine, engineopts): |
|
248 | def genversion2(gen, engine, engineopts): | |
215 | # application/mercurial-0.2 always sends a payload header |
|
249 | # application/mercurial-0.2 always sends a payload header | |
216 | # identifying the compression engine. |
|
250 | # identifying the compression engine. |
General Comments 0
You need to be logged in to leave comments.
Login now