minor fixes

This commit is contained in:
Maximilian Hils 2016-11-10 08:50:21 +01:00
parent 47ec1c9570
commit 677789a617
8 changed files with 40 additions and 31 deletions

2
dev.sh
View File

@ -7,7 +7,7 @@ VENV="venv$PYVERSION"
echo "Creating dev environment in $VENV using Python $PYVERSION" echo "Creating dev environment in $VENV using Python $PYVERSION"
python$PYVERSION -m virtualenv "$VENV" --always-copy python$PYVERSION -m venv "$VENV"
. "$VENV/bin/activate" . "$VENV/bin/activate"
pip$PYVERSION install -U pip setuptools pip$PYVERSION install -U pip setuptools
pip$PYVERSION install -r requirements.txt pip$PYVERSION install -r requirements.txt

View File

@ -83,7 +83,7 @@ class Options(optmanager.OptManager):
ssl_verify_upstream_trusted_cadir: Optional[str] = None, ssl_verify_upstream_trusted_cadir: Optional[str] = None,
ssl_verify_upstream_trusted_ca: Optional[str] = None, ssl_verify_upstream_trusted_ca: Optional[str] = None,
tcp_hosts: Sequence[str] = () tcp_hosts: Sequence[str] = ()
): ) -> None:
# We could replace all assignments with clever metaprogramming, # We could replace all assignments with clever metaprogramming,
# but type hints are a much more valueable asset. # but type hints are a much more valueable asset.

View File

@ -0,0 +1,5 @@
from mitmproxy.tools import web
from mitmproxy.tools import console
from mitmproxy.tools import dump
__all__ = ["web", "console", "dump"]

View File

@ -26,8 +26,7 @@ class Column(col_bytes.Column):
# This is the same for both edit and display. # This is the same for both edit and display.
class EncodingMixin: class EncodingMixin:
def __init__(self, data, encoding_args): def __init__(self, data: str, encoding_args) -> "TDisplay":
# type: (str) -> TDisplay
self.encoding_args = encoding_args self.encoding_args = encoding_args
data = data.encode(*self.encoding_args) data = data.encode(*self.encoding_args)
super().__init__(data) super().__init__(data)

View File

@ -1,5 +1,4 @@
import typing from typing import Optional, IO
from typing import Optional
from mitmproxy import controller from mitmproxy import controller
from mitmproxy import exceptions from mitmproxy import exceptions
@ -22,9 +21,9 @@ class Options(options.Options):
keepserving: bool = False, keepserving: bool = False,
filtstr: Optional[str] = None, filtstr: Optional[str] = None,
flow_detail: int = 1, flow_detail: int = 1,
tfile: Optional[typing.io.TextIO] = None, tfile: Optional[IO[str]] = None,
**kwargs **kwargs
): ) -> None:
self.filtstr = filtstr self.filtstr = filtstr
self.flow_detail = flow_detail self.flow_detail = flow_detail
self.keepserving = keepserving self.keepserving = keepserving

View File

