355 query = '/'.join(parts) |
355 query = '/'.join(parts) |
356 else: |
356 else: |
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 |
363 |
364 # of an errant request to an unavailable protocol command. And it |
364 if protohandler: |
365 # prevents hgweb from accidentally using ``cmd`` values used by |
365 cmd = protohandler['cmd'] |
366 # the wire protocol. |
|
367 |
|
368 # process this if it's a protocol request |
|
369 # protocol bits don't need to create any URLs |
|
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. |
383 if (cmd == 'unbundle' and |
375 if (cmd == 'unbundle' and |
384 (req.env.get('HTTP_EXPECT', |
376 (req.env.get('HTTP_EXPECT', |
423 for type_, spec in rctx.archivespecs.iteritems(): |
415 for type_, spec in rctx.archivespecs.iteritems(): |
424 ext = spec[2] |
416 ext = spec[2] |
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 |
431 try: |
425 try: |
432 tmpl = rctx.templater(req) |
426 tmpl = rctx.templater(req) |