def test_connection_close(): h = odict.ODictCaseless() assert HTTP1Protocol.connection_close((1, 0), h) assert not HTTP1Protocol.connection_close((1, 1), h) h["connection"] = ["keep-alive"] assert not HTTP1Protocol.connection_close((1, 1), h) h["connection"] = ["close"] assert HTTP1Protocol.connection_close((1, 1), h)
def test_connection_close(): headers = Headers() assert HTTP1Protocol.connection_close((1, 0), headers) assert not HTTP1Protocol.connection_close((1, 1), headers) headers["connection"] = "keep-alive" assert not HTTP1Protocol.connection_close((1, 1), headers) headers["connection"] = "close" assert HTTP1Protocol.connection_close((1, 1), headers)
def test_parse_init_connect(): assert HTTP1Protocol._parse_init_connect("CONNECT host.com:443 HTTP/1.0") assert not HTTP1Protocol._parse_init_connect("C\xfeONNECT host.com:443 HTTP/1.0") assert not HTTP1Protocol._parse_init_connect("CONNECT \0host.com:443 HTTP/1.0") assert not HTTP1Protocol._parse_init_connect("CONNECT host.com:444444 HTTP/1.0") assert not HTTP1Protocol._parse_init_connect("bogus") assert not HTTP1Protocol._parse_init_connect("GET host.com:443 HTTP/1.0") assert not HTTP1Protocol._parse_init_connect("CONNECT host.com443 HTTP/1.0") assert not HTTP1Protocol._parse_init_connect("CONNECT host.com:443 foo/1.0") assert not HTTP1Protocol._parse_init_connect("CONNECT host.com:foo HTTP/1.0")
def test_parse_init_proxy(): u = "GET http://foo.com:8888/test HTTP/1.1" m, s, h, po, pa, httpversion = HTTP1Protocol._parse_init_proxy(u) assert m == "GET" assert s == "http" assert h == "foo.com" assert po == 8888 assert pa == "/test" assert httpversion == (1, 1) u = "G\xfeET http://foo.com:8888/test HTTP/1.1" assert not HTTP1Protocol._parse_init_proxy(u) assert not HTTP1Protocol._parse_init_proxy("invalid") assert not HTTP1Protocol._parse_init_proxy("GET invalid HTTP/1.1") assert not HTTP1Protocol._parse_init_proxy("GET http://foo.com:8888/test foo/1.1")
def test_expected_http_body_size(): # gibber in the content-length field headers = Headers(content_length="foo") assert HTTP1Protocol.expected_http_body_size(headers, False, "GET", 200) is None # negative number in the content-length field headers = Headers(content_length="-7") assert HTTP1Protocol.expected_http_body_size(headers, False, "GET", 200) is None # explicit length headers = Headers(content_length="5") assert HTTP1Protocol.expected_http_body_size(headers, False, "GET", 200) == 5 # no length headers = Headers() assert HTTP1Protocol.expected_http_body_size(headers, False, "GET", 200) == -1 # no length request headers = Headers() assert HTTP1Protocol.expected_http_body_size(headers, True, "GET", None) == 0
def handle(self): self.log("clientconnect", "info") root_layer = self._create_root_layer() root_layer = self.channel.ask("clientconnect", root_layer) if root_layer == Kill: def root_layer(): raise Kill() try: root_layer() except Kill: self.log("Connection killed", "info") except ProtocolException as e: self.log(e, "info") # If an error propagates to the topmost level, # we send an HTTP error response, which is both # understandable by HTTP clients and humans. try: error_response = make_error_response(502, repr(e)) self.client_conn.send(HTTP1Protocol().assemble(error_response)) except NetLibError: pass except Exception: self.log(traceback.format_exc(), "error") print(traceback.format_exc(), file=sys.stderr) print("mitmproxy has crashed!", file=sys.stderr) print( "Please lodge a bug report at: https://github.com/mitmproxy/mitmproxy", file=sys.stderr) self.log("clientdisconnect", "info") self.channel.tell("clientdisconnect", root_layer) self.client_conn.finish()
def test_simple(self): resp = tutils.tresp() b = HTTP1Protocol().assemble_response(resp) assert b == match_http_string(""" HTTP/1.1 200 OK header_response: svalue Content-Length: 7 message""")
def test_expected_http_body_size(): # gibber in the content-length field h = odict.ODictCaseless() h["content-length"] = ["foo"] assert HTTP1Protocol.expected_http_body_size(h, False, "GET", 200) is None # negative number in the content-length field h = odict.ODictCaseless() h["content-length"] = ["-7"] assert HTTP1Protocol.expected_http_body_size(h, False, "GET", 200) is None # explicit length h = odict.ODictCaseless() h["content-length"] = ["5"] assert HTTP1Protocol.expected_http_body_size(h, False, "GET", 200) == 5 # no length h = odict.ODictCaseless() assert HTTP1Protocol.expected_http_body_size(h, False, "GET", 200) == -1 # no length request h = odict.ODictCaseless() assert HTTP1Protocol.expected_http_body_size(h, True, "GET", None) == 0
def test_simple(self): req = tutils.treq() b = HTTP1Protocol().assemble_request(req) assert b == match_http_string(""" GET /path HTTP/1.1 header: qvalue Host: address:22 Content-Length: 7 content""")
def handshake(self): http1_protocol = HTTP1Protocol(self) req = http1_protocol.read_request() key = self.protocol.check_client_handshake(req.headers) preamble = 'HTTP/1.1 101 %s' % status_codes.RESPONSES.get(101) self.wfile.write(preamble + "\r\n") headers = self.protocol.server_handshake_headers(key) self.wfile.write(str(headers) + "\r\n") self.wfile.flush() self.handshake_done = True
def handshake(self): http1_protocol = HTTP1Protocol(self) client_hs = http1_protocol.read_request() self.protocol.check_client_handshake(client_hs.headers) preamble = 'HTTP/1.1 101 %s' % status_codes.RESPONSES.get(101) self.wfile.write(preamble + "\r\n") headers = self.protocol.server_handshake_headers("malformed key") self.wfile.write(headers.format() + "\r\n") self.wfile.flush() self.handshake_done = True
def test_parse_http_protocol(): assert HTTP1Protocol._parse_http_protocol("HTTP/1.1") == (1, 1) assert HTTP1Protocol._parse_http_protocol("HTTP/0.0") == (0, 0) assert not HTTP1Protocol._parse_http_protocol("HTTP/a.1") assert not HTTP1Protocol._parse_http_protocol("HTTP/1.a") assert not HTTP1Protocol._parse_http_protocol("foo/0.0") assert not HTTP1Protocol._parse_http_protocol("HTTP/x")
def connect(self): super(WebSocketsClient, self).connect() http1_protocol = HTTP1Protocol(self) preamble = 'GET / HTTP/1.1' self.wfile.write(preamble + "\r\n") headers = self.protocol.client_handshake_headers() self.client_nonce = headers["sec-websocket-key"] self.wfile.write(str(headers) + "\r\n") self.wfile.flush() resp = http1_protocol.read_response("GET", None) server_nonce = self.protocol.check_server_handshake(resp.headers) if not server_nonce == self.protocol.create_server_nonce( self.client_nonce): self.close()
def test_parse_init_http(): u = "GET /test HTTP/1.1" m, u, httpversion = HTTP1Protocol._parse_init_http(u) assert m == "GET" assert u == "/test" assert httpversion == (1, 1) u = "G\xfeET /test HTTP/1.1" assert not HTTP1Protocol._parse_init_http(u) assert not HTTP1Protocol._parse_init_http("invalid") assert not HTTP1Protocol._parse_init_http("GET invalid HTTP/1.1") assert not HTTP1Protocol._parse_init_http("GET /test foo/1.1") assert not HTTP1Protocol._parse_init_http("GET /test\xc0 HTTP/1.1")
def test_not_a_request(self): tutils.raises(AssertionError, HTTP1Protocol().assemble_response, 'foo')
def test_body_missing(self): resp = tutils.tresp(content=semantics.CONTENT_MISSING) tutils.raises(http.HttpError, HTTP1Protocol().assemble_response, resp)
def connect(self): self.ctx.connect() self.server_protocol = HTTP1Protocol(self.server_conn)
def set_server(self, *args, **kwargs): self.ctx.set_server(*args, **kwargs) self.server_protocol = HTTP1Protocol(self.server_conn)
def test_no_content_length(self): c = tcp.TCPClient(("127.0.0.1", self.port)) c.connect() resp = HTTP1Protocol(c).read_response("GET", None) assert resp.body == "bar\r\n\r\n"
def test_has_chunked_encoding(): headers = http.Headers() assert not HTTP1Protocol.has_chunked_encoding(headers) headers["transfer-encoding"] = "chunked" assert HTTP1Protocol.has_chunked_encoding(headers)
def __init__(self, ctx, mode): super(Http1Layer, self).__init__(ctx) self.mode = mode self.client_protocol = HTTP1Protocol(self.client_conn) self.server_protocol = HTTP1Protocol(self.server_conn)
def test_has_chunked_encoding(): h = odict.ODictCaseless() assert not HTTP1Protocol.has_chunked_encoding(h) h["transfer-encoding"] = ["chunked"] assert HTTP1Protocol.has_chunked_encoding(h)
def run(self): r = self.flow.request form_out_backup = r.form_out try: self.flow.response = None # If we have a channel, run script hooks. if self.channel: request_reply = self.channel.ask("request", self.flow) if request_reply == Kill: raise Kill() elif isinstance(request_reply, HTTPResponse): self.flow.response = request_reply if not self.flow.response: # In all modes, we directly connect to the server displayed if self.config.mode == "upstream": server_address = self.config.upstream_server.address server = ServerConnection(server_address) server.connect() protocol = HTTP1Protocol(server) if r.scheme == "https": connect_request = make_connect_request( (r.host, r.port)) server.send(protocol.assemble(connect_request)) resp = protocol.read_response("CONNECT") if resp.code != 200: raise HttpError( 502, "Upstream server refuses CONNECT request") server.establish_ssl(self.config.clientcerts, sni=self.flow.server_conn.sni) r.form_out = "relative" else: r.form_out = "absolute" else: server_address = (r.host, r.port) server = ServerConnection(server_address) server.connect() protocol = HTTP1Protocol(server) if r.scheme == "https": server.establish_ssl(self.config.clientcerts, sni=self.flow.server_conn.sni) r.form_out = "relative" server.send(protocol.assemble(r)) self.flow.server_conn = server self.flow.response = HTTPResponse.from_protocol( protocol, r.method, body_size_limit=self.config.body_size_limit, ) if self.channel: response_reply = self.channel.ask("response", self.flow) if response_reply == Kill: raise Kill() except (HttpError, NetLibError) as v: self.flow.error = Error(repr(v)) if self.channel: self.channel.ask("error", self.flow) except Kill: # Kill should only be raised if there's a channel in the # first place. from ..proxy.root_context import Log self.channel.tell("log", Log("Connection killed", "info")) finally: r.form_out = form_out_backup
def mock_protocol(data=''): rfile = cStringIO.StringIO(data) wfile = cStringIO.StringIO() return HTTP1Protocol(rfile=rfile, wfile=wfile)