@ -1,3 +1,4 @@
import base64 import base64
import hashlib import hashlib
import json import json
@ -10,14 +11,15 @@ import tornado.web
import tornado.websocket import tornado.websocket
import tornado.escape import tornado.escape
from mitmproxy import contentviews from mitmproxy import contentviews
from mitmproxy import flow
from mitmproxy import flowfilter from mitmproxy import flowfilter
from mitmproxy import http from mitmproxy import http
from mitmproxy import io from mitmproxy import io
from mitmproxy import version from mitmproxy import version
import mitmproxy.addons.view
import mitmproxy.flow
def convert_flow_to_json_dict(flow: flow.Flow) -> dict: def convert_flow_to_json_dict(flow: mitmproxy.flow.Flow) -> dict:
""" """
Remove flow message content and cert to save transmission space. Remove flow message content and cert to save transmission space.
@ -86,9 +88,9 @@ class BasicAuth:
if auth_header is None or not auth_header.startswith('Basic '): if auth_header is None or not auth_header.startswith('Basic '):
self.set_auth_headers() self.set_auth_headers()
else: else:
self.auth_decoded = base64.decodestring(auth_header[6:]) auth_decoded = base64.decodebytes(auth_header[6:])
self.username, self.password = self.auth_decoded.split(':', 2) username, password = auth_decoded.split(':', 2)
if not wauthenticator.test(self.username, self.password): if not wauthenticator.test(username, password):
self.set_auth_headers() self.set_auth_headers()
raise APIError(401, "Invalid username or password.") raise APIError(401, "Invalid username or password.")
@ -123,7 +125,7 @@ class RequestHandler(BasicAuth, tornado.web.RequestHandler):
return json.loads(self.request.body.decode()) return json.loads(self.request.body.decode())
@property @property
def view(self): def view(self) -> mitmproxy.addons.view.View:
return self.application.master.view return self.application.master.view
@property @property
@ -131,7 +133,7 @@ class RequestHandler(BasicAuth, tornado.web.RequestHandler):
return self.application.master return self.application.master
@property @property
def flow(self): def flow(self) -> mitmproxy.flow.Flow:
flow_id = str(self.path_kwargs["flow_id"]) flow_id = str(self.path_kwargs["flow_id"])
# FIXME: Add a facility to addon.view to safely access the store # FIXME: Add a facility to addon.view to safely access the store
flow = self.view._store.get(flow_id) flow = self.view._store.get(flow_id)
@ -140,7 +142,7 @@ class RequestHandler(BasicAuth, tornado.web.RequestHandler):
else: else:
raise APIError(400, "Flow not found.") raise APIError(400, "Flow not found.")
def write_error(self, status_code, **kwargs): def write_error(self, status_code: int, **kwargs):
if "exc_info" in kwargs and isinstance(kwargs["exc_info"][1], APIError): if "exc_info" in kwargs and isinstance(kwargs["exc_info"][1], APIError):
self.finish(kwargs["exc_info"][1].log_message) self.finish(kwargs["exc_info"][1].log_message)
else: else:
@ -165,7 +167,7 @@ class FilterHelp(RequestHandler):
class WebSocketEventBroadcaster(BasicAuth, tornado.websocket.WebSocketHandler): class WebSocketEventBroadcaster(BasicAuth, tornado.websocket.WebSocketHandler):
# raise an error if inherited class doesn't specify its own instance. # raise an error if inherited class doesn't specify its own instance.
connections = None connections = None # type: set
def open(self): def open(self):
self.connections.add(self) self.connections.add(self)
@ -180,12 +182,12 @@ class WebSocketEventBroadcaster(BasicAuth, tornado.websocket.WebSocketHandler):
for conn in cls.connections: for conn in cls.connections:
try: try:
conn.write_message(message) conn.write_message(message)
except: except Exception:
logging.error("Error sending message", exc_info=True) logging.error("Error sending message", exc_info=True)
class ClientConnection(WebSocketEventBroadcaster): class ClientConnection(WebSocketEventBroadcaster):
connections = set() connections = set() # type: set
class Flows(RequestHandler): class Flows(RequestHandler):
@ -212,7 +214,7 @@ class DumpFlows(RequestHandler):
content = self.request.files.values()[0][0].body content = self.request.files.values()[0][0].body
bio = BytesIO(content) bio = BytesIO(content)
self.view.load_flows(io.FlowReader(bio).stream()) self.master.load_flows(io.FlowReader(bio).stream())
bio.close() bio.close()
@ -225,7 +227,7 @@ class ClearAll(RequestHandler):
class AcceptFlows(RequestHandler): class AcceptFlows(RequestHandler):
def post(self): def post(self):
self.view.flows.accept_all(self.master) self.master.accept_all(self.master)
class AcceptFlow(RequestHandler): class AcceptFlow(RequestHandler):
@ -239,13 +241,13 @@ class FlowHandler(RequestHandler):
def delete(self, flow_id): def delete(self, flow_id):
if self.flow.killable: if self.flow.killable:
self.flow.kill(self.master) self.flow.kill(self.master)
self.view.delete_flow(self.flow) self.view.remove(self.flow)
def put(self, flow_id): def put(self, flow_id):
flow = self.flow flow = self.flow
flow.backup() flow.backup()
for a, b in self.json.items(): for a, b in self.json.items():
if a == "request": if a == "request" and hasattr(flow, "request"):
request = flow.request request = flow.request
for k, v in b.items(): for k, v in b.items():
if k in ["method", "scheme", "host", "path", "http_version"]: if k in ["method", "scheme", "host", "path", "http_version"]:
@ -261,7 +263,7 @@ class FlowHandler(RequestHandler):
else: else:
print("Warning: Unknown update {}.{}: {}".format(a, k, v)) print("Warning: Unknown update {}.{}: {}".format(a, k, v))
elif a == "response": elif a == "response" and hasattr(flow, "response"):
response = flow.response response = flow.response
for k, v in b.items(): for k, v in b.items():
if k == "msg": if k == "msg":
@ -280,7 +282,7 @@ class FlowHandler(RequestHandler):
print("Warning: Unknown update {}.{}: {}".format(a, k, v)) print("Warning: Unknown update {}.{}: {}".format(a, k, v))
else: else:
print("Warning: Unknown update {}: {}".format(a, b)) print("Warning: Unknown update {}: {}".format(a, b))
self.view.update_flow(flow) self.view.update(flow)
class DuplicateFlow(RequestHandler): class DuplicateFlow(RequestHandler):
@ -300,7 +302,7 @@ class ReplayFlow(RequestHandler):
def post(self, flow_id): def post(self, flow_id):
self.flow.backup() self.flow.backup()
self.flow.response = None self.flow.response = None
self.view.update_flow(self.flow) self.view.update(self.flow)
r = self.master.replay_request(self.flow) r = self.master.replay_request(self.flow)
if r: if r:
@ -313,7 +315,7 @@ class FlowContent(RequestHandler):
self.flow.backup() self.flow.backup()
message = getattr(self.flow, message) message = getattr(self.flow, message)
message.content = self.request.files.values()[0][0].body message.content = self.request.files.values()[0][0].body
self.view.update_flow(self.flow) self.view.update(self.flow)
def get(self, flow_id, message): def get(self, flow_id, message):
message = getattr(self.flow, message) message = getattr(self.flow, message)
@ -329,13 +331,13 @@ class FlowContent(RequestHandler):
original_cd = message.headers.get("Content-Disposition", None) original_cd = message.headers.get("Content-Disposition", None)
filename = None filename = None
if original_cd: if original_cd:
filename = re.search("filename=([\w\" \.\-\(\)]+)", original_cd) filename = re.search('filename=([-\w" .()]+)', original_cd)
if filename: if filename:
filename = filename.group(1) filename = filename.group(1)
if not filename: if not filename:
filename = self.flow.request.path.split("?")[0].split("/")[-1] filename = self.flow.request.path.split("?")[0].split("/")[-1]
filename = re.sub(r"[^\w\" \.\-\(\)]", "", filename) filename = re.sub(r'[^-\w" .()]', "", filename)
cd = "attachment; filename={}".format(filename) cd = "attachment; filename={}".format(filename)
self.set_header("Content-Disposition", cd) self.set_header("Content-Disposition", cd)
self.set_header("Content-Type", "application/text") self.set_header("Content-Type", "application/text")

View File

@ -55,7 +55,7 @@ class Options(options.Options):
wsingleuser: Optional[str] = None, wsingleuser: Optional[str] = None,
whtpasswd: Optional[str] = None, whtpasswd: Optional[str] = None,
**kwargs **kwargs
): ) -> None:
self.wdebug = wdebug self.wdebug = wdebug
self.wport = wport self.wport = wport
self.wiface = wiface self.wiface = wiface

View File

@ -23,4 +23,8 @@ commands =
mitmdump --sysinfo mitmdump --sysinfo
flake8 --jobs 8 --count mitmproxy pathod examples test flake8 --jobs 8 --count mitmproxy pathod examples test
rstcheck README.rst rstcheck README.rst
mypy --silent-imports mitmproxy/addons mitmproxy/addonmanager.py mitmproxy/proxy/protocol/ mypy --silent-imports \
mitmproxy/addons \
mitmproxy/addonmanager.py \
mitmproxy/proxy/protocol/ \
mitmproxy/tools/dump.py mitmproxy/tools/web