# HG changeset patch # User Gregory Szorc # Date 2018-03-10 18:45:12 # Node ID ed0456fde625b92adb965be9b62642fcc606c604 # Parent 14f70c44af6cc47e0bbe43a2ca144f19599253f3 hgweb: handle CONTENT_LENGTH PEP 3333 says CONTENT_LENGTH may be set. I /think/ WSGI servers are allowed to invent this key even if the client didn't send it. We had code in wireprotoserver looking for this key. So let's just automagically convert this key to an HTTP request header when parsing the request. Differential Revision: https://phab.mercurial-scm.org/D2744 diff --git a/mercurial/hgweb/request.py b/mercurial/hgweb/request.py --- a/mercurial/hgweb/request.py +++ b/mercurial/hgweb/request.py @@ -200,6 +200,13 @@ def parserequestfromenv(env): headers = wsgiheaders.Headers(headers) + # This is kind of a lie because the HTTP header wasn't explicitly + # sent. But for all intents and purposes it should be OK to lie about + # this, since a consumer will either either value to determine how many + # bytes are available to read. + if 'CONTENT_LENGTH' in env and 'HTTP_CONTENT_LENGTH' not in env: + headers['Content-Length'] = env['CONTENT_LENGTH'] + return parsedrequest(url=fullurl, baseurl=baseurl, advertisedurl=advertisedfullurl, advertisedbaseurl=advertisedbaseurl, diff --git a/mercurial/wireprotoserver.py b/mercurial/wireprotoserver.py --- a/mercurial/wireprotoserver.py +++ b/mercurial/wireprotoserver.py @@ -91,10 +91,9 @@ class httpv1protocolhandler(wireprototyp return args def forwardpayload(self, fp): - if b'Content-Length' in self._req.headers: - length = int(self._req.headers[b'Content-Length']) - else: - length = int(self._wsgireq.env[r'CONTENT_LENGTH']) + # Existing clients *always* send Content-Length. + length = int(self._req.headers[b'Content-Length']) + # If httppostargs is used, we need to read Content-Length # minus the amount that was consumed by args. length -= int(self._req.headers.get(b'X-HgArgs-Post', 0))