From 6852eb9d0af5cf7196da5cad2ccf3b036e348226 Mon Sep 17 00:00:00 2001 From: Maximilian Hils Date: Fri, 10 Apr 2015 14:59:38 +0200 Subject: fix #553 --- libmproxy/protocol/http.py | 27 +++++++++++++++++++++++++-- test/test_protocol_http.py | 8 ++++++++ 2 files changed, 33 insertions(+), 2 deletions(-) diff --git a/libmproxy/protocol/http.py b/libmproxy/protocol/http.py index c763db4c..05657ea6 100644 --- a/libmproxy/protocol/http.py +++ b/libmproxy/protocol/http.py @@ -328,9 +328,22 @@ class HTTPRequest(HTTPMessage): ) @classmethod - def from_stream(cls, rfile, include_body=True, body_size_limit=None): + def from_stream(cls, rfile, include_body=True, body_size_limit=None, wfile=None): """ Parse an HTTP request from a file stream + + Args: + rfile (file): Input file to read from + include_body (bool): Read response body as well + body_size_limit (bool): Maximum body size + wfile (file): If specified, HTTP Expect headers are handled automatically. + by writing a HTTP 100 CONTINUE response to the stream. + + Returns: + HTTPRequest: The HTTP request + + Raises: + HttpError: If the input is invalid. """ httpversion, host, port, scheme, method, path, headers, content, timestamp_start, timestamp_end = ( None, None, None, None, None, None, None, None, None, None) @@ -385,6 +398,15 @@ class HTTPRequest(HTTPMessage): if headers is None: raise http.HttpError(400, "Invalid headers") + expect_header = headers.get_first("expect") + if expect_header and expect_header.lower() == "100-continue" and httpversion >= (1, 1): + wfile.write( + 'HTTP/1.1 100 Continue\r\n' + '\r\n' + ) + wfile.flush() + del headers['expect'] + if include_body: content = http.read_http_body(rfile, headers, body_size_limit, method, None, True) @@ -1062,7 +1084,8 @@ class HTTPHandler(ProtocolHandler): try: req = HTTPRequest.from_stream( self.c.client_conn.rfile, - body_size_limit=self.c.config.body_size_limit + body_size_limit=self.c.config.body_size_limit, + wfile=self.c.client_conn.wfile ) except tcp.NetLibError: # don't throw an error for disconnects that happen diff --git a/test/test_protocol_http.py b/test/test_protocol_http.py index 23c3f469..c6fad508 100644 --- a/test/test_protocol_http.py +++ b/test/test_protocol_http.py @@ -55,6 +55,14 @@ class TestHTTPRequest: r.update_host_header() assert "Host" in r.headers + def test_expect_header(self): + s = StringIO("GET / HTTP/1.1\r\nContent-Length: 3\r\nExpect: 100-continue\r\n\r\nfoobar") + w = StringIO() + r = HTTPRequest.from_stream(s, wfile=w) + assert w.getvalue() == "HTTP/1.1 100 Continue\r\n\r\n" + assert r.content == "foo" + assert s.read(3) == "bar" + def test_authority_form_in(self): s = StringIO("CONNECT oops-no-port.com HTTP/1.1") tutils.raises("Bad HTTP request line", HTTPRequest.from_stream, s) -- cgit v1.2.3