mirror of
https://github.com/facebook/sapling.git
synced 2024-10-09 00:14:35 +03:00
9ccf5570f8
This patch fixes a bug where hgweb would send an incomplete HTTP response. If an uncaught exception is raised when hgweb is processing a request, hgweb attempts to send a generic error response and log that exception. The server defaults to chunked transfer coding. If an uncaught exception occurred, it was sending the error response string / chunk properly. However, RFC 7230 Section 4.1 mandates a 0 size last chunk be sent to indicate end of the entity body. hgweb was failing to send this last chunk. As a result, properly written HTTP clients would assume more data was coming and they would likely time out waiting for another chunk to arrive. Mercurial's own test harness was paving over the improper HTTP behavior by not attempting to read the response body if the status code was 500. This incorrect workaround was added in faced8f5c2af and has been removed with this patch.
61 lines
1.6 KiB
Python
Executable File
61 lines
1.6 KiB
Python
Executable File
#!/usr/bin/env python
|
|
|
|
"""This does HTTP GET requests given a host:port and path and returns
|
|
a subset of the headers plus the body of the result."""
|
|
|
|
import httplib, sys
|
|
|
|
try:
|
|
import msvcrt, os
|
|
msvcrt.setmode(sys.stdout.fileno(), os.O_BINARY)
|
|
msvcrt.setmode(sys.stderr.fileno(), os.O_BINARY)
|
|
except ImportError:
|
|
pass
|
|
|
|
twice = False
|
|
if '--twice' in sys.argv:
|
|
sys.argv.remove('--twice')
|
|
twice = True
|
|
headeronly = False
|
|
if '--headeronly' in sys.argv:
|
|
sys.argv.remove('--headeronly')
|
|
headeronly = True
|
|
|
|
reasons = {'Not modified': 'Not Modified'} # python 2.4
|
|
|
|
tag = None
|
|
def request(host, path, show):
|
|
assert not path.startswith('/'), path
|
|
global tag
|
|
headers = {}
|
|
if tag:
|
|
headers['If-None-Match'] = tag
|
|
|
|
conn = httplib.HTTPConnection(host)
|
|
conn.request("GET", '/' + path, None, headers)
|
|
response = conn.getresponse()
|
|
print response.status, reasons.get(response.reason, response.reason)
|
|
if show[:1] == ['-']:
|
|
show = sorted(h for h, v in response.getheaders()
|
|
if h.lower() not in show)
|
|
for h in [h.lower() for h in show]:
|
|
if response.getheader(h, None) is not None:
|
|
print "%s: %s" % (h, response.getheader(h))
|
|
if not headeronly:
|
|
print
|
|
data = response.read()
|
|
sys.stdout.write(data)
|
|
|
|
if twice and response.getheader('ETag', None):
|
|
tag = response.getheader('ETag')
|
|
|
|
return response.status
|
|
|
|
status = request(sys.argv[1], sys.argv[2], sys.argv[3:])
|
|
if twice:
|
|
status = request(sys.argv[1], sys.argv[2], sys.argv[3:])
|
|
|
|
if 200 <= status <= 305:
|
|
sys.exit(0)
|
|
sys.exit(1)
|