mirror of
https://github.com/Grasscutters/mitmproxy.git
synced 2025-02-01 15:55:28 +00:00
fix bugs, make https work
This commit is contained in:
parent
0dd243c5e4
commit
2a15479cdb
@ -4,7 +4,7 @@ from .. import version
|
||||
from ..exceptions import InvalidCredentials, HttpException, ProtocolException
|
||||
from .layer import Layer, ServerConnectionMixin
|
||||
from libmproxy import utils
|
||||
from .messages import ChangeServer, Connect, Reconnect, Kill
|
||||
from .messages import SetServer, Connect, Reconnect, Kill
|
||||
from libmproxy.protocol import KILL
|
||||
|
||||
from libmproxy.protocol.http import HTTPFlow
|
||||
@ -71,19 +71,9 @@ class HttpLayer(Layer):
|
||||
HTTP 1 Layer
|
||||
"""
|
||||
|
||||
def __init__(self, ctx):
|
||||
def __init__(self, ctx, mode):
|
||||
super(HttpLayer, self).__init__(ctx)
|
||||
|
||||
# FIXME: Imports
|
||||
from .http_proxy import HttpProxy, HttpUpstreamProxy
|
||||
|
||||
if any(isinstance(l, HttpProxy) for l in self.layers):
|
||||
self.mode = "regular"
|
||||
elif any(isinstance(l, HttpUpstreamProxy) for l in self.layers):
|
||||
self.mode = "upstream"
|
||||
else:
|
||||
# also includes socks or reverse mode, which are handled similarly on this layer.
|
||||
self.mode = "transparent"
|
||||
self.mode = mode
|
||||
|
||||
def __call__(self):
|
||||
while True:
|
||||
@ -104,7 +94,7 @@ class HttpLayer(Layer):
|
||||
|
||||
# Regular Proxy Mode: Handle CONNECT
|
||||
if self.mode == "regular" and request.form_in == "authority":
|
||||
self.server_address = (request.host, request.port)
|
||||
yield SetServer((request.host, request.port), False, None)
|
||||
self.send_to_client(make_connect_response(request.httpversion))
|
||||
layer = self.ctx.next_layer(self)
|
||||
for message in layer():
|
||||
@ -255,7 +245,7 @@ class HttpLayer(Layer):
|
||||
else:
|
||||
flow.request.host = self.ctx.server_address.host
|
||||
flow.request.port = self.ctx.server_address.port
|
||||
flow.request.scheme = self.server_conn.tls_established
|
||||
flow.request.scheme = "https" if self.server_conn.tls_established else "http"
|
||||
|
||||
# TODO: Expose ChangeServer functionality to inline scripts somehow? (yield_from_callback?)
|
||||
request_reply = self.channel.ask("request", flow)
|
||||
@ -271,8 +261,8 @@ class HttpLayer(Layer):
|
||||
tls = (flow.request.scheme == "https")
|
||||
if self.mode == "regular" or self.mode == "transparent":
|
||||
# If there's an existing connection that doesn't match our expectations, kill it.
|
||||
if self.server_address != address or tls != self.server_address.ssl_established:
|
||||
yield ChangeServer(address, tls, address.host)
|
||||
if self.server_address != address or tls != self.server_conn.ssl_established:
|
||||
yield SetServer(address, tls, address.host)
|
||||
# Establish connection is neccessary.
|
||||
if not self.server_conn:
|
||||
yield Connect()
|
||||
|
@ -6,7 +6,7 @@ from .http import HttpLayer
|
||||
|
||||
class HttpProxy(Layer, ServerConnectionMixin):
|
||||
def __call__(self):
|
||||
layer = HttpLayer(self)
|
||||
layer = HttpLayer(self, "regular")
|
||||
for message in layer():
|
||||
if not self._handle_server_message(message):
|
||||
yield message
|
||||
@ -18,7 +18,7 @@ class HttpUpstreamProxy(Layer, ServerConnectionMixin):
|
||||
self.server_address = server_address
|
||||
|
||||
def __call__(self):
|
||||
layer = HttpLayer(self)
|
||||
layer = HttpLayer(self, "upstream")
|
||||
for message in layer():
|
||||
if not self._handle_server_message(message):
|
||||
yield message
|
||||
|
@ -35,7 +35,7 @@ import threading
|
||||
from netlib import tcp
|
||||
from ..proxy import Log
|
||||
from ..proxy.connection import ServerConnection
|
||||
from .messages import Connect, Reconnect, ChangeServer, Kill
|
||||
from .messages import Connect, Reconnect, SetServer, Kill
|
||||
from ..exceptions import ProtocolException
|
||||
|
||||
|
||||
@ -116,7 +116,7 @@ class ServerConnectionMixin(object):
|
||||
elif message == Connect:
|
||||
self._connect()
|
||||
return True
|
||||
elif message == ChangeServer and message.depth == 1:
|
||||
elif message == SetServer and message.depth == 1:
|
||||
if self.server_conn:
|
||||
self._disconnect()
|
||||
self.server_address = message.address
|
||||
|
@ -27,7 +27,7 @@ class Reconnect(_Message):
|
||||
"""
|
||||
|
||||
|
||||
class ChangeServer(_Message):
|
||||
class SetServer(_Message):
|
||||
"""
|
||||
Change the upstream server.
|
||||
"""
|
||||
|
@ -2,7 +2,7 @@ from __future__ import (absolute_import, print_function, division)
|
||||
|
||||
from .rawtcp import RawTcpLayer
|
||||
from .tls import TlsLayer
|
||||
|
||||
from .http import HttpLayer
|
||||
|
||||
class RootContext(object):
|
||||
"""
|
||||
@ -38,10 +38,12 @@ class RootContext(object):
|
||||
return
|
||||
|
||||
if is_tls_client_hello:
|
||||
layer = TlsLayer(top_layer, True, True)
|
||||
return TlsLayer(top_layer, True, True)
|
||||
elif isinstance(top_layer, TlsLayer) and isinstance(top_layer.ctx, HttpLayer):
|
||||
return HttpLayer(top_layer, "transparent")
|
||||
else:
|
||||
layer = RawTcpLayer(top_layer)
|
||||
return layer
|
||||
return RawTcpLayer(top_layer)
|
||||
|
||||
|
||||
@property
|
||||
def layers(self):
|
||||
|
@ -5,7 +5,7 @@ from netlib import tcp
|
||||
|
||||
from ..exceptions import ProtocolException
|
||||
from .layer import Layer, yield_from_callback
|
||||
from .messages import Connect, Reconnect, ChangeServer
|
||||
from .messages import Connect, Reconnect, SetServer
|
||||
|
||||
|
||||
class TlsLayer(Layer):
|
||||
@ -13,7 +13,6 @@ class TlsLayer(Layer):
|
||||
super(TlsLayer, self).__init__(ctx)
|
||||
self._client_tls = client_tls
|
||||
self._server_tls = server_tls
|
||||
self._connected = False
|
||||
self.client_sni = None
|
||||
self._sni_from_server_change = None
|
||||
|
||||
@ -44,9 +43,6 @@ class TlsLayer(Layer):
|
||||
client_tls_requires_server_cert = (
|
||||
self._client_tls and self._server_tls and not self.config.no_upstream_cert
|
||||
)
|
||||
lazy_server_tls = (
|
||||
self._server_tls and not client_tls_requires_server_cert
|
||||
)
|
||||
|
||||
if client_tls_requires_server_cert:
|
||||
for m in self._establish_tls_with_client_and_server():
|
||||
@ -56,18 +52,27 @@ class TlsLayer(Layer):
|
||||
yield m
|
||||
|
||||
layer = self.ctx.next_layer(self)
|
||||
|
||||
for message in layer():
|
||||
if message != Connect or not self._connected:
|
||||
self.log("TlsLayer: %s" % message,"debug")
|
||||
if not (message == Connect and self._connected):
|
||||
yield message
|
||||
if message == Connect:
|
||||
if lazy_server_tls:
|
||||
|
||||
if message == Connect or message == Reconnect:
|
||||
if self._server_tls and not self._server_tls_established:
|
||||
self._establish_tls_with_server()
|
||||
if message == ChangeServer and message.depth == 1:
|
||||
self._server_tls = message.server_tls
|
||||
if message == SetServer and message.depth == 1:
|
||||
if message.server_tls is not None:
|
||||
self._sni_from_server_change = message.sni
|
||||
if message == Reconnect or message == ChangeServer:
|
||||
if self._server_tls:
|
||||
self._establish_tls_with_server()
|
||||
self._server_tls = message.server_tls
|
||||
|
||||
@property
|
||||
def _server_tls_established(self):
|
||||
return self.server_conn and self.server_conn.tls_established
|
||||
|
||||
@property
|
||||
def _connected(self):
|
||||
return bool(self.server_conn)
|
||||
|
||||
@property
|
||||
def sni_for_upstream_connection(self):
|
||||
@ -83,7 +88,6 @@ class TlsLayer(Layer):
|
||||
|
||||
# First, try to connect to the server.
|
||||
yield Connect()
|
||||
self._connected = True
|
||||
server_err = None
|
||||
try:
|
||||
self._establish_tls_with_server()
|
||||
|
Loading…
Reference in New Issue
Block a user