mirror of
https://github.com/Grasscutters/mitmproxy.git
synced 2024-11-23 08:11:00 +00:00
Refactor pathod to allow switching protocol handlers
This commit is contained in:
parent
2a1a0e1ab2
commit
88ab54fab0
@ -5,7 +5,6 @@ import sys
|
|||||||
import threading
|
import threading
|
||||||
import urllib
|
import urllib
|
||||||
from netlib import tcp, http, wsgi, certutils, websockets
|
from netlib import tcp, http, wsgi, certutils, websockets
|
||||||
import netlib.utils
|
|
||||||
|
|
||||||
from . import version, app, language, utils, log
|
from . import version, app, language, utils, log
|
||||||
import language.http
|
import language.http
|
||||||
@ -25,15 +24,17 @@ class PathodError(Exception):
|
|||||||
|
|
||||||
|
|
||||||
class SSLOptions:
|
class SSLOptions:
|
||||||
def __init__(self,
|
def __init__(
|
||||||
confdir=CONFDIR,
|
self,
|
||||||
cn=None,
|
confdir=CONFDIR,
|
||||||
sans=(),
|
cn=None,
|
||||||
not_after_connect=None,
|
sans=(),
|
||||||
request_client_cert=False,
|
not_after_connect=None,
|
||||||
sslversion=tcp.SSLv23_METHOD,
|
request_client_cert=False,
|
||||||
ciphers=None,
|
sslversion=tcp.SSLv23_METHOD,
|
||||||
certs=None):
|
ciphers=None,
|
||||||
|
certs=None
|
||||||
|
):
|
||||||
self.confdir = confdir
|
self.confdir = confdir
|
||||||
self.cn = cn
|
self.cn = cn
|
||||||
self.certstore = certutils.CertStore.from_store(
|
self.certstore = certutils.CertStore.from_store(
|
||||||
@ -84,11 +85,12 @@ class PathodHandler(tcp.BaseHandler):
|
|||||||
type="error",
|
type="error",
|
||||||
msg = error
|
msg = error
|
||||||
)
|
)
|
||||||
return False, log
|
return None, log
|
||||||
|
|
||||||
if self.server.explain and not isinstance(
|
if self.server.explain and not isinstance(
|
||||||
crafted,
|
crafted,
|
||||||
language.http.PathodErrorResponse):
|
language.http.PathodErrorResponse
|
||||||
|
):
|
||||||
crafted = crafted.freeze(self.settings)
|
crafted = crafted.freeze(self.settings)
|
||||||
self.info(">> Spec: %s" % crafted.spec())
|
self.info(">> Spec: %s" % crafted.spec())
|
||||||
response_log = language.serve(
|
response_log = language.serve(
|
||||||
@ -97,14 +99,14 @@ class PathodHandler(tcp.BaseHandler):
|
|||||||
self.settings
|
self.settings
|
||||||
)
|
)
|
||||||
if response_log["disconnect"]:
|
if response_log["disconnect"]:
|
||||||
return False, response_log
|
return None, response_log
|
||||||
return True, response_log
|
return self.handle_http_request, response_log
|
||||||
|
|
||||||
def handle_request(self):
|
def handle_http_request(self):
|
||||||
"""
|
"""
|
||||||
Returns a (again, log) tuple.
|
Returns a (handler, log) tuple.
|
||||||
|
|
||||||
again: True if request handling should continue.
|
handler: Handler for the next request, or None to disconnect
|
||||||
log: A dictionary, or None
|
log: A dictionary, or None
|
||||||
"""
|
"""
|
||||||
lr = self.rfile if self.server.logreq else None
|
lr = self.rfile if self.server.logreq else None
|
||||||
@ -113,7 +115,7 @@ class PathodHandler(tcp.BaseHandler):
|
|||||||
line = http.get_request_line(self.rfile)
|
line = http.get_request_line(self.rfile)
|
||||||
if not line:
|
if not line:
|
||||||
# Normal termination
|
# Normal termination
|
||||||
return False
|
return None
|
||||||
|
|
||||||
m = utils.MemBool()
|
m = utils.MemBool()
|
||||||
if m(http.parse_init_connect(line)):
|
if m(http.parse_init_connect(line)):
|
||||||
@ -141,8 +143,8 @@ class PathodHandler(tcp.BaseHandler):
|
|||||||
s = str(v)
|
s = str(v)
|
||||||
lg(s)
|
lg(s)
|
||||||
self.addlog(dict(type="error", msg=s))
|
self.addlog(dict(type="error", msg=s))
|
||||||
return False
|
return None
|
||||||
return True
|
return self.handle_http_request
|
||||||
elif m(http.parse_init_proxy(line)):
|
elif m(http.parse_init_proxy(line)):
|
||||||
method, _, _, _, path, httpversion = m.v
|
method, _, _, _, path, httpversion = m.v
|
||||||
elif m(http.parse_init_http(line)):
|
elif m(http.parse_init_http(line)):
|
||||||
@ -151,14 +153,14 @@ class PathodHandler(tcp.BaseHandler):
|
|||||||
s = "Invalid first line: %s" % repr(line)
|
s = "Invalid first line: %s" % repr(line)
|
||||||
lg(s)
|
lg(s)
|
||||||
self.addlog(dict(type="error", msg=s))
|
self.addlog(dict(type="error", msg=s))
|
||||||
return False
|
return None
|
||||||
|
|
||||||
headers = http.read_headers(self.rfile)
|
headers = http.read_headers(self.rfile)
|
||||||
if headers is None:
|
if headers is None:
|
||||||
s = "Invalid headers"
|
s = "Invalid headers"
|
||||||
lg(s)
|
lg(s)
|
||||||
self.addlog(dict(type="error", msg=s))
|
self.addlog(dict(type="error", msg=s))
|
||||||
return False
|
return None
|
||||||
|
|
||||||
clientcert = None
|
clientcert = None
|
||||||
if self.clientcert:
|
if self.clientcert:
|
||||||
@ -196,14 +198,14 @@ class PathodHandler(tcp.BaseHandler):
|
|||||||
s = str(s)
|
s = str(s)
|
||||||
lg(s)
|
lg(s)
|
||||||
self.addlog(dict(type="error", msg=s))
|
self.addlog(dict(type="error", msg=s))
|
||||||
return False
|
return None
|
||||||
|
|
||||||
for i in self.server.anchors:
|
for i in self.server.anchors:
|
||||||
if i[0].match(path):
|
if i[0].match(path):
|
||||||
lg("crafting anchor: %s" % path)
|
lg("crafting anchor: %s" % path)
|
||||||
again, retlog["response"] = self.serve_crafted(i[1])
|
nexthandler, retlog["response"] = self.serve_crafted(i[1])
|
||||||
self.addlog(retlog)
|
self.addlog(retlog)
|
||||||
return again
|
return nexthandler
|
||||||
|
|
||||||
if not self.server.nocraft and utils.matchpath(
|
if not self.server.nocraft and utils.matchpath(
|
||||||
path,
|
path,
|
||||||
@ -222,9 +224,9 @@ class PathodHandler(tcp.BaseHandler):
|
|||||||
"Parse Error",
|
"Parse Error",
|
||||||
"Error parsing response spec: %s\n" % v.msg + v.marked()
|
"Error parsing response spec: %s\n" % v.msg + v.marked()
|
||||||
)
|
)
|
||||||
again, retlog["response"] = self.serve_crafted(crafted)
|
nexthandler, retlog["response"] = self.serve_crafted(crafted)
|
||||||
self.addlog(retlog)
|
self.addlog(retlog)
|
||||||
return again
|
return nexthandler
|
||||||
elif self.server.noweb:
|
elif self.server.noweb:
|
||||||
crafted = language.http.make_error_response("Access Denied")
|
crafted = language.http.make_error_response("Access Denied")
|
||||||
language.serve(crafted, self.wfile, self.settings)
|
language.serve(crafted, self.wfile, self.settings)
|
||||||
@ -232,7 +234,7 @@ class PathodHandler(tcp.BaseHandler):
|
|||||||
type="error",
|
type="error",
|
||||||
msg="Access denied: web interface disabled"
|
msg="Access denied: web interface disabled"
|
||||||
))
|
))
|
||||||
return False
|
return None
|
||||||
else:
|
else:
|
||||||
lg("app: %s %s" % (method, path))
|
lg("app: %s %s" % (method, path))
|
||||||
req = wsgi.Request("http", method, path, headers, content)
|
req = wsgi.Request("http", method, path, headers, content)
|
||||||
@ -245,7 +247,7 @@ class PathodHandler(tcp.BaseHandler):
|
|||||||
version.NAMEVERSION
|
version.NAMEVERSION
|
||||||
)
|
)
|
||||||
a.serve(flow, self.wfile)
|
a.serve(flow, self.wfile)
|
||||||
return True
|
return self.handle_http_request
|
||||||
|
|
||||||
def addlog(self, log):
|
def addlog(self, log):
|
||||||
# FIXME: The bytes in the log should not be escaped. We do this at the
|
# FIXME: The bytes in the log should not be escaped. We do this at the
|
||||||
@ -282,9 +284,10 @@ class PathodHandler(tcp.BaseHandler):
|
|||||||
self.info(s)
|
self.info(s)
|
||||||
return
|
return
|
||||||
self.settimeout(self.server.timeout)
|
self.settimeout(self.server.timeout)
|
||||||
|
handler = self.handle_http_request
|
||||||
while not self.finished:
|
while not self.finished:
|
||||||
again = self.handle_request()
|
handler = handler()
|
||||||
if not again:
|
if not handler:
|
||||||
return
|
return
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user