mirror of
https://github.com/Grasscutters/mitmproxy.git
synced 2024-11-27 02:24:18 +00:00
Make Message classes more self-contained.
This commit is contained in:
parent
b2deb470de
commit
a09584b9e6
@ -85,6 +85,7 @@ def serve(msg, fp, settings, request_host=None):
|
|||||||
|
|
||||||
Calling this function may modify the object.
|
Calling this function may modify the object.
|
||||||
"""
|
"""
|
||||||
|
msg = msg.resolve(settings, request_host)
|
||||||
started = time.time()
|
started = time.time()
|
||||||
|
|
||||||
hdrs = msg.headervals(settings, request_host)
|
hdrs = msg.headervals(settings, request_host)
|
||||||
@ -96,7 +97,11 @@ def serve(msg, fp, settings, request_host=None):
|
|||||||
if msg.body:
|
if msg.body:
|
||||||
vals.append(msg.body.value.get_generator(settings))
|
vals.append(msg.body.value.get_generator(settings))
|
||||||
vals.reverse()
|
vals.reverse()
|
||||||
actions = msg.ready_actions(settings, request_host)
|
|
||||||
|
actions = msg.actions[:]
|
||||||
|
actions.sort()
|
||||||
|
actions.reverse()
|
||||||
|
actions = [i.intermediate(settings) for i in actions]
|
||||||
|
|
||||||
disconnect = write_values(fp, vals, actions[:])
|
disconnect = write_values(fp, vals, actions[:])
|
||||||
duration = time.time() - started
|
duration = time.time() - started
|
||||||
@ -105,18 +110,7 @@ def serve(msg, fp, settings, request_host=None):
|
|||||||
started = started,
|
started = started,
|
||||||
duration = duration,
|
duration = duration,
|
||||||
)
|
)
|
||||||
for i in msg.logattrs:
|
ret.update(msg.log(settings))
|
||||||
v = getattr(msg, i)
|
|
||||||
# Careful not to log any VALUE specs without sanitizing them first. We truncate at 1k.
|
|
||||||
if hasattr(v, "values"):
|
|
||||||
v = [x[:TRUNCATE] for x in v.values(settings)]
|
|
||||||
v = "".join(v).encode("string_escape")
|
|
||||||
elif hasattr(v, "__len__"):
|
|
||||||
v = v[:TRUNCATE]
|
|
||||||
v = v.encode("string_escape")
|
|
||||||
ret[i] = v
|
|
||||||
ret["spec"] = msg.spec()
|
|
||||||
ret.update(msg.logflags)
|
|
||||||
return ret
|
return ret
|
||||||
|
|
||||||
|
|
||||||
@ -228,7 +222,7 @@ class _Token(object):
|
|||||||
"""
|
"""
|
||||||
return None
|
return None
|
||||||
|
|
||||||
def resolve(self, msg): # pragma: no cover
|
def resolve(self, msg, settings, request_host): # pragma: no cover
|
||||||
"""
|
"""
|
||||||
Resolves this token to ready it for transmission. This means that
|
Resolves this token to ready it for transmission. This means that
|
||||||
the calculated offsets of actions are fixed.
|
the calculated offsets of actions are fixed.
|
||||||
@ -559,7 +553,7 @@ class _Action(_Token):
|
|||||||
def __init__(self, offset):
|
def __init__(self, offset):
|
||||||
self.offset = offset
|
self.offset = offset
|
||||||
|
|
||||||
def resolve_offset(self, msg, settings, request_host):
|
def resolve(self, msg, settings, request_host):
|
||||||
"""
|
"""
|
||||||
Resolves offset specifications to a numeric offset. Returns a copy
|
Resolves offset specifications to a numeric offset. Returns a copy
|
||||||
of the action object.
|
of the action object.
|
||||||
@ -713,11 +707,11 @@ class _Message(object):
|
|||||||
l += len(i.value.get_generator(settings))
|
l += len(i.value.get_generator(settings))
|
||||||
return l
|
return l
|
||||||
|
|
||||||
def headervals(self, settings, request_host):
|
def resolve(self, settings, request_host):
|
||||||
hdrs = self.headers[:]
|
tokens = self.tokens[:]
|
||||||
if not self.raw:
|
if not self.raw:
|
||||||
if self.body and not utils.get_header("Content-Length", self.headers):
|
if self.body and not utils.get_header("Content-Length", self.headers):
|
||||||
hdrs.append(
|
tokens.append(
|
||||||
Header(
|
Header(
|
||||||
ValueLiteral("Content-Length"),
|
ValueLiteral("Content-Length"),
|
||||||
ValueLiteral(str(len(self.body.value.get_generator(settings)))),
|
ValueLiteral(str(len(self.body.value.get_generator(settings)))),
|
||||||
@ -725,7 +719,7 @@ class _Message(object):
|
|||||||
)
|
)
|
||||||
if request_host:
|
if request_host:
|
||||||
if not utils.get_header("Host", self.headers):
|
if not utils.get_header("Host", self.headers):
|
||||||
hdrs.append(
|
tokens.append(
|
||||||
Header(
|
Header(
|
||||||
ValueLiteral("Host"),
|
ValueLiteral("Host"),
|
||||||
ValueLiteral(request_host)
|
ValueLiteral(request_host)
|
||||||
@ -733,23 +727,21 @@ class _Message(object):
|
|||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
if not utils.get_header("Date", self.headers):
|
if not utils.get_header("Date", self.headers):
|
||||||
hdrs.append(
|
tokens.append(
|
||||||
Header(
|
Header(
|
||||||
ValueLiteral("Date"),
|
ValueLiteral("Date"),
|
||||||
ValueLiteral(formatdate(timeval=None, localtime=False, usegmt=True))
|
ValueLiteral(formatdate(timeval=None, localtime=False, usegmt=True))
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
intermediate = self.__class__(tokens)
|
||||||
|
return self.__class__([i.resolve(intermediate, settings, request_host) for i in tokens])
|
||||||
|
|
||||||
|
def headervals(self, settings, request_host):
|
||||||
values = []
|
values = []
|
||||||
for h in hdrs:
|
for h in self.headers:
|
||||||
values.extend(h.values(settings))
|
values.extend(h.values(settings))
|
||||||
return values
|
return values
|
||||||
|
|
||||||
def ready_actions(self, settings, request_host):
|
|
||||||
actions = [i.resolve_offset(self, settings, request_host) for i in self.actions]
|
|
||||||
actions.sort()
|
|
||||||
actions.reverse()
|
|
||||||
return [i.intermediate(settings) for i in actions]
|
|
||||||
|
|
||||||
@abc.abstractmethod
|
@abc.abstractmethod
|
||||||
def preamble(self, settings): # pragma: no cover
|
def preamble(self, settings): # pragma: no cover
|
||||||
pass
|
pass
|
||||||
@ -758,6 +750,24 @@ class _Message(object):
|
|||||||
def expr(klass): # pragma: no cover
|
def expr(klass): # pragma: no cover
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
def log(self, settings):
|
||||||
|
"""
|
||||||
|
A dictionary that should be logged if this message is served.
|
||||||
|
"""
|
||||||
|
ret = {}
|
||||||
|
for i in self.logattrs:
|
||||||
|
v = getattr(self, i)
|
||||||
|
# Careful not to log any VALUE specs without sanitizing them first. We truncate at 1k.
|
||||||
|
if hasattr(v, "values"):
|
||||||
|
v = [x[:TRUNCATE] for x in v.values(settings)]
|
||||||
|
v = "".join(v).encode("string_escape")
|
||||||
|
elif hasattr(v, "__len__"):
|
||||||
|
v = v[:TRUNCATE]
|
||||||
|
v = v.encode("string_escape")
|
||||||
|
ret[i] = v
|
||||||
|
ret["spec"] = self.spec()
|
||||||
|
return ret
|
||||||
|
|
||||||
|
|
||||||
Sep = pp.Optional(pp.Literal(":")).suppress()
|
Sep = pp.Optional(pp.Literal(":")).suppress()
|
||||||
|
|
||||||
@ -774,7 +784,6 @@ class Response(_Message):
|
|||||||
Reason
|
Reason
|
||||||
)
|
)
|
||||||
logattrs = ["code", "reason", "version", "body"]
|
logattrs = ["code", "reason", "version", "body"]
|
||||||
logflags = dict()
|
|
||||||
@property
|
@property
|
||||||
def code(self):
|
def code(self):
|
||||||
return self._get_token(Code)
|
return self._get_token(Code)
|
||||||
@ -820,7 +829,6 @@ class Request(_Message):
|
|||||||
Raw
|
Raw
|
||||||
)
|
)
|
||||||
logattrs = ["method", "path", "body"]
|
logattrs = ["method", "path", "body"]
|
||||||
logflags = dict()
|
|
||||||
@property
|
@property
|
||||||
def method(self):
|
def method(self):
|
||||||
return self._get_token(Method)
|
return self._get_token(Method)
|
||||||
@ -855,16 +863,14 @@ class Request(_Message):
|
|||||||
return ":".join([i.spec() for i in self.tokens])
|
return ":".join([i.spec() for i in self.tokens])
|
||||||
|
|
||||||
|
|
||||||
class PathodErrorResponse(Response):
|
def PathodErrorResponse(reason, body=None):
|
||||||
logflags = dict(internal=True)
|
|
||||||
def __init__(self, reason, body=None):
|
|
||||||
tokens = [
|
tokens = [
|
||||||
Code("800"),
|
Code("800"),
|
||||||
Header(ValueLiteral("Content-Type"), ValueLiteral("text/plain")),
|
Header(ValueLiteral("Content-Type"), ValueLiteral("text/plain")),
|
||||||
Reason(ValueLiteral(reason)),
|
Reason(ValueLiteral(reason)),
|
||||||
Body(ValueLiteral("pathod error: " + (body or reason))),
|
Body(ValueLiteral("pathod error: " + (body or reason))),
|
||||||
]
|
]
|
||||||
Response.__init__(self, tokens)
|
return Response(tokens)
|
||||||
|
|
||||||
|
|
||||||
FILESTART = "+"
|
FILESTART = "+"
|
||||||
|
@ -257,10 +257,10 @@ class Test_Action:
|
|||||||
l.sort()
|
l.sort()
|
||||||
assert l[0].offset == 0
|
assert l[0].offset == 0
|
||||||
|
|
||||||
def test_resolve_offset(self):
|
def test_resolve(self):
|
||||||
r = language.parse_request({}, 'GET:"/foo"')
|
r = language.parse_request({}, 'GET:"/foo"')
|
||||||
e = language.DisconnectAt("r")
|
e = language.DisconnectAt("r")
|
||||||
ret = e.resolve_offset(r, {}, None)
|
ret = e.resolve(r, {}, None)
|
||||||
assert isinstance(ret.offset, int)
|
assert isinstance(ret.offset, int)
|
||||||
|
|
||||||
def test_repr(self):
|
def test_repr(self):
|
||||||
@ -584,9 +584,9 @@ class TestResponse:
|
|||||||
s = cStringIO.StringIO()
|
s = cStringIO.StringIO()
|
||||||
language.serve(x, s, {})
|
language.serve(x, s, {})
|
||||||
assert x.length({}, None) == len(s.getvalue())
|
assert x.length({}, None) == len(s.getvalue())
|
||||||
testlen(language.parse_response({}, "400:m'msg'"))
|
testlen(language.parse_response({}, "400:m'msg':r"))
|
||||||
testlen(language.parse_response({}, "400:m'msg':h'foo'='bar'"))
|
testlen(language.parse_response({}, "400:m'msg':h'foo'='bar':r"))
|
||||||
testlen(language.parse_response({}, "400:m'msg':h'foo'='bar':b@100b"))
|
testlen(language.parse_response({}, "400:m'msg':h'foo'='bar':b@100b:r"))
|
||||||
|
|
||||||
def test_maximum_length(self):
|
def test_maximum_length(self):
|
||||||
def testlen(x):
|
def testlen(x):
|
||||||
|
Loading…
Reference in New Issue
Block a user