##// 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 357 query = req.env[r'QUERY_STRING'].partition(r'&')[0]
358 358 query = query.partition(r';')[0]
359 359
360 # The ``cmd`` request parameter is used by both the wire protocol
361 # and hgweb. We route all known wire protocol commands to the
362 # wire protocol handler, even if the command isn't available for
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.
360 # Route it to a wire protocol handler if it looks like a wire protocol
361 # request.
362 protohandler = wireprotoserver.parsehttprequest(rctx.repo, req, query)
367 363
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):
364 if protohandler:
365 cmd = protohandler['cmd']
374 366 try:
375 367 if query:
376 368 raise ErrorResponse(HTTP_NOT_FOUND)
377 369 if cmd in perms:
378 370 self.check_perm(rctx, req, perms[cmd])
379 return wireprotoserver.callhttp(rctx.repo, req, cmd)
371 return protohandler['dispatch']()
380 372 except ErrorResponse as inst:
381 373 # A client that sends unbundle without 100-continue will
382 374 # break if we respond early.
@@ -425,6 +417,8 b' class hgweb(object):'
425 417 if fn.endswith(ext):
426 418 req.form['node'] = [fn[:-len(ext)]]
427 419 req.form['type'] = [type_]
420 else:
421 cmd = pycompat.sysbytes(req.form.get(r'cmd', [r''])[0])
428 422
429 423 # process the web interface request
430 424
@@ -208,9 +208,43 b' class webproto(abstractserverproto):'
208 208 def iscmd(cmd):
209 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 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 248 def genversion2(gen, engine, engineopts):
215 249 # application/mercurial-0.2 always sends a payload header
216 250 # identifying the compression engine.
General Comments 0
You need to be logged in to leave comments. Login now