mirror of
https://github.com/Grasscutters/mitmproxy.git
synced 2025-02-01 07:49:10 +00:00
More robust response handling.
This commit is contained in:
parent
86fe199988
commit
7a49cdfef3
@ -40,23 +40,23 @@ class Pathoc(tcp.TCPClient):
|
|||||||
r = rparse.parse_request({}, i)
|
r = rparse.parse_request({}, i)
|
||||||
req = r.serve(self.wfile)
|
req = r.serve(self.wfile)
|
||||||
if reqdump:
|
if reqdump:
|
||||||
print >> fp, ">>", req["method"], req["path"]
|
print >> fp, "\n>>", req["method"], req["path"]
|
||||||
for a in req["actions"]:
|
for a in req["actions"]:
|
||||||
print >> fp, "\t",
|
print >> fp, "\t",
|
||||||
for x in a:
|
for x in a:
|
||||||
print x,
|
print >> fp, x,
|
||||||
print
|
print >> fp
|
||||||
self.wfile.flush()
|
self.wfile.flush()
|
||||||
resp = self.request(i)
|
resp = http.read_response(self.rfile, r.method, None)
|
||||||
except rparse.ParseException, v:
|
except rparse.ParseException, v:
|
||||||
print >> fp, "Error parsing request spec: %s"%v.msg
|
print >> fp, "Error parsing request spec: %s"%v.msg
|
||||||
print >> fp, v.marked()
|
print >> fp, v.marked()
|
||||||
return
|
return
|
||||||
except http.HttpError, v:
|
except http.HttpError, v:
|
||||||
print >> fp, v.msg
|
print >> fp, "<<", v.msg
|
||||||
return
|
return
|
||||||
except tcp.NetLibTimeout:
|
except tcp.NetLibTimeout:
|
||||||
print >> fp, "Timeout"
|
print >> fp, "<<", "Timeout"
|
||||||
else:
|
else:
|
||||||
if respdump:
|
if respdump:
|
||||||
print_full(fp, *resp)
|
print_full(fp, *resp)
|
||||||
|
@ -18,6 +18,82 @@ class PathodHandler(tcp.BaseHandler):
|
|||||||
def handle_sni(self, connection):
|
def handle_sni(self, connection):
|
||||||
self.sni = connection.get_servername()
|
self.sni = connection.get_servername()
|
||||||
|
|
||||||
|
def handle_request(self):
|
||||||
|
"""
|
||||||
|
Returns True if handling should continue.
|
||||||
|
"""
|
||||||
|
line = self.rfile.readline()
|
||||||
|
if line == "\r\n" or line == "\n": # Possible leftover from previous message
|
||||||
|
line = self.rfile.readline()
|
||||||
|
if line == "":
|
||||||
|
return
|
||||||
|
|
||||||
|
parts = http.parse_init_http(line)
|
||||||
|
if not parts:
|
||||||
|
s = "Invalid first line: %s"%line.rstrip()
|
||||||
|
self.info(s)
|
||||||
|
self.server.add_log(
|
||||||
|
dict(
|
||||||
|
type = "error",
|
||||||
|
msg = s
|
||||||
|
)
|
||||||
|
)
|
||||||
|
return
|
||||||
|
method, path, httpversion = parts
|
||||||
|
|
||||||
|
headers = http.read_headers(self.rfile)
|
||||||
|
content = http.read_http_body_request(
|
||||||
|
self.rfile, self.wfile, headers, httpversion, None
|
||||||
|
)
|
||||||
|
|
||||||
|
crafted = None
|
||||||
|
for i in self.server.anchors:
|
||||||
|
if i[0].match(path):
|
||||||
|
crafted = i[1]
|
||||||
|
|
||||||
|
if not crafted and path.startswith(self.server.prefix):
|
||||||
|
spec = urllib.unquote(path)[len(self.server.prefix):]
|
||||||
|
try:
|
||||||
|
crafted = rparse.parse_response(self.server.request_settings, spec)
|
||||||
|
except rparse.ParseException, v:
|
||||||
|
crafted = rparse.InternalResponse(
|
||||||
|
800,
|
||||||
|
"Error parsing response spec: %s\n"%v.msg + v.marked()
|
||||||
|
)
|
||||||
|
|
||||||
|
request_log = dict(
|
||||||
|
path = path,
|
||||||
|
method = method,
|
||||||
|
headers = headers.lst,
|
||||||
|
sni = self.sni,
|
||||||
|
remote_address = self.client_address,
|
||||||
|
httpversion = httpversion,
|
||||||
|
)
|
||||||
|
if crafted:
|
||||||
|
response_log = crafted.serve(self.wfile)
|
||||||
|
if response_log["disconnect"]:
|
||||||
|
return
|
||||||
|
self.server.add_log(
|
||||||
|
dict(
|
||||||
|
type = "crafted",
|
||||||
|
request=request_log,
|
||||||
|
response=response_log
|
||||||
|
)
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
cc = wsgi.ClientConn(self.client_address)
|
||||||
|
req = wsgi.Request(cc, "http", method, path, headers, content)
|
||||||
|
sn = self.connection.getsockname()
|
||||||
|
app = wsgi.WSGIAdaptor(
|
||||||
|
self.server.app,
|
||||||
|
sn[0],
|
||||||
|
self.server.port,
|
||||||
|
version.NAMEVERSION
|
||||||
|
)
|
||||||
|
app.serve(req, self.wfile)
|
||||||
|
self.debug("%s %s"%(method, path))
|
||||||
|
return True
|
||||||
|
|
||||||
def handle(self):
|
def handle(self):
|
||||||
if self.server.ssloptions:
|
if self.server.ssloptions:
|
||||||
try:
|
try:
|
||||||
@ -34,79 +110,21 @@ class PathodHandler(tcp.BaseHandler):
|
|||||||
)
|
)
|
||||||
)
|
)
|
||||||
self.info(s)
|
self.info(s)
|
||||||
self.finish()
|
return
|
||||||
|
|
||||||
while not self.finished:
|
while not self.finished:
|
||||||
line = self.rfile.readline()
|
try:
|
||||||
if line == "\r\n" or line == "\n": # Possible leftover from previous message
|
if not self.handle_request():
|
||||||
line = self.rfile.readline()
|
return
|
||||||
if line == "":
|
except tcp.NetLibDisconnect:
|
||||||
return None
|
self.info("Disconnect")
|
||||||
|
|
||||||
parts = http.parse_init_http(line)
|
|
||||||
if not parts:
|
|
||||||
s = "Invalid first line: %s"%line.rstrip()
|
|
||||||
self.info(s)
|
|
||||||
self.server.add_log(
|
self.server.add_log(
|
||||||
dict(
|
dict(
|
||||||
type = "error",
|
type = "error",
|
||||||
msg = s
|
msg = "Disconnect"
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
return None
|
return
|
||||||
method, path, httpversion = parts
|
|
||||||
|
|
||||||
headers = http.read_headers(self.rfile)
|
|
||||||
content = http.read_http_body_request(
|
|
||||||
self.rfile, self.wfile, headers, httpversion, None
|
|
||||||
)
|
|
||||||
|
|
||||||
crafted = None
|
|
||||||
for i in self.server.anchors:
|
|
||||||
if i[0].match(path):
|
|
||||||
crafted = i[1]
|
|
||||||
|
|
||||||
if not crafted and path.startswith(self.server.prefix):
|
|
||||||
spec = urllib.unquote(path)[len(self.server.prefix):]
|
|
||||||
try:
|
|
||||||
crafted = rparse.parse_response(self.server.request_settings, spec)
|
|
||||||
except rparse.ParseException, v:
|
|
||||||
crafted = rparse.InternalResponse(
|
|
||||||
800,
|
|
||||||
"Error parsing response spec: %s\n"%v.msg + v.marked()
|
|
||||||
)
|
|
||||||
|
|
||||||
request_log = dict(
|
|
||||||
path = path,
|
|
||||||
method = method,
|
|
||||||
headers = headers.lst,
|
|
||||||
sni = self.sni,
|
|
||||||
remote_address = self.client_address,
|
|
||||||
httpversion = httpversion,
|
|
||||||
)
|
|
||||||
if crafted:
|
|
||||||
response_log = crafted.serve(self.wfile)
|
|
||||||
if response_log["disconnect"]:
|
|
||||||
self.finish()
|
|
||||||
self.server.add_log(
|
|
||||||
dict(
|
|
||||||
type = "crafted",
|
|
||||||
request=request_log,
|
|
||||||
response=response_log
|
|
||||||
)
|
|
||||||
)
|
|
||||||
else:
|
|
||||||
cc = wsgi.ClientConn(self.client_address)
|
|
||||||
req = wsgi.Request(cc, "http", method, path, headers, content)
|
|
||||||
sn = self.connection.getsockname()
|
|
||||||
app = wsgi.WSGIAdaptor(
|
|
||||||
self.server.app,
|
|
||||||
sn[0],
|
|
||||||
self.server.port,
|
|
||||||
version.NAMEVERSION
|
|
||||||
)
|
|
||||||
app.serve(req, self.wfile)
|
|
||||||
self.debug("%s %s"%(method, path))
|
|
||||||
|
|
||||||
|
|
||||||
class Pathod(tcp.TCPServer):
|
class Pathod(tcp.TCPServer):
|
||||||
|
@ -64,11 +64,13 @@ class _DaemonTests:
|
|||||||
scheme = "https" if self.SSL else "http"
|
scheme = "https" if self.SSL else "http"
|
||||||
return requests.get("%s://localhost:%s/p/%s"%(scheme, self.d.port, spec), verify=False)
|
return requests.get("%s://localhost:%s/p/%s"%(scheme, self.d.port, spec), verify=False)
|
||||||
|
|
||||||
def pathoc(self, spec):
|
def pathoc(self, spec, timeout=None):
|
||||||
c = pathoc.Pathoc("localhost", self.d.port)
|
c = pathoc.Pathoc("localhost", self.d.port)
|
||||||
c.connect()
|
c.connect()
|
||||||
if self.SSL:
|
if self.SSL:
|
||||||
c.convert_to_ssl()
|
c.convert_to_ssl()
|
||||||
|
if timeout:
|
||||||
|
c.settimeout(timeout)
|
||||||
return c.request(spec)
|
return c.request(spec)
|
||||||
|
|
||||||
def test_preline(self):
|
def test_preline(self):
|
||||||
@ -114,6 +116,7 @@ class _DaemonTests:
|
|||||||
assert "foo" in l["msg"]
|
assert "foo" in l["msg"]
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class TestDaemon(_DaemonTests):
|
class TestDaemon(_DaemonTests):
|
||||||
SSL = False
|
SSL = False
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user