mirror of
https://github.com/Grasscutters/mitmproxy.git
synced 2025-02-07 10:40:09 +00:00
improve error handling
This commit is contained in:
parent
1a41c15c03
commit
1e4e332ef9
@ -22,7 +22,7 @@ def get_line(fp):
|
||||
if line == "\r\n" or line == "\n": # Possible leftover from previous message
|
||||
line = fp.readline()
|
||||
if line == "":
|
||||
raise tcp.NetLibDisconnect
|
||||
raise tcp.NetLibDisconnect()
|
||||
return line
|
||||
|
||||
|
||||
@ -927,7 +927,7 @@ class HTTPHandler(ProtocolHandler):
|
||||
body_size_limit=self.c.config.body_size_limit, include_body=include_body)
|
||||
return res
|
||||
except (tcp.NetLibDisconnect, http.HttpErrorConnClosed), v:
|
||||
self.c.log("error in server communication: %s" % str(v), level="debug")
|
||||
self.c.log("error in server communication: %s" % repr(v), level="debug")
|
||||
if i < 1:
|
||||
# In any case, we try to reconnect at least once.
|
||||
# This is necessary because it might be possible that we already initiated an upstream connection
|
||||
@ -1064,23 +1064,23 @@ class HTTPHandler(ProtocolHandler):
|
||||
def handle_error(self, error, flow=None):
|
||||
|
||||
message = repr(error)
|
||||
code = getattr(error, "code", 502)
|
||||
headers = getattr(error, "headers", None)
|
||||
|
||||
if "tlsv1 alert unknown ca" in message:
|
||||
message = message + " \nThe client does not trust the proxy's certificate."
|
||||
message += " The client does not trust the proxy's certificate."
|
||||
|
||||
if isinstance(error, tcp.NetLibDisconnect):
|
||||
self.c.log("TCP connection closed unexpectedly.", "debug", [repr(error)])
|
||||
else:
|
||||
self.c.log("error: %s" % message, level="info")
|
||||
|
||||
if flow:
|
||||
flow.error = Error(message)
|
||||
# FIXME: no flows without request or with both request and response at the moment.
|
||||
# TODO: no flows without request or with both request and response at the moment.
|
||||
if flow.request and not flow.response:
|
||||
flow.error = Error(message)
|
||||
self.c.channel.ask("error", flow.error)
|
||||
else:
|
||||
pass
|
||||
|
||||
try:
|
||||
code = getattr(error, "code", 502)
|
||||
headers = getattr(error, "headers", None)
|
||||
self.send_error(code, message, headers)
|
||||
except:
|
||||
pass
|
||||
|
@ -16,8 +16,9 @@ class TCPHandler(ProtocolHandler):
|
||||
|
||||
server = "%s:%s" % self.c.server_conn.address()[:2]
|
||||
buf = memoryview(bytearray(self.chunk_size))
|
||||
|
||||
conns = [self.c.client_conn.rfile, self.c.server_conn.rfile]
|
||||
|
||||
try:
|
||||
while True:
|
||||
r, _, _ = select.select(conns, [], [], 10)
|
||||
for rfile in r:
|
||||
@ -58,9 +59,12 @@ class TCPHandler(ProtocolHandler):
|
||||
# if one of the peers is over SSL, we need to send bytes/strings
|
||||
if not src.ssl_established: # only ssl to dst, i.e. we revc'd into buf but need bytes/string now.
|
||||
contents = buf[:size].tobytes()
|
||||
self.c.log("%s %s\r\n%s" % (direction, dst_str, cleanBin(contents)), "debug")
|
||||
# self.c.log("%s %s\r\n%s" % (direction, dst_str, cleanBin(contents)), "debug")
|
||||
dst.connection.send(contents)
|
||||
else:
|
||||
# socket.socket.send supports raw bytearrays/memoryviews
|
||||
self.c.log("%s %s\r\n%s" % (direction, dst_str, cleanBin(buf.tobytes())), "debug")
|
||||
# self.c.log("%s %s\r\n%s" % (direction, dst_str, cleanBin(buf.tobytes())), "debug")
|
||||
dst.connection.send(buf[:size])
|
||||
except socket.error as e:
|
||||
self.c.log("TCP connection closed unexpectedly.", "debug", [repr(e)])
|
||||
return
|
@ -3,7 +3,6 @@ import copy
|
||||
import os
|
||||
from netlib import tcp, certutils
|
||||
from .. import stateobject, utils
|
||||
from .primitives import ProxyError
|
||||
|
||||
|
||||
class ClientConnection(tcp.BaseHandler, stateobject.SimpleStateObject):
|
||||
@ -156,11 +155,8 @@ class ServerConnection(tcp.TCPClient, stateobject.SimpleStateObject):
|
||||
path = os.path.join(clientcerts, self.address.host.encode("idna")) + ".pem"
|
||||
if os.path.exists(path):
|
||||
clientcert = path
|
||||
try:
|
||||
self.convert_to_ssl(cert=clientcert, sni=sni)
|
||||
self.timestamp_ssl_setup = utils.timestamp()
|
||||
except tcp.NetLibError, v:
|
||||
raise ProxyError(400, repr(v))
|
||||
|
||||
def finish(self):
|
||||
tcp.TCPClient.finish(self)
|
||||
|
@ -95,7 +95,7 @@ class ConnectionHandler:
|
||||
# Delegate handling to the protocol handler
|
||||
protocol_handler(self.conntype)(self).handle_messages()
|
||||
|
||||
except (ProxyError, tcp.NetLibError), e:
|
||||
except ProxyError as e:
|
||||
protocol_handler(self.conntype)(self).handle_error(e)
|
||||
except Exception:
|
||||
import traceback, sys
|
||||
@ -190,11 +190,15 @@ class ConnectionHandler:
|
||||
raise ProxyError(502, "No server connection.")
|
||||
if self.server_conn.ssl_established:
|
||||
raise ProxyError(502, "SSL to Server already established.")
|
||||
try:
|
||||
self.server_conn.establish_ssl(self.config.clientcerts, self.sni)
|
||||
except tcp.NetLibError as v:
|
||||
raise ProxyError(502, repr(v))
|
||||
if client:
|
||||
if self.client_conn.ssl_established:
|
||||
raise ProxyError(502, "SSL to Client already established.")
|
||||
cert, key = self.find_cert()
|
||||
try:
|
||||
self.client_conn.convert_to_ssl(
|
||||
cert, key,
|
||||
handle_sni=self.handle_sni,
|
||||
@ -202,6 +206,8 @@ class ConnectionHandler:
|
||||
dhparams=self.config.certstore.dhparams,
|
||||
ca_file=self.config.ca_file
|
||||
)
|
||||
except tcp.NetLibError as v:
|
||||
raise ProxyError(400, repr(v))
|
||||
|
||||
def server_reconnect(self):
|
||||
address = self.server_conn.address
|
||||
|
@ -179,7 +179,7 @@ class TestHTTPConnectSSLError(tservers.HTTPProxTest):
|
||||
p = self.pathoc_raw()
|
||||
dst = ("localhost", self.proxy.port)
|
||||
p.connect(connect_to=dst)
|
||||
tutils.raises("400 - Bad Request", p.http_connect, dst)
|
||||
tutils.raises("502 - Bad Gateway", p.http_connect, dst)
|
||||
|
||||
|
||||
class TestHTTPS(tservers.HTTPProxTest, CommonMixin):
|
||||
@ -244,7 +244,7 @@ class TestTransparentSSL(tservers.TransparentProxTest, CommonMixin):
|
||||
p = pathoc.Pathoc(("localhost", self.proxy.port))
|
||||
p.connect()
|
||||
r = p.request("get:/")
|
||||
assert r.status_code == 502
|
||||
assert r.status_code == 400
|
||||
|
||||
|
||||
class TestProxy(tservers.HTTPProxTest):
|
||||
|
Loading…
Reference in New Issue
Block a user