Mercurial > public > mercurial-scm > hg-stable
diff mercurial/hgweb/request.py @ 37818:877185de62cf stable
hgweb: reuse body file object when hgwebdir calls hgweb (issue5851)
An unintended side-effect of f0a851542a05 was that the request body
file object (which uses a util.cappedreader) was constructed twice
when hgwebdir called into hgweb. Since we attempt to read all remaining
data from this file object when Content-Length is defined and since there
were two instances of this object and the client supplied no additional
data to read, this resulted in deadlock.
The fix implemented in this commit is to reuse the request body file
object when it is passed from hgwebdir to hgweb.
A test demonstrating `hg clone` and `hg push` via hgwebdir has been
added. Without this patch, the test hangs when doing `hg clone`.
Surprisingly, this must mean that we have effectively no test coverage
of the wire protocol when run via hgwebdir.
Differential Revision: https://phab.mercurial-scm.org/D3427
author | Gregory Szorc <gregory.szorc@gmail.com> |
---|---|
date | Tue, 24 Apr 2018 13:55:25 -0700 |
parents | 5e81cf9651c1 |
children | e82b137a8b4e |
line wrap: on
line diff
--- a/mercurial/hgweb/request.py Wed Apr 25 00:26:49 2018 +0530 +++ b/mercurial/hgweb/request.py Tue Apr 24 13:55:25 2018 -0700 @@ -124,7 +124,7 @@ # WSGI environment dict, unmodified. rawenv = attr.ib() -def parserequestfromenv(env, reponame=None, altbaseurl=None): +def parserequestfromenv(env, reponame=None, altbaseurl=None, bodyfh=None): """Parse URL components from environment variables. WSGI defines request attributes via environment variables. This function @@ -144,6 +144,9 @@ if the request were to ``http://myserver:9000/prefix/rev/@``. In other words, ``wsgi.url_scheme``, ``SERVER_NAME``, ``SERVER_PORT``, and ``SCRIPT_NAME`` are all effectively replaced by components from this URL. + + ``bodyfh`` can be used to specify a file object to read the request body + from. If not defined, ``wsgi.input`` from the environment dict is used. """ # PEP 3333 defines the WSGI spec and is a useful reference for this code. @@ -307,9 +310,10 @@ if 'CONTENT_TYPE' in env and 'HTTP_CONTENT_TYPE' not in env: headers['Content-Type'] = env['CONTENT_TYPE'] - bodyfh = env['wsgi.input'] - if 'Content-Length' in headers: - bodyfh = util.cappedreader(bodyfh, int(headers['Content-Length'])) + if bodyfh is None: + bodyfh = env['wsgi.input'] + if 'Content-Length' in headers: + bodyfh = util.cappedreader(bodyfh, int(headers['Content-Length'])) return parsedrequest(method=env['REQUEST_METHOD'], url=fullurl, baseurl=baseurl,