Merge pull request #1073 from mitmproxy/first-line-format

form_(in|out) -> first_line_format
This commit is contained in:
Thomas Kriechbaumer 2016-04-03 10:16:06 +02:00
commit 16fdbb4f2f
9 changed files with 37 additions and 76 deletions

View File

@ -80,18 +80,13 @@ class HTTPRequest(MessageMixin, Request):
content: Content of the request, the value is None if there is content
associated, but not present.
form_in: The request form which mitmproxy has received. The following
values are possible:
first_line_format: The request form. The following values are possible:
- relative (GET /index.html, OPTIONS *) (covers origin form and
asterisk form)
- relative (GET /index.html, OPTIONS *) (origin form or asterisk form)
- absolute (GET http://example.com:80/index.html)
- authority-form (CONNECT example.com:443)
Details: http://tools.ietf.org/html/draft-ietf-httpbis-p1-messaging-25#section-5.3
form_out: The request form which mitmproxy will send out to the
destination
timestamp_start: Timestamp indicating when request transmission started
timestamp_end: Timestamp indicating when request transmission ended
@ -110,7 +105,6 @@ class HTTPRequest(MessageMixin, Request):
content,
timestamp_start=None,
timestamp_end=None,
form_out=None,
is_replay=False,
stickycookie=False,
stickyauth=False,
@ -129,7 +123,6 @@ class HTTPRequest(MessageMixin, Request):
timestamp_start,
timestamp_end,
)
self.form_out = form_out or first_line_format # FIXME remove
# Have this request's cookies been modified by sticky cookies or auth?
self.stickycookie = stickycookie
@ -167,20 +160,9 @@ class HTTPRequest(MessageMixin, Request):
content=request.data.content,
timestamp_start=request.data.timestamp_start,
timestamp_end=request.data.timestamp_end,
form_out=(request.form_out if hasattr(request, 'form_out') else None),
)
return req
@property
def form_out(self):
warnings.warn(".form_out is deprecated, use .first_line_format instead.", DeprecationWarning)
return self.first_line_format
@form_out.setter
def form_out(self, value):
warnings.warn(".form_out is deprecated, use .first_line_format instead.", DeprecationWarning)
self.first_line_format = value
def __hash__(self):
return id(self)

View File

