code formatting: fix whitespace issues

This commit is contained in:
Thomas Kriechbaumer 2016-01-27 10:12:18 +01:00
parent c2bb29f669
commit 8c37538314
75 changed files with 249 additions and 63 deletions

View File

@ -372,10 +372,10 @@ def proxy_options(parser):
rawtcp = group.add_mutually_exclusive_group()
rawtcp.add_argument("--raw-tcp", action="store_true", dest="rawtcp")
rawtcp.add_argument("--no-raw-tcp", action="store_false", dest="rawtcp",
help="Explicitly enable/disable experimental raw tcp support. "
"Disabled by default. "
"Default value will change in a future version."
)
help="Explicitly enable/disable experimental raw tcp support. "
"Disabled by default. "
"Default value will change in a future version."
)
def proxy_ssl_options(parser):

View File

@ -22,6 +22,7 @@ EVENTLOG_SIZE = 500
class ConsoleState(flow.State):
def __init__(self):
flow.State.__init__(self)
self.focus = None
@ -732,4 +733,4 @@ class ConsoleMaster(flow.FlowMaster):
if super(ConsoleMaster, self).handle_script_change(script):
signals.status_message.send(message='"{}" reloaded.'.format(script.filename))
else:
signals.status_message.send(message='Error reloading "{}".'.format(script.filename))
signals.status_message.send(message='Error reloading "{}".'.format(script.filename))

View File

