Add proxy.should_connection_close, and strip out unused code.

This commit is contained in:
Aldo Cortesi 2012-06-10 10:10:46 +12:00
parent 0c458e2f1a
commit 8254187bf3
2 changed files with 26 additions and 60 deletions

View File

@ -183,38 +183,22 @@ def parse_init_http(line):
return method, url, mm[0], mm[1]
#FIXME: Return full HTTP version specification from here. Allow non-HTTP
#protocol specs, and make it all editable.
def parse_request_line(request):
def should_connection_close(httpmajor, httpminor, headers):
"""
Parse a proxy request line. Return (method, scheme, host, port, path, minor).
Raise ProxyError on error.
Checks the HTTP version and headers to see if this connection should be
closed.
"""
try:
method, url, protocol = string.split(request)
except ValueError:
raise ProxyError(400, "Can't parse request")
if method == 'CONNECT':
scheme = None
path = None
try:
host, port = url.split(":")
except ValueError:
raise ProxyError(400, "Can't parse request")
port = int(port)
elif url.startswith("/") or url == "*":
scheme, port, host, path = None, None, None, url
else:
parts = utils.parse_url(url)
if not parts:
raise ProxyError(400, "Invalid url: %s"%url)
scheme, host, port, path = parts
if not protocol.startswith("HTTP/"):
raise ProxyError(400, "Unsupported protocol")
major,minor = protocol.split('/')[1].split('.')
major = int(major)
minor = int(minor)
return method, scheme, host, port, path, minor
if "connection" in headers:
for value in ",".join(headers['connection']).split(","):
value = value.strip()
if value == "close":
return True
elif value == "keep-alive":
return False
# HTTP 1.1 connections are assumed to be persistent
if httpmajor == 1 and httpminor == 1:
return False
return True
class FileLike:
@ -302,7 +286,6 @@ class ServerConnection:
self.rfile, self.wfile = server.makefile('rb'), server.makefile('wb')
def send(self, request):
request.close = self.close
try:
d = request._assemble()
if not d:
@ -350,6 +333,7 @@ class ProxyHandler(SocketServer.StreamRequestHandler):
def __init__(self, config, request, client_address, server, q):
self.config = config
self.mqueue = q
self.server_conn = None
SocketServer.StreamRequestHandler.__init__(self, request, client_address, server)
def handle(self):
@ -389,9 +373,9 @@ class ProxyHandler(SocketServer.StreamRequestHandler):
else:
if self.config.reverse_proxy:
scheme, host, port = self.config.reverse_proxy
server_conn = ServerConnection(self.config, scheme, host, port)
else:
server_conn = ServerConnection(self.config, request.scheme, request.host, request.port)
scheme, host, port = request.scheme, request.host, request.port
server_conn = ServerConnection(self.config, scheme, host, port)
server_conn.send(request)
try:
response = server_conn.read_response(request)

View File

@ -24,6 +24,15 @@ def test_read_chunked():
tutils.raises(proxy.ProxyError, proxy.read_chunked, s, None)
def test_should_connection_close():
h = flow.ODictCaseless()
assert proxy.should_connection_close(1, 0, h)
assert not proxy.should_connection_close(1, 1, h)
h["connection"] = ["keep-alive"]
assert not proxy.should_connection_close(1, 1, h)
def test_read_http_body():
d = Dummy()
h = flow.ODict()
@ -47,33 +56,6 @@ def test_read_http_body():
assert len(proxy.read_http_body(s, d, h, True, 100)) == 7
class TestParseRequestLine:
def test_simple(self):
tutils.raises(proxy.ProxyError, proxy.parse_request_line, "")
u = "GET ... HTTP/1.1"
tutils.raises("invalid url", proxy.parse_request_line, u)
u = "GET http://foo.com:8888/test HTTP/1.1"
m, s, h, po, pa, minor = proxy.parse_request_line(u)
assert m == "GET"
assert s == "http"
assert h == "foo.com"
assert po == 8888
assert pa == "/test"
assert minor == 1
def test_connect(self):
u = "CONNECT host.com:443 HTTP/1.0"
expected = ('CONNECT', None, 'host.com', 443, None, 0)
ret = proxy.parse_request_line(u)
assert expected == ret
def test_inner(self):
u = "GET / HTTP/1.1"
assert proxy.parse_request_line(u) == ('GET', None, None, None, '/', 1)
class TestFileLike:
def test_wrap(self):
s = cStringIO.StringIO("foobar\nfoobar")