@ -167,7 +167,7 @@ class HttpLayer(Layer):
self.validate_request(request)
# Regular Proxy Mode: Handle CONNECT
if self.mode == "regular" and request.form_in == "authority":
if self.mode == "regular" and request.first_line_format == "authority":
self.handle_regular_mode_connect(request)
return
@ -215,7 +215,7 @@ class HttpLayer(Layer):
return
# Upstream Proxy Mode: Handle CONNECT
if flow.request.form_in == "authority" and flow.response.status_code == 200:
if flow.request.first_line_format == "authority" and flow.response.status_code == 200:
self.handle_upstream_mode_connect(flow.request.copy())
return
@ -340,7 +340,7 @@ class HttpLayer(Layer):
if self.mode == "regular":
pass # only absolute-form at this point, nothing to do here.
elif self.mode == "upstream":
if flow.request.form_in == "authority":
if flow.request.first_line_format == "authority":
flow.request.scheme = "http" # pseudo value
else:
# Setting request.host also updates the host header, which we want to preserve
@ -390,7 +390,7 @@ class HttpLayer(Layer):
"""
def validate_request(self, request):
if request.form_in == "absolute" and request.scheme != "http":
if request.first_line_format == "absolute" and request.scheme != "http":
raise HttpException("Invalid request scheme: %s" % request.scheme)
expected_request_forms = {
@ -400,14 +400,14 @@ class HttpLayer(Layer):
}
allowed_request_forms = expected_request_forms[self.mode]
if request.form_in not in allowed_request_forms:
if request.first_line_format not in allowed_request_forms:
err_message = "Invalid HTTP request form (expected: %s, got: %s)" % (
" or ".join(allowed_request_forms), request.form_in
" or ".join(allowed_request_forms), request.first_line_format
)
raise HttpException(err_message)
if self.mode == "regular" and request.form_in == "absolute":
request.form_out = "relative"
if self.mode == "regular" and request.first_line_format == "absolute":
request.first_line_format = "relative"
def authenticate(self, request):
if self.config.authenticator:

View File

@ -54,7 +54,7 @@ class Http1Layer(_HttpTransmissionLayer):
)
read_until_eof = http1.expected_http_body_size(flow.request, flow.response) == -1
close_connection = request_close or response_close or read_until_eof
if flow.request.form_in == "authority" and flow.response.status_code == 200:
if flow.request.first_line_format == "authority" and flow.response.status_code == 200:
# Workaround for https://github.com/mitmproxy/mitmproxy/issues/313:
# Charles Proxy sends a CONNECT response with HTTP/1.0
# and no Content-Length header

View File

@ -303,11 +303,11 @@ class Http2SingleStreamLayer(_HttpTransmissionLayer, threading.Thread):
port = None
if path == '*' or path.startswith("/"):
form_in = "relative"
first_line_format = "relative"
elif method == 'CONNECT': # pragma: no cover
raise NotImplementedError("CONNECT over HTTP/2 is not implemented.")
else: # pragma: no cover
form_in = "absolute"
first_line_format = "absolute"
# FIXME: verify if path or :host contains what we need
scheme, host, port, _ = utils.parse_url(path)
@ -326,7 +326,7 @@ class Http2SingleStreamLayer(_HttpTransmissionLayer, threading.Thread):
data = b"".join(data)
return HTTPRequest(
form_in,
first_line_format,
method,
scheme,
host,

View File

@ -30,7 +30,7 @@ class RequestReplayThread(threading.Thread):
def run(self):
r = self.flow.request
form_out_backup = r.form_out
first_line_format_backup = r.first_line_format
try:
self.flow.response = None
@ -63,9 +63,9 @@ class RequestReplayThread(threading.Thread):
self.config.clientcerts,
sni=self.flow.server_conn.sni
)
r.form_out = "relative"
r.first_line_format = "relative"
else:
r.form_out = "absolute"
r.first_line_format= "absolute"
else:
server_address = (r.host, r.port)
server = ServerConnection(server_address, (self.config.host, 0))
@ -75,7 +75,7 @@ class RequestReplayThread(threading.Thread):
self.config.clientcerts,
sni=self.flow.server_conn.sni
)
r.form_out = "relative"
r.first_line_format = "relative"
server.wfile.write(http1.assemble_request(r))
server.wfile.flush()
@ -102,4 +102,4 @@ class RequestReplayThread(threading.Thread):
from ..proxy.root_context import Log
self.channel.tell("log", Log(traceback.format_exc(), "error"))
finally:
r.form_out = form_out_backup
r.first_line_format = first_line_format_backup

View File

@ -102,15 +102,15 @@ class HTTP2Protocol(object):
port = None
if path == '*' or path.startswith("/"):
form_in = "relative"
first_line_format = "relative"
elif method == 'CONNECT':
form_in = "authority"
first_line_format = "authority"
if ":" in authority:
host, port = authority.split(":", 1)
else:
host = authority
else:
form_in = "absolute"
first_line_format = "absolute"
# FIXME: verify if path or :host contains what we need
scheme, host, port, _ = utils.parse_url(path)
scheme = scheme.decode('ascii')
@ -123,7 +123,7 @@ class HTTP2Protocol(object):
port = int(port)
request = Request(
form_in,
first_line_format,
method.encode('ascii'),
scheme.encode('ascii'),
host.encode('ascii'),

View File

@ -358,24 +358,3 @@ class Request(Message):
def get_form_multipart(self): # pragma: no cover
warnings.warn(".get_form_multipart is deprecated, use .multipart_form instead.", DeprecationWarning)
return self.multipart_form or ODict([])
@property
def form_in(self): # pragma: no cover
warnings.warn(".form_in is deprecated, use .first_line_format instead.", DeprecationWarning)
return self.first_line_format
@form_in.setter
def form_in(self, form_in): # pragma: no cover
warnings.warn(".form_in is deprecated, use .first_line_format instead.", DeprecationWarning)
self.first_line_format = form_in
@property
def form_out(self): # pragma: no cover
warnings.warn(".form_out is deprecated, use .first_line_format instead.", DeprecationWarning)
return self.first_line_format
@form_out.setter
def form_out(self, form_out): # pragma: no cover
warnings.warn(".form_out is deprecated, use .first_line_format instead.", DeprecationWarning)
self.first_line_format = form_out

View File

@ -973,22 +973,22 @@ class TestProxyChainingSSLReconnect(tservers.HTTPUpstreamProxyTest):
assert not self.chain[1].tmaster.state.flows[0].response # killed
assert self.chain[1].tmaster.state.flows[1].response
assert self.proxy.tmaster.state.flows[0].request.form_in == "authority"
assert self.proxy.tmaster.state.flows[1].request.form_in == "relative"
assert self.proxy.tmaster.state.flows[0].request.first_line_format == "authority"
assert self.proxy.tmaster.state.flows[1].request.first_line_format == "relative"
assert self.chain[0].tmaster.state.flows[
0].request.form_in == "authority"
0].request.first_line_format == "authority"
assert self.chain[0].tmaster.state.flows[
1].request.form_in == "relative"
1].request.first_line_format == "relative"
assert self.chain[0].tmaster.state.flows[
2].request.form_in == "authority"
2].request.first_line_format == "authority"
assert self.chain[0].tmaster.state.flows[
3].request.form_in == "relative"
3].request.first_line_format == "relative"
assert self.chain[1].tmaster.state.flows[
0].request.form_in == "relative"
0].request.first_line_format == "relative"
assert self.chain[1].tmaster.state.flows[
1].request.form_in == "relative"
1].request.first_line_format == "relative"
req = p.request("get:'/p/418:b\"content2\"'")

View File

@ -325,7 +325,7 @@ class TestReadRequestRelative(tservers.ServerTestBase):
ssl = True
def test_asterisk_form_in(self):
def test_asterisk_form(self):
c = tcp.TCPClient(("127.0.0.1", self.port))
c.connect()
c.convert_to_ssl()
@ -334,7 +334,7 @@ class TestReadRequestRelative(tservers.ServerTestBase):
req = protocol.read_request(NotImplemented)
assert req.form_in == "relative"
assert req.first_line_format == "relative"
assert req.method == "OPTIONS"
assert req.path == "*"
@ -348,7 +348,7 @@ class TestReadRequestAbsolute(tservers.ServerTestBase):
ssl = True
def test_absolute_form_in(self):
def test_absolute_form(self):
c = tcp.TCPClient(("127.0.0.1", self.port))
c.connect()
c.convert_to_ssl()
@ -357,7 +357,7 @@ class TestReadRequestAbsolute(tservers.ServerTestBase):
req = protocol.read_request(NotImplemented)
assert req.form_in == "absolute"
assert req.first_line_format == "absolute"
assert req.scheme == "http"
assert req.host == "address"
assert req.port == 22
@ -382,13 +382,13 @@ class TestReadRequestConnect(tservers.ServerTestBase):
protocol.connection_preface_performed = True
req = protocol.read_request(NotImplemented)
assert req.form_in == "authority"
assert req.first_line_format == "authority"
assert req.method == "CONNECT"
assert req.host == "address"
assert req.port == 22
req = protocol.read_request(NotImplemented)
assert req.form_in == "authority"
assert req.first_line_format == "authority"
assert req.method == "CONNECT"
assert req.host == "example.com"
assert req.port == 443