##// END OF EJS Templates
wireprotoserver: move protocol parsing and dispatch out of hgweb...
Gregory Szorc -
r36002:cdc93fe1 default
parent child Browse files
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 callhttp(repo, req, cmd):
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