@ -242,7 +242,7 @@ def ask_save_path(prompt, data):
signals.status_prompt_path.send(
prompt = prompt,
callback = ask_save_overwrite,
args = (data, )
args = (data, )
)
@ -290,16 +290,16 @@ def copy_as_curl_command(flow):
data = "curl "
for k, v in flow.request.headers.fields:
data += "-H '%s:%s' " % (k, v)
data += "-H '%s:%s' " % (k, v)
if flow.request.method != "GET":
data += "-X %s " % flow.request.method
data += "-X %s " % flow.request.method
full_url = flow.request.scheme + "://" + flow.request.host + flow.request.path
data += "'%s'" % full_url
if flow.request.content:
data += " --data-binary '%s'" % flow.request.content
data += " --data-binary '%s'" % flow.request.content
copy_to_clipboard_or_prompt(data)
@ -316,7 +316,7 @@ def copy_as_python_code(flow):
headers = "\n"
for k, v in flow.request.headers.fields:
headers += " '%s': '%s',\n" % (k, v)
headers += " '%s': '%s',\n" % (k, v)
full_url = flow.request.scheme + "://" + flow.request.host + flow.request.path
@ -439,7 +439,7 @@ flowcache = utils.LRUCache(800)
def format_flow(f, focus, extended=False, hostheader=False, padding=2,
marked=False):
marked=False):
d = dict(
intercepted = f.intercepted,
acked = f.reply.acked,

View File

@ -43,6 +43,7 @@ footer = [
class EventListBox(urwid.ListBox):
def __init__(self, master):
self.master = master
urwid.ListBox.__init__(self, master.eventlist)
@ -60,6 +61,7 @@ class EventListBox(urwid.ListBox):
class BodyPile(urwid.Pile):
def __init__(self, master):
h = urwid.Text("Event log")
h = urwid.Padding(h, align="left", width=("relative", 100))
@ -103,6 +105,7 @@ class BodyPile(urwid.Pile):
class ConnectionItem(urwid.WidgetWrap):
def __init__(self, master, state, flow, focus):
self.master, self.state, self.flow = master, state, flow
self.f = focus
@ -273,6 +276,7 @@ class ConnectionItem(urwid.WidgetWrap):
class FlowListWalker(urwid.ListWalker):
def __init__(self, master, state):
self.master, self.state = master, state
signals.flowlist_change.connect(self.sig_flowlist_change)
@ -301,6 +305,7 @@ class FlowListWalker(urwid.ListWalker):
class FlowListBox(urwid.ListBox):
def __init__(self, master):
self.master = master
urwid.ListBox.__init__(

View File

@ -96,6 +96,7 @@ footer = [
class FlowViewHeader(urwid.WidgetWrap):
def __init__(self, master, f):
self.master, self.flow = master, f
self._w = common.format_flow(
@ -218,7 +219,7 @@ class FlowView(tabs.Tabs):
txt = []
for (style, text) in line:
if total_chars + len(text) > max_chars:
text = text[:max_chars-total_chars]
text = text[:max_chars - total_chars]
txt.append((style, text))
total_chars += len(text)
if total_chars == max_chars:

View File

@ -63,6 +63,7 @@ class TextColumn:
class SubgridColumn:
def __init__(self, heading, subeditor):
self.heading = heading
self.subeditor = subeditor
@ -97,6 +98,7 @@ class SubgridColumn:
class SEscaped(urwid.WidgetWrap):
def __init__(self, txt):
txt = txt.encode("string-escape")
w = urwid.Text(txt, wrap="any")
@ -113,6 +115,7 @@ class SEscaped(urwid.WidgetWrap):
class SEdit(urwid.WidgetWrap):
def __init__(self, txt):
txt = txt.encode("string-escape")
w = urwid.Edit(edit_text=txt, wrap="any", multiline=True)
@ -127,6 +130,7 @@ class SEdit(urwid.WidgetWrap):
class GridRow(urwid.WidgetWrap):
def __init__(self, focused, editing, editor, values):
self.focused, self.editing, self.editor = focused, editing, editor
@ -172,6 +176,7 @@ class GridRow(urwid.WidgetWrap):
class GridWalker(urwid.ListWalker):
"""
Stores rows as a list of (rows, errors) tuples, where rows is a list
and errors is a set with an entry of each offset in rows that is an
@ -311,6 +316,7 @@ class GridWalker(urwid.ListWalker):
class GridListBox(urwid.ListBox):
def __init__(self, lw):
urwid.ListBox.__init__(self, lw)

View File

@ -12,6 +12,7 @@ footer = [
class HelpView(urwid.ListBox):
def __init__(self, help_context):
self.help_context = help_context or []
urwid.ListBox.__init__(

View File

@ -22,6 +22,7 @@ help_context = _mkhelp()
class Options(urwid.WidgetWrap):
def __init__(self, master):
self.master = master
self.lb = select.Select(

View File

@ -18,6 +18,7 @@ help_context = _mkhelp()
class PalettePicker(urwid.WidgetWrap):
def __init__(self, master):
self.master = master
low, high = [], []

View File

@ -65,6 +65,7 @@ class Palette:
class LowDark(Palette):
"""
Low-color dark background
"""
@ -129,6 +130,7 @@ class Dark(LowDark):
class LowLight(Palette):
"""
Low-color light background
"""

View File

@ -5,6 +5,7 @@ import urwid
class _PathCompleter:
def __init__(self, _testing=False):
"""
_testing: disables reloading of the lookup table to make testing
@ -55,6 +56,7 @@ class _PathCompleter:
class PathEdit(urwid.Edit, _PathCompleter):
def __init__(self, *args, **kwargs):
urwid.Edit.__init__(self, *args, **kwargs)
_PathCompleter.__init__(self)

View File

@ -4,6 +4,7 @@ from . import signals
class Highlight(urwid.AttrMap):
def __init__(self, t):
urwid.AttrMap.__init__(
self,
@ -14,6 +15,7 @@ class Highlight(urwid.AttrMap):
class Searchable(urwid.ListBox):
def __init__(self, state, contents):
self.walker = urwid.SimpleFocusListWalker(contents)
urwid.ListBox.__init__(self, self.walker)

View File

@ -4,6 +4,7 @@ from . import common
class _OptionWidget(urwid.WidgetWrap):
def __init__(self, option, text, shortcut, active, focus):
self.option = option
textattr = "text"
@ -36,6 +37,7 @@ class _OptionWidget(urwid.WidgetWrap):
class OptionWalker(urwid.ListWalker):
def __init__(self, options):
urwid.ListWalker.__init__(self)
self.options = options
@ -59,6 +61,7 @@ class OptionWalker(urwid.ListWalker):
class Heading:
def __init__(self, text):
self.text = text
@ -73,6 +76,7 @@ _neg = lambda: False
class Option:
def __init__(self, text, shortcut, getstate=None, activate=None):
self.text = text
self.shortcut = shortcut
@ -89,6 +93,7 @@ class Option:
class Select(urwid.ListBox):
def __init__(self, options):
self.walker = OptionWalker(options)
urwid.ListBox.__init__(

View File

@ -2,6 +2,8 @@ import blinker
# Show a status message in the action bar
sig_add_event = blinker.Signal()
def add_event(e, level):
sig_add_event.send(
None,

View File

@ -7,6 +7,7 @@ from . import pathedit, signals, common
class ActionBar(urwid.WidgetWrap):
def __init__(self):
urwid.WidgetWrap.__init__(self, None)
self.clear()
@ -108,6 +109,7 @@ class ActionBar(urwid.WidgetWrap):
class StatusBar(urwid.WidgetWrap):
def __init__(self, master, helptext):
self.master, self.helptext = master, helptext
self.ab = ActionBar()

View File

@ -2,6 +2,7 @@ import urwid
class Tab(urwid.WidgetWrap):
def __init__(self, offset, content, attr, onclick):
"""
onclick is called on click with the tab offset as argument
@ -20,6 +21,7 @@ class Tab(urwid.WidgetWrap):
class Tabs(urwid.WidgetWrap):
def __init__(self, tabs, tab_offset=0):
urwid.WidgetWrap.__init__(self, "")
self.tab_offset = tab_offset

View File

@ -3,6 +3,7 @@ from . import signals
class Window(urwid.Frame):
def __init__(self, master, body, header, footer, helpctx):
urwid.Frame.__init__(
self,

View File

@ -275,6 +275,7 @@ class ViewMultipart(View):
if pyamf:
class DummyObject(dict):
def __init__(self, alias):
dict.__init__(self)
@ -282,7 +283,6 @@ if pyamf:
data = input.readObject()
self["data"] = data
def pyamf_class_loader(s):
for i in pyamf.CLASS_LOADERS:
if i != pyamf_class_loader:
@ -291,10 +291,8 @@ if pyamf:
return v
return DummyObject
pyamf.register_class_loader(pyamf_class_loader)
class ViewAMF(View):
name = "AMF"
prompt = ("amf", "f")
@ -417,6 +415,7 @@ class ViewImage(View):
class ViewProtobuf(View):
"""Human friendly view of protocol buffers
The view uses the protoc compiler to decode the binary
"""

View File

@ -4,6 +4,7 @@ import threading
class DummyReply:
"""
A reply object that does nothing. Useful when we need an object to seem
like it has a channel, and during testing.
@ -17,6 +18,7 @@ class DummyReply:
class Reply:
"""
Messages sent through a channel are decorated with a "reply" attribute.
This object is used to respond to the message through the return
@ -38,6 +40,7 @@ class Reply:
class Channel:
def __init__(self, q, should_exit):
self.q = q
self.should_exit = should_exit
@ -67,6 +70,7 @@ class Channel:
class Slave(threading.Thread):
"""
Slaves get a channel end-point through which they can send messages to
the master.
@ -84,6 +88,7 @@ class Slave(threading.Thread):
class Master(object):
"""
Masters get and respond to messages from slaves.
"""

View File

@ -9,6 +9,7 @@ import netlib.utils
from . import flow, filt, contentviews
from .exceptions import ContentViewException
class DumpError(Exception):
pass
@ -55,6 +56,7 @@ class Options(object):
class DumpMaster(flow.FlowMaster):
def __init__(self, server, options, outfile=None):
flow.FlowMaster.__init__(self, server, flow.State())
self.outfile = outfile
@ -168,7 +170,7 @@ class DumpMaster(flow.FlowMaster):
"{}: {}".format(
click.style(k, fg="blue", bold=True),
click.style(v, fg="blue"))
for k, v in message.headers.fields
for k, v in message.headers.fields
)
self.echo(headers, indent=4)
if self.o.flow_detail >= 3:
@ -234,7 +236,7 @@ class DumpMaster(flow.FlowMaster):
client = click.style("[replay]", fg="yellow", bold=True)
method = flow.request.method
method_color=dict(
method_color = dict(
GET="green",
DELETE="red"
).get(method.upper(), "magenta")

View File

@ -9,9 +9,11 @@ from __future__ import (absolute_import, print_function, division)
class ProxyException(Exception):
"""
Base class for all exceptions thrown by libmproxy.
"""
def __init__(self, message=None):
super(ProxyException, self).__init__(message)
@ -25,6 +27,7 @@ class TlsProtocolException(ProtocolException):
class ClientHandshakeException(TlsProtocolException):
def __init__(self, message, server):
super(ClientHandshakeException, self).__init__(message)
self.server = server
@ -51,4 +54,4 @@ class ReplayException(ProxyException):
class ScriptException(ProxyException):
pass
pass

View File

@ -38,6 +38,7 @@ import pyparsing as pp
class _Token:
def dump(self, indent=0, fp=sys.stdout):
print >> fp, "\t" * indent, self.__class__.__name__,
if hasattr(self, "expr"):
@ -46,6 +47,7 @@ class _Token:
class _Action(_Token):
@classmethod
def make(klass, s, loc, toks):
return klass(*toks[1:])
@ -261,6 +263,7 @@ class FDst(_Rex):
class _Int(_Action):
def __init__(self, num):
self.num = int(num)
@ -275,6 +278,7 @@ class FCode(_Int):
class FAnd(_Token):
def __init__(self, lst):
self.lst = lst
@ -288,6 +292,7 @@ class FAnd(_Token):
class FOr(_Token):
def __init__(self, lst):
self.lst = lst
@ -301,6 +306,7 @@ class FOr(_Token):
class FNot(_Token):
def __init__(self, itm):
self.itm = itm[0]

View File

@ -22,6 +22,7 @@ from .models import ClientConnection, ServerConnection, HTTPResponse, HTTPFlow,
class AppRegistry:
def __init__(self):
self.apps = {}
@ -49,6 +50,7 @@ class AppRegistry:
class ReplaceHooks:
def __init__(self):
self.lst = []
@ -101,6 +103,7 @@ class ReplaceHooks:
class SetHeaders:
def __init__(self):
self.lst = []
@ -155,6 +158,7 @@ class SetHeaders:
class StreamLargeBodies(object):
def __init__(self, max_size):
self.max_size = max_size
@ -169,6 +173,7 @@ class StreamLargeBodies(object):
class ClientPlaybackState:
def __init__(self, flows, exit):
self.flows, self.exit = flows, exit
self.current = None
@ -203,6 +208,7 @@ class ClientPlaybackState:
class ServerPlaybackState:
def __init__(
self,
headers,
@ -295,6 +301,7 @@ class ServerPlaybackState:
class StickyCookieState:
def __init__(self, flt):
"""
flt: Compiled filter.
@ -342,10 +349,11 @@ class StickyCookieState:
l.append(self.jar[i].output(header="").strip())
if l:
f.request.stickycookie = True
f.request.headers.set_all("cookie",l)
f.request.headers.set_all("cookie", l)
class StickyAuthState:
def __init__(self, flt):
"""
flt: Compiled filter.
@ -397,6 +405,7 @@ class FlowList(object):
class FlowView(FlowList):
def __init__(self, store, filt=None):
self._list = []
if not filt:
@ -433,6 +442,7 @@ class FlowView(FlowList):
class FlowStore(FlowList):
"""
Responsible for handling flows in the state:
Keeps a list of all flows and provides views on them.
@ -526,6 +536,7 @@ class FlowStore(FlowList):
class State(object):
def __init__(self):
self.flows = FlowStore()
self.view = FlowView(self.flows, None)
@ -613,6 +624,7 @@ class State(object):
class FlowMaster(controller.Master):
def __init__(self, server, state):
controller.Master.__init__(self, server)
self.state = state
@ -1099,6 +1111,7 @@ def read_flows_from_paths(paths):
class FlowWriter:
def __init__(self, fo):
self.fo = fo
@ -1108,12 +1121,14 @@ class FlowWriter:
class FlowReadError(Exception):
@property
def strerror(self):
return self.args[0]
class FlowReader:
def __init__(self, fo):
self.fo = fo
@ -1139,6 +1154,7 @@ class FlowReader:
class FilteredFlowWriter:
def __init__(self, fo, filt):
self.fo = fo
self.filt = filt

View File

@ -8,6 +8,7 @@ from .. import stateobject, utils
class ClientConnection(tcp.BaseHandler, stateobject.StateObject):
def __init__(self, client_connection, address, server):
# Eventually, this object is restored from state. We don't have a
# connection then.
@ -88,6 +89,7 @@ class ClientConnection(tcp.BaseHandler, stateobject.StateObject):
class ServerConnection(tcp.TCPClient, stateobject.StateObject):
def __init__(self, address, source_address=None):
tcp.TCPClient.__init__(self, address, source_address)
@ -134,7 +136,7 @@ class ServerConnection(tcp.TCPClient, stateobject.StateObject):
d = super(ServerConnection, self).get_state(short)
d.update(
address=({"address": self.address(),
"use_ipv6": self.address.use_ipv6} if self.address else {}),
"use_ipv6": self.address.use_ipv6} if self.address else {}),
source_address=({"address": self.source_address(),
"use_ipv6": self.source_address.use_ipv6} if self.source_address else None),
cert=self.cert.to_pem() if self.cert else None

View File

@ -7,6 +7,7 @@ from .connections import ClientConnection, ServerConnection
class Error(stateobject.StateObject):
"""
An Error.
@ -53,6 +54,7 @@ class Error(stateobject.StateObject):
class Flow(stateobject.StateObject):
"""
A Flow is a collection of objects representing a single transaction.
This class is usually subclassed for each protocol, e.g. HTTPFlow.

View File

@ -102,6 +102,7 @@ class MessageMixin(stateobject.StateObject):
class HTTPRequest(MessageMixin, Request):
"""
An HTTP request.
@ -264,6 +265,7 @@ class HTTPRequest(MessageMixin, Request):
class HTTPResponse(MessageMixin, Response):
"""
An HTTP response.
@ -411,6 +413,7 @@ class HTTPResponse(MessageMixin, Response):
class HTTPFlow(Flow):
"""
A HTTPFlow is a collection of objects representing a single HTTP
transaction.
@ -544,4 +547,4 @@ def make_connect_response(http_version):
"",
)
expect_continue_response = HTTPResponse(b"HTTP/1.1", 100, "Continue", Headers(), b"")
expect_continue_response = HTTPResponse(b"HTTP/1.1", 100, "Continue", Headers(), b"")

View File

@ -15,6 +15,7 @@ class Adapter(tornado.wsgi.WSGIAdapter):
# Tornado doesn't make the WSGI environment available to pages, so this
# hideous monkey patch is the easiest way to get to the mitmproxy.master
# variable.
def __init__(self, application):
self._application = application
@ -32,12 +33,14 @@ class Adapter(tornado.wsgi.WSGIAdapter):
class Index(tornado.web.RequestHandler):
def get(self):
t = loader.load("index.html")
self.write(t.generate())
class PEM(tornado.web.RequestHandler):
@property
def filename(self):
return config.CONF_BASENAME + "-ca-cert.pem"
@ -55,6 +58,7 @@ class PEM(tornado.web.RequestHandler):
class P12(tornado.web.RequestHandler):
@property
def filename(self):
return config.CONF_BASENAME + "-ca-cert.p12"

View File

@ -6,6 +6,7 @@ SO_ORIGINAL_DST = 80
class Resolver(object):
def original_addr(self, csock):
odestdata = csock.getsockopt(socket.SOL_IP, SO_ORIGINAL_DST, 16)
_, port, a1, a2, a3, a4 = struct.unpack("!HHBBBBxxxxxxxx", odestdata)

View File

@ -18,6 +18,7 @@ PROXY_API_PORT = 8085
class Resolver(object):
def __init__(self):
TransparentProxy.setup()
self.socket = None
@ -53,6 +54,7 @@ class Resolver(object):
class APIRequestHandler(SocketServer.StreamRequestHandler):
"""
TransparentProxy API: Returns the pickled server address, port tuple
for each received pickled client address, port tuple.
@ -77,6 +79,7 @@ class APIRequestHandler(SocketServer.StreamRequestHandler):
class APIServer(SocketServer.ThreadingMixIn, SocketServer.TCPServer):
def __init__(self, proxifier, *args, **kwargs):
SocketServer.TCPServer.__init__(self, *args, **kwargs)
self.proxifier = proxifier
@ -110,6 +113,7 @@ def MIB_TCPTABLE2(size):
class TransparentProxy(object):
"""
Transparent Windows Proxy for mitmproxy based on WinDivert/PyDivert.

View File

@ -9,6 +9,7 @@ from netlib.exceptions import TcpException
class _LayerCodeCompletion(object):
"""
Dummy class that provides type hinting in PyCharm, which simplifies development a lot.
"""
@ -30,6 +31,7 @@ class _LayerCodeCompletion(object):
class Layer(_LayerCodeCompletion):
"""
Base class for all layers. All other protocol layers should inherit from this class.
"""
@ -90,6 +92,7 @@ class Layer(_LayerCodeCompletion):
class ServerConnectionMixin(object):
"""
Mixin that provides a layer with the capabilities to manage a server connection.
The server address can be passed in the constructor or set by calling :py:meth:`set_server`.
@ -189,6 +192,7 @@ class ServerConnectionMixin(object):
class Kill(Exception):
"""
Signal that both client and server connection(s) should be killed immediately.
"""

View File

@ -72,6 +72,7 @@ class _StreamingHttpLayer(_HttpLayer):
class Http1Layer(_StreamingHttpLayer):
def __init__(self, ctx, mode):
super(Http1Layer, self).__init__(ctx)
self.mode = mode
@ -132,6 +133,7 @@ class Http1Layer(_StreamingHttpLayer):
# TODO: The HTTP2 layer is missing multiplexing, which requires a major rewrite.
class Http2Layer(_HttpLayer):
def __init__(self, ctx, mode):
super(Http2Layer, self).__init__(ctx)
self.mode = mode
@ -229,6 +231,7 @@ class Http2Layer(_HttpLayer):
class ConnectServerConnection(object):
"""
"Fake" ServerConnection to represent state after a CONNECT request to an upstream proxy.
"""
@ -249,6 +252,7 @@ class ConnectServerConnection(object):
class UpstreamConnectLayer(Layer):
def __init__(self, ctx, connect_request):
super(UpstreamConnectLayer, self).__init__(ctx)
self.connect_request = connect_request
@ -293,6 +297,7 @@ class UpstreamConnectLayer(Layer):
class HttpLayer(Layer):
def __init__(self, ctx, mode):
super(HttpLayer, self).__init__(ctx)
self.mode = mode
@ -328,7 +333,8 @@ class HttpLayer(Layer):
return
except NetlibException as e:
self.send_error_response(400, repr(e))
six.reraise(ProtocolException, ProtocolException("Error in HTTP connection: %s" % repr(e)), sys.exc_info()[2])
six.reraise(ProtocolException, ProtocolException(
"Error in HTTP connection: %s" % repr(e)), sys.exc_info()[2])
try:
flow = HTTPFlow(self.client_conn, self.server_conn, live=self)
@ -376,7 +382,8 @@ class HttpLayer(Layer):
self.log(traceback.format_exc(), "debug")
return
else:
six.reraise(ProtocolException, ProtocolException("Error in HTTP connection: %s" % repr(e)), sys.exc_info()[2])
six.reraise(ProtocolException, ProtocolException(
"Error in HTTP connection: %s" % repr(e)), sys.exc_info()[2])
finally:
flow.live = False

View File

@ -13,6 +13,7 @@ from .base import Layer
class TcpMessage(object):
def __init__(self, client_conn, server_conn, sender, receiver, message):
self.client_conn = client_conn
self.server_conn = server_conn

View File

@ -13,7 +13,6 @@ from ..exceptions import ProtocolException, TlsProtocolException, ClientHandshak
from .base import Layer
# taken from https://testssl.sh/openssl-rfc.mappping.html
CIPHER_ID_NAME_MAP = {
0x00: 'NULL-MD5',
@ -222,6 +221,7 @@ def is_tls_record_magic(d):
d[2] in ('\x00', '\x01', '\x02', '\x03')
)
def get_client_hello(client_conn):
"""
Peek into the socket and read all records that contain the initial client hello message.
@ -248,7 +248,9 @@ def get_client_hello(client_conn):
client_hello_size = struct.unpack("!I", '\x00' + client_hello[1:4])[0] + 4
return client_hello
class TlsClientHello(object):
def __init__(self, raw_client_hello):
self._client_hello = ClientHello.parse(raw_client_hello)
@ -289,15 +291,16 @@ class TlsClientHello(object):
try:
return cls(raw_client_hello)
except ConstructError as e:
raise TlsProtocolException('Cannot parse Client Hello: %s, Raw Client Hello: %s' % \
(repr(e), raw_client_hello.encode("hex")))
raise TlsProtocolException('Cannot parse Client Hello: %s, Raw Client Hello: %s' %
(repr(e), raw_client_hello.encode("hex")))
def __repr__(self):
return "TlsClientHello( sni: %s alpn_protocols: %s, cipher_suites: %s)" % \
(self.client_sni, self.client_alpn_protocols, self.client_cipher_suites)
(self.client_sni, self.client_alpn_protocols, self.client_cipher_suites)
class TlsLayer(Layer):
def __init__(self, ctx, client_tls, server_tls):
self.client_sni = None
self.client_alpn_protocols = None
@ -356,7 +359,6 @@ class TlsLayer(Layer):
else:
return "TlsLayer(inactive)"
def _parse_client_hello(self):
"""
Peek into the connection, read the initial client hello and parse it to obtain ALPN values.
@ -365,7 +367,7 @@ class TlsLayer(Layer):
parsed = TlsClientHello.from_client_conn(self.client_conn)
self.client_sni = parsed.client_sni
self.client_alpn_protocols = parsed.client_alpn_protocols
self.client_ciphers = parsed.client_cipher_suites
self.client_ciphers = parsed.client_cipher_suites
except TlsProtocolException as e:
self.log("Cannot parse Client Hello: %s" % repr(e), "error")
@ -468,7 +470,7 @@ class TlsLayer(Layer):
alpn = [x for x in self.client_alpn_protocols if not deprecated_http2_variant(x)]
else:
alpn = None
if alpn and "h2" in alpn and not self.config.http2 :
if alpn and "h2" in alpn and not self.config.http2:
alpn.remove("h2")
ciphers_server = self.config.ciphers_server

View File

@ -19,6 +19,7 @@ DEFAULT_CLIENT_CIPHERS = "ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA
class HostMatcher(object):
def __init__(self, patterns=tuple()):
self.patterns = list(patterns)
self.regexes = [re.compile(p, re.IGNORECASE) for p in self.patterns]
@ -41,6 +42,7 @@ ServerSpec = collections.namedtuple("ServerSpec", "scheme address")
class ProxyConfig:
def __init__(
self,
host='',

View File

@ -4,6 +4,7 @@ from ...protocol import Layer, ServerConnectionMixin
class HttpProxy(Layer, ServerConnectionMixin):
def __call__(self):
layer = self.ctx.next_layer(self)
try:
@ -14,6 +15,7 @@ class HttpProxy(Layer, ServerConnectionMixin):
class HttpUpstreamProxy(Layer, ServerConnectionMixin):
def __init__(self, ctx, server_address):
super(HttpUpstreamProxy, self).__init__(ctx, server_address=server_address)

View File

@ -4,6 +4,7 @@ from ...protocol import Layer, ServerConnectionMixin
class ReverseProxy(Layer, ServerConnectionMixin):
def __init__(self, ctx, server_address, server_tls):
super(ReverseProxy, self).__init__(ctx, server_address=server_address)
self.server_tls = server_tls

View File

@ -8,6 +8,7 @@ from ...protocol import Layer, ServerConnectionMixin
class Socks5Proxy(Layer, ServerConnectionMixin):
def __init__(self, ctx):
super(Socks5Proxy, self).__init__(ctx)

View File

@ -6,6 +6,7 @@ from ...protocol import Layer, ServerConnectionMixin
class TransparentProxy(Layer, ServerConnectionMixin):
def __init__(self, ctx):
super(TransparentProxy, self).__init__(ctx)
self.resolver = platform.resolver()

View File

@ -12,7 +12,9 @@ from ..protocol import (
)
from .modes import HttpProxy, HttpUpstreamProxy, ReverseProxy
class RootContext(object):
"""
The outermost context provided to the root layer.
As a consequence, every layer has access to methods and attributes defined here.
@ -131,6 +133,7 @@ class RootContext(object):
class Log(object):
def __init__(self, msg, level="info"):
self.msg = msg
self.level = level

View File

@ -65,6 +65,7 @@ class ProxyServer(tcp.TCPServer):
class ConnectionHandler(object):
def __init__(self, client_conn, client_address, config, channel):
self.config = config
"""@type: libmproxy.proxy.config.ProxyConfig"""

View File

@ -10,4 +10,4 @@ __all__ = [
"concurrent",
"ScriptException",
"reloader"
]
]

View File

@ -7,6 +7,7 @@ import threading
class ReplyProxy(object):
def __init__(self, original_reply, script_thread):
self.original_reply = original_reply
self.script_thread = script_thread

View File

@ -1,11 +1,11 @@
import os
import sys
from watchdog.events import RegexMatchingEventHandler
from watchdog.events import RegexMatchingEventHandler
if sys.platform == 'darwin':
from watchdog.observers.polling import PollingObserver as Observer
else:
from watchdog.observers import Observer
# The OSX reloader in watchdog 0.8.3 breaks when unobserving paths.
# The OSX reloader in watchdog 0.8.3 breaks when unobserving paths.
# We use the PollingObserver instead.
_observers = {}
@ -31,11 +31,12 @@ def unwatch(script):
class _ScriptModificationHandler(RegexMatchingEventHandler):
def __init__(self, callback, filename='.*'):
super(_ScriptModificationHandler, self).__init__(
ignore_directories=True,
regexes=['.*'+filename]
regexes=['.*' + filename]
)
self.callback = callback
@ -43,4 +44,3 @@ class _ScriptModificationHandler(RegexMatchingEventHandler):
self.callback()
__all__ = ["watch", "unwatch"]

View File

@ -12,6 +12,7 @@ from ..exceptions import ScriptException
class Script(object):
"""
Script object representing an inline script.
"""
@ -94,4 +95,4 @@ class Script(object):
except Exception as e:
raise ScriptException(traceback.format_exc(e))
else:
return None
return None

View File

@ -6,6 +6,7 @@ from .. import contentviews
class ScriptContext(object):
"""
The script context should be used to interact with the global mitmproxy state from within a
script.

View File

@ -2,6 +2,7 @@ from __future__ import absolute_import
class StateObject(object):
"""
An object with serializable state.

View File

@ -37,7 +37,7 @@ def isBin(s):
def isMostlyBin(s):
s = s[:100]
return sum(isBin(ch) for ch in s)/len(s) > 0.3
return sum(isBin(ch) for ch in s) / len(s) > 0.3
def isXML(s):
@ -73,6 +73,7 @@ def pretty_duration(secs):
class Data:
def __init__(self, name):
m = __import__(name)
dirname, _ = os.path.split(m.__file__)
@ -93,6 +94,7 @@ pkg_data = Data(__name__)
class LRUCache:
"""
A simple LRU cache for generated values.
"""

View File

@ -11,6 +11,7 @@ class Stop(Exception):
class WebFlowView(flow.FlowView):
def __init__(self, store):
super(WebFlowView, self).__init__(store, None)
@ -47,6 +48,7 @@ class WebFlowView(flow.FlowView):
class WebState(flow.State):
def __init__(self):
super(WebState, self).__init__()
self.view._close()
@ -121,6 +123,7 @@ class Options(object):
class WebMaster(flow.FlowMaster):
def __init__(self, server, options):
self.options = options
super(WebMaster, self).__init__(server, WebState())

View File

@ -12,6 +12,7 @@ class APIError(tornado.web.HTTPError):
class RequestHandler(tornado.web.RequestHandler):
def set_default_headers(self):
super(RequestHandler, self).set_default_headers()
self.set_header("Server", version.NAMEVERSION)
@ -56,12 +57,14 @@ class RequestHandler(tornado.web.RequestHandler):
class IndexHandler(RequestHandler):
def get(self):
_ = self.xsrf_token # https://github.com/tornadoweb/tornado/issues/645
self.render("index.html")
class FiltHelp(RequestHandler):
def get(self):
self.write(dict(
commands=filt.help
@ -94,6 +97,7 @@ class ClientConnection(WebSocketEventBroadcaster):
class Flows(RequestHandler):
def get(self):
self.write(dict(
data=[f.get_state(short=True) for f in self.state.flows]
@ -101,21 +105,25 @@ class Flows(RequestHandler):
class ClearAll(RequestHandler):
def post(self):
self.state.clear()
class AcceptFlows(RequestHandler):
def post(self):
self.state.flows.accept_all(self.master)
class AcceptFlow(RequestHandler):
def post(self, flow_id):
self.flow.accept_intercept(self.master)
class FlowHandler(RequestHandler):
def delete(self, flow_id):
self.flow.kill(self.master)
self.state.delete_flow(self.flow)
@ -156,16 +164,19 @@ class FlowHandler(RequestHandler):
class DuplicateFlow(RequestHandler):
def post(self, flow_id):
self.master.duplicate_flow(self.flow)
class RevertFlow(RequestHandler):
def post(self, flow_id):
self.state.revert(self.flow)
class ReplayFlow(RequestHandler):
def post(self, flow_id):
self.flow.backup()
self.flow.response = None
@ -177,6 +188,7 @@ class ReplayFlow(RequestHandler):
class FlowContent(RequestHandler):
def get(self, flow_id, message):
message = getattr(self.flow, message)
@ -207,6 +219,7 @@ class FlowContent(RequestHandler):
class Events(RequestHandler):
def get(self):
self.write(dict(
data=list(self.state.events)
@ -214,6 +227,7 @@ class Events(RequestHandler):
class Settings(RequestHandler):
def get(self):
self.write(dict(
data=dict(
@ -240,6 +254,7 @@ class Settings(RequestHandler):
class Application(tornado.web.Application):
def __init__(self, master, debug):
self.master = master
handlers = [

View File

@ -1,4 +1,4 @@
import argparse
parser = argparse.ArgumentParser()
parser.add_argument('--var', type=int)
parser.add_argument('--var', type=int)

View File

@ -1,3 +1,3 @@
def tcp_message(ctx,tm):
def tcp_message(ctx, tm):
if tm.sender == tm.server_conn:
tm.message = tm.message.replace("foo", "bar")

View File

@ -1,2 +1,2 @@
def done(ctx):
raise RuntimeError()
raise RuntimeError()

View File

@ -3,6 +3,7 @@ import tservers
class TestApp(tservers.HTTPProxTest):
def test_basic(self):
assert self.app("/").status_code == 200

View File

@ -8,6 +8,7 @@ import tutils
class TestConsoleState:
def test_flow(self):
"""
normal flow:

View File

@ -7,11 +7,13 @@ import libmproxy.console.help as help
class DummyLoop:
def __init__(self):
self.widget = None
class DummyMaster:
def __init__(self):
self.loop = DummyLoop()
@ -20,6 +22,7 @@ class DummyMaster:
class TestHelp:
def test_helptext(self):
h = help.HelpView(None)
assert h.helptext()

View File

@ -6,6 +6,7 @@ import libmproxy.console.palettes as palettes
class TestPalette:
def test_helptext(self):
for i in palettes.palettes.values():
assert i.palette(False)

View File

@ -6,6 +6,7 @@ import tutils
class TestPathCompleter:
def test_lookup_construction(self):
c = pathedit._PathCompleter()

View File

@ -3,6 +3,7 @@ from libmproxy import controller
class TestMaster:
def test_default_handler(self):
m = controller.Master(None)
msg = mock.MagicMock()

View File

@ -11,7 +11,6 @@ def test_custom_views():
def __call__(self, data, **metadata):
return "noop", cv.format_text(data)
view_obj = ViewNoop()
cv.add(view_obj)
@ -47,5 +46,3 @@ def test_custom_views():
)
)
assert "noop" not in r[0]

View File

@ -43,7 +43,6 @@ def test_strfuncs():
flow.response.status_code = 300
m.echo_flow(flow)
flow = tutils.tflow(resp=netlib.tutils.tresp(content="{"))
flow.response.headers["content-type"] = "application/json"
flow.response.status_code = 400
@ -61,6 +60,7 @@ def test_contentview(get_content_view):
class TestDumpMaster:
def _cycle(self, m, content):
f = tutils.tflow(req=netlib.tutils.treq(content=content))
l = Log("connect")

View File

@ -7,6 +7,7 @@ import tutils
class TestParsing:
def _dump(self, x):
c = cStringIO.StringIO()
x.dump(fp=c)
@ -75,6 +76,7 @@ class TestParsing:
class TestMatching:
def req(self):
headers = Headers(header="qvalue")
req = http.HTTPRequest(

View File

@ -43,6 +43,7 @@ def test_app_registry():
class TestStickyCookieState:
def _response(self, cookie, host):
s = flow.StickyCookieState(filt.parse(".*"))
f = tutils.tflow(req=netlib.tutils.treq(host=host, port=80), resp=True)
@ -76,6 +77,7 @@ class TestStickyCookieState:
class TestStickyAuthState:
def test_handle_response(self):
s = flow.StickyAuthState(filt.parse(".*"))
f = tutils.tflow(resp=True)
@ -89,6 +91,7 @@ class TestStickyAuthState:
class TestClientPlaybackState:
def test_tick(self):
first = tutils.tflow()
s = flow.State()
@ -122,6 +125,7 @@ class TestClientPlaybackState:
class TestServerPlaybackState:
def test_hash(self):
s = flow.ServerPlaybackState(
None,
@ -343,6 +347,7 @@ class TestServerPlaybackState:
class TestFlow(object):
def test_copy(self):
f = tutils.tflow(resp=True)
a0 = f.get_state()
@ -492,6 +497,7 @@ class TestFlow(object):
class TestState:
def test_backup(self):
c = flow.State()
f = tutils.tflow()
@ -629,6 +635,7 @@ class TestState:
class TestSerialize:
def _treader(self):
sio = StringIO()
w = flow.FlowWriter(sio)
@ -716,6 +723,7 @@ class TestSerialize:
class TestFlowMaster:
def test_load_script(self):
s = flow.State()
fm = flow.FlowMaster(None, s)
@ -995,6 +1003,7 @@ class TestFlowMaster:
class TestRequest:
def test_simple(self):
f = tutils.tflow()
r = f.request
@ -1113,7 +1122,7 @@ class TestRequest:
r = HTTPRequest.wrap(netlib.tutils.treq())
r.content = None
r.headers["content-encoding"] = "identity"
assert r.get_decoded_content() == None
assert r.get_decoded_content() is None
r.content = "falafel"
r.encode("gzip")
@ -1126,6 +1135,7 @@ class TestRequest:
class TestResponse:
def test_simple(self):
f = tutils.tflow(resp=True)
resp = f.response
@ -1179,6 +1189,7 @@ class TestResponse:
class TestError:
def test_getset_state(self):
e = Error("Error")
state = e.get_state()
@ -1196,6 +1207,7 @@ class TestError:
class TestClientConnection:
def test_state(self):
c = tutils.tclient_conn()

View File

@ -14,4 +14,4 @@ def test_cannot_convert():
with open(tutils.test_data.path("data/dumpfile-012"), "rb") as f:
flow_reader = FlowReader(f)
with tutils.raises(FlowReadError):
list(flow_reader.stream())
list(flow_reader.stream())

View File

@ -7,6 +7,7 @@ import tservers
class TestFuzzy(tservers.HTTPProxTest):
def test_idna_err(self):
req = r'get:"http://localhost:%s":i10,"\xc6"'
p = self.pathoc()

View File

@ -4,6 +4,7 @@ from libmproxy.platform import pf
class TestLookup:
def test_simple(self):
if sys.platform == "freebsd10":
p = tutils.test_data.path("data/pf02")

View File

@ -8,6 +8,7 @@ import tservers
class TestHTTPResponse:
def test_read_from_stringio(self):
s = (
b"HTTP/1.1 200 OK\r\n"
@ -34,6 +35,7 @@ class TestHTTPResponse:
class TestHTTPFlow(object):
def test_repr(self):
f = tutils.tflow(resp=True, err=True)
assert repr(f)
@ -57,6 +59,7 @@ class TestInvalidRequests(tservers.HTTPProxTest):
class TestExpectHeader(tservers.HTTPProxTest):
def test_simple(self):
client = TCPClient(("127.0.0.1", self.proxy.port))
client.connect()
@ -83,7 +86,8 @@ class TestExpectHeader(tservers.HTTPProxTest):
class TestHeadContentLength(tservers.HTTPProxTest):
def test_head_content_length(self):
p = self.pathoc()
resp = p.request("""head:'%s/p/200:h"Content-Length"="42"'""" % self.server.urlbase)
assert resp.headers["Content-Length"] == "42"
assert resp.headers["Content-Length"] == "42"

View File

@ -54,6 +54,7 @@ class TestServerConnection(object):
class TestProcessProxyOptions:
def p(self, *args):
parser = tutils.MockParser()
cmdline.common_options(parser)
@ -151,6 +152,7 @@ class TestProcessProxyOptions:
class TestProxyServer:
# binding to 0.0.0.0:1 works without special permissions on Windows
@tutils.skip_windows
def test_err(self):
conf = ProxyConfig(
@ -166,6 +168,7 @@ class TestProxyServer:
class TestDummyServer:
def test_simple(self):
d = DummyServer(None)
d.start_slave()
@ -173,6 +176,7 @@ class TestDummyServer:
class TestConnectionHandler:
def test_fatal_error(self):
config = mock.Mock()
root_layer = mock.Mock()

View File

@ -91,6 +91,7 @@ def test_concurrent2():
m = mock.Mock()
class Dummy:
def __init__(self):
self.response = self
self.error = self
@ -129,4 +130,3 @@ def test_command_parsing():
absfilepath = os.path.normcase(tutils.test_data.path("scripts/a.py"))
s = script.Script(absfilepath, script.ScriptContext(fm))
assert os.path.isfile(s.args[0])

View File

@ -29,6 +29,7 @@ import tservers
class CommonMixin:
def test_large(self):
assert len(self.pathod("200:b@50k").content) == 1024 * 50
@ -107,6 +108,7 @@ class CommonMixin:
class TcpMixin:
def _ignore_on(self):
assert not hasattr(self, "_ignore_backup")
self._ignore_backup = self.config.check_ignore
@ -194,6 +196,7 @@ class TcpMixin:
class AppMixin:
def test_app(self):
ret = self.app("/")
assert ret.status_code == 200
@ -201,6 +204,7 @@ class AppMixin:
class TestHTTP(tservers.HTTPProxTest, CommonMixin, AppMixin):
def test_app_err(self):
p = self.pathoc()
ret = p.request("get:'http://errapp/'")
@ -348,6 +352,7 @@ class TestHTTPSCertfile(tservers.HTTPProxTest, CommonMixin):
class TestHTTPSUpstreamServerVerificationWTrustedCert(tservers.HTTPProxTest):
"""
Test upstream server certificate verification with a trusted server cert.
"""
@ -374,6 +379,7 @@ class TestHTTPSUpstreamServerVerificationWTrustedCert(tservers.HTTPProxTest):
class TestHTTPSUpstreamServerVerificationWBadCert(tservers.HTTPProxTest):
"""
Test upstream server certificate verification with an untrusted server cert.
"""
@ -412,6 +418,7 @@ class TestHTTPSUpstreamServerVerificationWBadCert(tservers.HTTPProxTest):
class TestHTTPSNoCommonName(tservers.HTTPProxTest):
"""
Test what happens if we get a cert without common name back.
"""
@ -432,6 +439,7 @@ class TestReverse(tservers.ReverseProxTest, CommonMixin, TcpMixin):
class TestSocks5(tservers.SocksModeTest):
def test_simple(self):
p = self.pathoc()
p.socks_connect(("localhost", self.server.port))
@ -469,6 +477,7 @@ class TestSocks5(tservers.SocksModeTest):
class TestHttps2Http(tservers.ReverseProxTest):
@classmethod
def get_proxy_config(cls):
d = super(TestHttps2Http, cls).get_proxy_config()
@ -526,6 +535,7 @@ class TestTransparentSSL(tservers.TransparentProxTest, CommonMixin, TcpMixin):
class TestProxy(tservers.HTTPProxTest):
def test_http(self):
f = self.pathod("304")
assert f.status_code == 304
@ -562,7 +572,7 @@ class TestProxy(tservers.HTTPProxTest):
connection.close()
request, response = self.master.state.view[
0].request, self.master.state.view[0].response
0].request, self.master.state.view[0].response
assert response.status_code == 304 # sanity test for our low level request
# timestamp_start might fire a bit late, so we play safe and only require 300ms.
assert 0.3 <= request.timestamp_end - request.timestamp_start
@ -678,6 +688,7 @@ class TestRedirectRequest(tservers.HTTPProxTest):
class MasterStreamRequest(tservers.TestMaster):
"""
Enables the stream flag on the flow for all requests
"""
@ -731,6 +742,7 @@ class TestStreamRequest(tservers.HTTPProxTest):
class MasterFakeResponse(tservers.TestMaster):
def handle_request(self, f):
resp = HTTPResponse.wrap(netlib.tutils.tresp())
f.reply(resp)
@ -748,6 +760,7 @@ class TestServerConnect(tservers.HTTPProxTest):
masterclass = MasterFakeResponse
no_upstream_cert = True
ssl = True
def test_unnecessary_serverconnect(self):
"""A replayed/fake response with no_upstream_cert should not connect to an upstream server"""
assert self.pathod("200").status_code == 200
@ -756,6 +769,7 @@ class TestServerConnect(tservers.HTTPProxTest):
class MasterKillRequest(tservers.TestMaster):
def handle_request(self, f):
f.reply(Kill)
@ -771,6 +785,7 @@ class TestKillRequest(tservers.HTTPProxTest):
class MasterKillResponse(tservers.TestMaster):
def handle_response(self, f):
f.reply(Kill)
@ -786,6 +801,7 @@ class TestKillResponse(tservers.HTTPProxTest):
class EResolver(tservers.TResolver):
def original_addr(self, sock):
raise RuntimeError("Could not resolve original destination.")
@ -798,6 +814,7 @@ class TestTransparentResolveError(tservers.TransparentProxTest):
class MasterIncomplete(tservers.TestMaster):
def handle_request(self, f):
resp = HTTPResponse.wrap(netlib.tutils.tresp())
resp.content = CONTENT_MISSING
@ -833,9 +850,9 @@ class TestUpstreamProxy(tservers.HTTPUpstreamProxTest, CommonMixin, AppMixin):
class TestUpstreamProxySSL(
tservers.HTTPUpstreamProxTest,
CommonMixin,
TcpMixin):
tservers.HTTPUpstreamProxTest,
CommonMixin,
TcpMixin):
ssl = True
def _host_pattern_on(self, attr):
@ -930,7 +947,7 @@ class TestProxyChainingSSLReconnect(tservers.HTTPUpstreamProxTest):
exclude=[
# fail first request
2, # allow second request
])
])
kill_requests(self.chain[0].tmaster, "handle_request",
exclude=[
@ -938,7 +955,7 @@ class TestProxyChainingSSLReconnect(tservers.HTTPUpstreamProxTest):
# fail first request
3, # reCONNECT
4, # request
])
])
p = self.pathoc()
req = p.request("get:'/p/418:b\"content\"'")
@ -954,7 +971,6 @@ class TestProxyChainingSSLReconnect(tservers.HTTPUpstreamProxTest):
# (doesn't store (repeated) CONNECTs from chain[0]
# as it is a regular proxy)
assert not self.chain[1].tmaster.state.flows[0].response # killed
assert self.chain[1].tmaster.state.flows[1].response
@ -962,18 +978,18 @@ class TestProxyChainingSSLReconnect(tservers.HTTPUpstreamProxTest):
assert self.proxy.tmaster.state.flows[1].request.form_in == "relative"
assert self.chain[0].tmaster.state.flows[
0].request.form_in == "authority"
0].request.form_in == "authority"
assert self.chain[0].tmaster.state.flows[
1].request.form_in == "relative"
1].request.form_in == "relative"
assert self.chain[0].tmaster.state.flows[
2].request.form_in == "authority"
2].request.form_in == "authority"
assert self.chain[0].tmaster.state.flows[
3].request.form_in == "relative"
3].request.form_in == "relative"
assert self.chain[1].tmaster.state.flows[
0].request.form_in == "relative"
0].request.form_in == "relative"
assert self.chain[1].tmaster.state.flows[
1].request.form_in == "relative"
1].request.form_in == "relative"
req = p.request("get:'/p/418:b\"content2\"'")

View File

@ -15,6 +15,7 @@ import click
class ApacheBenchThread(Thread):
def __init__(self, concurrency):
self.concurrency = concurrency
super(ApacheBenchThread, self).__init__()

View File

@ -15,6 +15,7 @@ def read_tnetstring(input):
input.seek(-1, 1)
return tnetstring.load(input)
@click.command()
@click.argument("input", type=click.File('rb'))
def inspect(input):

View File

@ -18,7 +18,7 @@ def str_fun(obj):
return "(-locals-)"
if "self" in obj and isinstance(obj["self"], refbrowser.InteractiveBrowser):
return "(-browser-)"
return str(id(obj)) + ": " + str(obj)[:100].replace("\r\n","\\r\\n").replace("\n","\\n")
return str(id(obj)) + ": " + str(obj)[:100].replace("\r\n", "\\r\\n").replace("\n", "\\n")
def request(ctx, flow):
@ -35,4 +35,4 @@ def request(ctx, flow):
ib = refbrowser.InteractiveBrowser(ssl, 2, str_fun, repeat=False)
del ssl # do this to unpollute view
ib.main(True)
# print("\r\n".join(str(x)[:100] for x in gc.get_referrers(ssl)))
# print("\r\n".join(str(x)[:100] for x in gc.get_referrers(ssl)))

View File

@ -3,6 +3,7 @@ from time import sleep
class service(SocketServer.BaseRequestHandler):
def handle(self):
data = 'dummy'
print "Client connected with ", self.client_address

View File

@ -29,6 +29,7 @@ def errapp(environ, start_response):
class TestMaster(flow.FlowMaster):
def __init__(self, config):
config.port = 0
s = ProxyServer(config)
@ -55,6 +56,7 @@ class TestMaster(flow.FlowMaster):
class ProxyThread(threading.Thread):
def __init__(self, tmaster):
threading.Thread.__init__(self)
self.tmaster = tmaster
@ -131,6 +133,7 @@ class ProxTestBase(object):
class HTTPProxTest(ProxTestBase):
def pathoc_raw(self):
return libpathod.pathoc.Pathoc(("127.0.0.1", self.proxy.port), fp=None)
@ -172,12 +175,14 @@ class HTTPProxTest(ProxTestBase):
class TResolver:
def __init__(self, port):
self.port = port
def original_addr(self, sock):
return ("127.0.0.1", self.port)
class TransparentProxTest(ProxTestBase):
ssl = None
resolver = TResolver
@ -263,6 +268,7 @@ class ReverseProxTest(ProxTestBase):
class SocksModeTest(HTTPProxTest):
@classmethod
def get_proxy_config(cls):
d = ProxTestBase.get_proxy_config()
@ -271,6 +277,7 @@ class SocksModeTest(HTTPProxTest):
class ChainProxTest(ProxTestBase):
"""
Chain three instances of mitmproxy in a row to test upstream mode.
Proxy order is cls.proxy -> cls.chain[0] -> cls.chain[1]

View File

@ -121,6 +121,7 @@ def tmpdir(*args, **kwargs):
class MockParser(argparse.ArgumentParser):
"""
argparse.ArgumentParser sys.exits() by default.
Make it more testable by throwing an exception instead.