aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--.gitignore1
-rw-r--r--mitmproxy/io/__init__.py4
-rw-r--r--mitmproxy/io/db.py9
-rw-r--r--mitmproxy/io/proto/http.proto1
-rw-r--r--mitmproxy/io/proto/http_pb2.py43
-rw-r--r--mitmproxy/io/protobuf.py53
-rw-r--r--setup.cfg2
-rw-r--r--setup.py2
-rwxr-xr-xtest/filename_matching.py3
-rw-r--r--test/mitmproxy/io/test_db.py26
-rw-r--r--test/mitmproxy/io/test_protobuf.py120
11 files changed, 200 insertions, 64 deletions
diff --git a/.gitignore b/.gitignore
index 2ada574a..deb93814 100644
--- a/.gitignore
+++ b/.gitignore
@@ -5,6 +5,7 @@ MANIFEST
*.py[cdo]
*.swp
*.swo
+*.sqlite
*.egg-info/
.coverage*
.idea
diff --git a/mitmproxy/io/__init__.py b/mitmproxy/io/__init__.py
index 854d2505..bd248fd2 100644
--- a/mitmproxy/io/__init__.py
+++ b/mitmproxy/io/__init__.py
@@ -1,8 +1,8 @@
from .io import FlowWriter, FlowReader, FilteredFlowWriter, read_flows_from_paths
-from .db import DbHandler
+from .db import DBHandler
__all__ = [
- "FlowWriter", "FlowReader", "FilteredFlowWriter", "read_flows_from_paths", "DbHandler"
+ "FlowWriter", "FlowReader", "FilteredFlowWriter", "read_flows_from_paths", "DBHandler"
]
diff --git a/mitmproxy/io/db.py b/mitmproxy/io/db.py
index 01d30aa2..ea42e08b 100644
--- a/mitmproxy/io/db.py
+++ b/mitmproxy/io/db.py
@@ -2,17 +2,18 @@ import sqlite3
import os
from mitmproxy.io import protobuf
-from mitmproxy.http import HTTPFlow
-from mitmproxy import exceptions
-class DbHandler:
+class DBHandler:
"""
This class is wrapping up connection to SQLITE DB.
"""
- def __init__(self, db_path="/tmp/tmp.sqlite"):
+ def __init__(self, db_path, mode='load'):
+ if mode == 'write':
+ if os.path.isfile(db_path):
+ os.remove(db_path)
self.db_path = db_path
self._con = sqlite3.connect(self.db_path)
self._c = self._con.cursor()
diff --git a/mitmproxy/io/proto/http.proto b/mitmproxy/io/proto/http.proto
index 6c372433..c86a04f3 100644
--- a/mitmproxy/io/proto/http.proto
+++ b/mitmproxy/io/proto/http.proto
@@ -10,7 +10,6 @@ message HTTPFlow {
optional bool marked = 7;
optional string mode = 8;
optional string id = 9;
- optional int32 version = 10;
}
message HTTPRequest {
diff --git a/mitmproxy/io/proto/http_pb2.py b/mitmproxy/io/proto/http_pb2.py
index 9809e7ee..47b09815 100644
--- a/mitmproxy/io/proto/http_pb2.py
+++ b/mitmproxy/io/proto/http_pb2.py
@@ -19,7 +19,7 @@ DESCRIPTOR = _descriptor.FileDescriptor(
name='http.proto',
package='',
syntax='proto2',
- serialized_pb=_b('\n\nhttp.proto\"\x85\x02\n\x08HTTPFlow\x12\x1d\n\x07request\x18\x01 \x01(\x0b\x32\x0c.HTTPRequest\x12\x1f\n\x08response\x18\x02 \x01(\x0b\x32\r.HTTPResponse\x12\x19\n\x05\x65rror\x18\x03 \x01(\x0b\x32\n.HTTPError\x12&\n\x0b\x63lient_conn\x18\x04 \x01(\x0b\x32\x11.ClientConnection\x12&\n\x0bserver_conn\x18\x05 \x01(\x0b\x32\x11.ServerConnection\x12\x13\n\x0bintercepted\x18\x06 \x01(\x08\x12\x0e\n\x06marked\x18\x07 \x01(\x08\x12\x0c\n\x04mode\x18\x08 \x01(\t\x12\n\n\x02id\x18\t \x01(\t\x12\x0f\n\x07version\x18\n \x01(\x05\"\xfa\x01\n\x0bHTTPRequest\x12\x19\n\x11\x66irst_line_format\x18\x01 \x01(\t\x12\x0e\n\x06method\x18\x02 \x01(\t\x12\x0e\n\x06scheme\x18\x03 \x01(\t\x12\x0c\n\x04host\x18\x04 \x01(\t\x12\x0c\n\x04port\x18\x05 \x01(\x05\x12\x0c\n\x04path\x18\x06 \x01(\t\x12\x14\n\x0chttp_version\x18\x07 \x01(\t\x12\x1c\n\x07headers\x18\x08 \x03(\x0b\x32\x0b.HTTPHeader\x12\x0f\n\x07\x63ontent\x18\t \x01(\x0c\x12\x17\n\x0ftimestamp_start\x18\n \x01(\x01\x12\x15\n\rtimestamp_end\x18\x0b \x01(\x01\x12\x11\n\tis_replay\x18\x0c \x01(\x08\"\xbb\x01\n\x0cHTTPResponse\x12\x14\n\x0chttp_version\x18\x01 \x01(\t\x12\x13\n\x0bstatus_code\x18\x02 \x01(\x05\x12\x0e\n\x06reason\x18\x03 \x01(\t\x12\x1c\n\x07headers\x18\x04 \x03(\x0b\x32\x0b.HTTPHeader\x12\x0f\n\x07\x63ontent\x18\x05 \x01(\x0c\x12\x17\n\x0ftimestamp_start\x18\x06 \x01(\x01\x12\x15\n\rtimestamp_end\x18\x07 \x01(\x01\x12\x11\n\tis_replay\x18\x08 \x01(\x08\"+\n\tHTTPError\x12\x0b\n\x03msg\x18\x01 \x01(\t\x12\x11\n\ttimestamp\x18\x02 \x01(\x01\")\n\nHTTPHeader\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\r\n\x05value\x18\x02 \x01(\t\"%\n\x07\x41\x64\x64ress\x12\x0c\n\x04host\x18\x01 \x01(\t\x12\x0c\n\x04port\x18\x02 \x01(\x05\"\xc2\x02\n\x10\x43lientConnection\x12\n\n\x02id\x18\x01 \x01(\t\x12\x19\n\x07\x61\x64\x64ress\x18\x02 \x01(\x0b\x32\x08.Address\x12\x17\n\x0ftls_established\x18\x03 \x01(\x08\x12\x12\n\nclientcert\x18\x04 \x01(\t\x12\x10\n\x08mitmcert\x18\x05 \x01(\t\x12\x17\n\x0ftimestamp_start\x18\x06 \x01(\x01\x12\x1b\n\x13timestamp_tls_setup\x18\x07 \x01(\x01\x12\x15\n\rtimestamp_end\x18\x08 \x01(\x01\x12\x0b\n\x03sni\x18\t \x01(\t\x12\x13\n\x0b\x63ipher_name\x18\n \x01(\t\x12\x1d\n\x15\x61lpn_proto_negotiated\x18\x0b \x01(\x0c\x12\x13\n\x0btls_version\x18\x0c \x01(\t\x12%\n\x0etls_extensions\x18\r \x03(\x0b\x32\r.TLSExtension\"\xeb\x02\n\x10ServerConnection\x12\n\n\x02id\x18\x01 \x01(\t\x12\x19\n\x07\x61\x64\x64ress\x18\x02 \x01(\x0b\x32\x08.Address\x12\x1c\n\nip_address\x18\x03 \x01(\x0b\x32\x08.Address\x12 \n\x0esource_address\x18\x04 \x01(\x0b\x32\x08.Address\x12\x17\n\x0ftls_established\x18\x05 \x01(\x08\x12\x0c\n\x04\x63\x65rt\x18\x06 \x01(\t\x12\x0b\n\x03sni\x18\x07 \x01(\t\x12\x1d\n\x15\x61lpn_proto_negotiated\x18\x08 \x01(\x0c\x12\x13\n\x0btls_version\x18\t \x01(\t\x12\x17\n\x0ftimestamp_start\x18\n \x01(\x01\x12\x1b\n\x13timestamp_tcp_setup\x18\x0b \x01(\x01\x12\x1b\n\x13timestamp_tls_setup\x18\x0c \x01(\x01\x12\x15\n\rtimestamp_end\x18\r \x01(\x01\x12\x1e\n\x03via\x18\x0e \x01(\x0b\x32\x11.ServerConnection\"*\n\x0cTLSExtension\x12\x0b\n\x03int\x18\x01 \x01(\x03\x12\r\n\x05\x62ytes\x18\x02 \x01(\x0c')
+ serialized_pb=_b('\n\nhttp.proto\"\xf4\x01\n\x08HTTPFlow\x12\x1d\n\x07request\x18\x01 \x01(\x0b\x32\x0c.HTTPRequest\x12\x1f\n\x08response\x18\x02 \x01(\x0b\x32\r.HTTPResponse\x12\x19\n\x05\x65rror\x18\x03 \x01(\x0b\x32\n.HTTPError\x12&\n\x0b\x63lient_conn\x18\x04 \x01(\x0b\x32\x11.ClientConnection\x12&\n\x0bserver_conn\x18\x05 \x01(\x0b\x32\x11.ServerConnection\x12\x13\n\x0bintercepted\x18\x06 \x01(\x08\x12\x0e\n\x06marked\x18\x07 \x01(\x08\x12\x0c\n\x04mode\x18\x08 \x01(\t\x12\n\n\x02id\x18\t \x01(\t\"\xfa\x01\n\x0bHTTPRequest\x12\x19\n\x11\x66irst_line_format\x18\x01 \x01(\t\x12\x0e\n\x06method\x18\x02 \x01(\t\x12\x0e\n\x06scheme\x18\x03 \x01(\t\x12\x0c\n\x04host\x18\x04 \x01(\t\x12\x0c\n\x04port\x18\x05 \x01(\x05\x12\x0c\n\x04path\x18\x06 \x01(\t\x12\x14\n\x0chttp_version\x18\x07 \x01(\t\x12\x1c\n\x07headers\x18\x08 \x03(\x0b\x32\x0b.HTTPHeader\x12\x0f\n\x07\x63ontent\x18\t \x01(\x0c\x12\x17\n\x0ftimestamp_start\x18\n \x01(\x01\x12\x15\n\rtimestamp_end\x18\x0b \x01(\x01\x12\x11\n\tis_replay\x18\x0c \x01(\x08\"\xbb\x01\n\x0cHTTPResponse\x12\x14\n\x0chttp_version\x18\x01 \x01(\t\x12\x13\n\x0bstatus_code\x18\x02 \x01(\x05\x12\x0e\n\x06reason\x18\x03 \x01(\t\x12\x1c\n\x07headers\x18\x04 \x03(\x0b\x32\x0b.HTTPHeader\x12\x0f\n\x07\x63ontent\x18\x05 \x01(\x0c\x12\x17\n\x0ftimestamp_start\x18\x06 \x01(\x01\x12\x15\n\rtimestamp_end\x18\x07 \x01(\x01\x12\x11\n\tis_replay\x18\x08 \x01(\x08\"+\n\tHTTPError\x12\x0b\n\x03msg\x18\x01 \x01(\t\x12\x11\n\ttimestamp\x18\x02 \x01(\x01\")\n\nHTTPHeader\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\r\n\x05value\x18\x02 \x01(\t\"%\n\x07\x41\x64\x64ress\x12\x0c\n\x04host\x18\x01 \x01(\t\x12\x0c\n\x04port\x18\x02 \x01(\x05\"\xc2\x02\n\x10\x43lientConnection\x12\n\n\x02id\x18\x01 \x01(\t\x12\x19\n\x07\x61\x64\x64ress\x18\x02 \x01(\x0b\x32\x08.Address\x12\x17\n\x0ftls_established\x18\x03 \x01(\x08\x12\x12\n\nclientcert\x18\x04 \x01(\t\x12\x10\n\x08mitmcert\x18\x05 \x01(\t\x12\x17\n\x0ftimestamp_start\x18\x06 \x01(\x01\x12\x1b\n\x13timestamp_tls_setup\x18\x07 \x01(\x01\x12\x15\n\rtimestamp_end\x18\x08 \x01(\x01\x12\x0b\n\x03sni\x18\t \x01(\t\x12\x13\n\x0b\x63ipher_name\x18\n \x01(\t\x12\x1d\n\x15\x61lpn_proto_negotiated\x18\x0b \x01(\x0c\x12\x13\n\x0btls_version\x18\x0c \x01(\t\x12%\n\x0etls_extensions\x18\r \x03(\x0b\x32\r.TLSExtension\"\xeb\x02\n\x10ServerConnection\x12\n\n\x02id\x18\x01 \x01(\t\x12\x19\n\x07\x61\x64\x64ress\x18\x02 \x01(\x0b\x32\x08.Address\x12\x1c\n\nip_address\x18\x03 \x01(\x0b\x32\x08.Address\x12 \n\x0esource_address\x18\x04 \x01(\x0b\x32\x08.Address\x12\x17\n\x0ftls_established\x18\x05 \x01(\x08\x12\x0c\n\x04\x63\x65rt\x18\x06 \x01(\t\x12\x0b\n\x03sni\x18\x07 \x01(\t\x12\x1d\n\x15\x61lpn_proto_negotiated\x18\x08 \x01(\x0c\x12\x13\n\x0btls_version\x18\t \x01(\t\x12\x17\n\x0ftimestamp_start\x18\n \x01(\x01\x12\x1b\n\x13timestamp_tcp_setup\x18\x0b \x01(\x01\x12\x1b\n\x13timestamp_tls_setup\x18\x0c \x01(\x01\x12\x15\n\rtimestamp_end\x18\r \x01(\x01\x12\x1e\n\x03via\x18\x0e \x01(\x0b\x32\x11.ServerConnection\"*\n\x0cTLSExtension\x12\x0b\n\x03int\x18\x01 \x01(\x03\x12\r\n\x05\x62ytes\x18\x02 \x01(\x0c')
)
@@ -95,13 +95,6 @@ _HTTPFLOW = _descriptor.Descriptor(
message_type=None, enum_type=None, containing_type=None,
is_extension=False, extension_scope=None,
options=None, file=DESCRIPTOR),
- _descriptor.FieldDescriptor(
- name='version', full_name='HTTPFlow.version', index=9,
- number=10, type=5, cpp_type=1, label=1,
- has_default_value=False, default_value=0,
- message_type=None, enum_type=None, containing_type=None,
- is_extension=False, extension_scope=None,
- options=None, file=DESCRIPTOR),
],
extensions=[
],
@@ -115,7 +108,7 @@ _HTTPFLOW = _descriptor.Descriptor(
oneofs=[
],
serialized_start=15,
- serialized_end=276,
+ serialized_end=259,
)
@@ -222,8 +215,8 @@ _HTTPREQUEST = _descriptor.Descriptor(
extension_ranges=[],
oneofs=[
],
- serialized_start=279,
- serialized_end=529,
+ serialized_start=262,
+ serialized_end=512,
)
@@ -302,8 +295,8 @@ _HTTPRESPONSE = _descriptor.Descriptor(
extension_ranges=[],
oneofs=[
],
- serialized_start=532,
- serialized_end=719,
+ serialized_start=515,
+ serialized_end=702,
)
@@ -340,8 +333,8 @@ _HTTPERROR = _descriptor.Descriptor(
extension_ranges=[],
oneofs=[
],
- serialized_start=721,
- serialized_end=764,
+ serialized_start=704,
+ serialized_end=747,
)
@@ -378,8 +371,8 @@ _HTTPHEADER = _descriptor.Descriptor(
extension_ranges=[],
oneofs=[
],
- serialized_start=766,
- serialized_end=807,
+ serialized_start=749,
+ serialized_end=790,
)
@@ -416,8 +409,8 @@ _ADDRESS = _descriptor.Descriptor(
extension_ranges=[],
oneofs=[
],
- serialized_start=809,
- serialized_end=846,
+ serialized_start=792,
+ serialized_end=829,
)
@@ -531,8 +524,8 @@ _CLIENTCONNECTION = _descriptor.Descriptor(
extension_ranges=[],
oneofs=[
],
- serialized_start=849,
- serialized_end=1171,
+ serialized_start=832,
+ serialized_end=1154,
)
@@ -653,8 +646,8 @@ _SERVERCONNECTION = _descriptor.Descriptor(
extension_ranges=[],
oneofs=[
],
- serialized_start=1174,
- serialized_end=1537,
+ serialized_start=1157,
+ serialized_end=1520,
)
@@ -691,8 +684,8 @@ _TLSEXTENSION = _descriptor.Descriptor(
extension_ranges=[],
oneofs=[
],
- serialized_start=1539,
- serialized_end=1581,
+ serialized_start=1522,
+ serialized_end=1564,
)
_HTTPFLOW.fields_by_name['request'].message_type = _HTTPREQUEST
diff --git a/mitmproxy/io/protobuf.py b/mitmproxy/io/protobuf.py
index 3db9a013..9a00eacf 100644
--- a/mitmproxy/io/protobuf.py
+++ b/mitmproxy/io/protobuf.py
@@ -2,7 +2,6 @@ import typing
from mitmproxy import flow
from mitmproxy import exceptions
-from mitmproxy import ctx
from mitmproxy.http import HTTPFlow, HTTPResponse, HTTPRequest
from mitmproxy.certs import Cert
from mitmproxy.connections import ClientConnection, ServerConnection
@@ -16,7 +15,8 @@ def _move_attrs(s_obj, d_obj, attrs):
setattr(d_obj, attr, getattr(s_obj, attr))
else:
if hasattr(s_obj, attr) and getattr(s_obj, attr) is not None:
- if not getattr(s_obj, attr):
+ # ugly fix to set None in empty str or bytes fields
+ if getattr(s_obj, attr) == "" or getattr(s_obj, attr) == b"":
d_obj[attr] = None
else:
d_obj[attr] = getattr(s_obj, attr)
@@ -87,12 +87,12 @@ def _dump_http_error(e: flow.Error) -> http_pb2.HTTPError:
return pe
-def dump_http(f: HTTPFlow) -> http_pb2.HTTPFlow():
+def dump_http(f: flow.Flow) -> http_pb2.HTTPFlow:
pf = http_pb2.HTTPFlow()
for p in ['request', 'response', 'client_conn', 'server_conn', 'error']:
- if hasattr(f, p):
+ if hasattr(f, p) and getattr(f, p):
getattr(pf, p).MergeFrom(eval(f"_dump_http_{p}")(getattr(f, p)))
- _move_attrs(f, pf, ['intercepted', 'marked', 'mode', 'id', 'version'])
+ _move_attrs(f, pf, ['intercepted', 'marked', 'mode', 'id'])
return pf
@@ -105,9 +105,9 @@ def dumps(f: flow.Flow) -> bytes:
def _load_http_request(o: http_pb2.HTTPRequest) -> HTTPRequest:
- d = {}
+ d: dict = {}
_move_attrs(o, d, ['first_line_format', 'method', 'scheme', 'host', 'port', 'path', 'http_version', 'content',
- 'timestamp_start', 'timestamp_end', 'is_replay'])
+ 'timestamp_start', 'timestamp_end', 'is_replay'])
if d['content'] is None:
d['content'] = b""
d["headers"] = []
@@ -118,9 +118,9 @@ def _load_http_request(o: http_pb2.HTTPRequest) -> HTTPRequest:
def _load_http_response(o: http_pb2.HTTPResponse) -> HTTPResponse:
- d = {}
+ d: dict = {}
_move_attrs(o, d, ['http_version', 'status_code', 'reason',
- 'content', 'timestamp_start', 'timestamp_end', 'is_replay'])
+ 'content', 'timestamp_start', 'timestamp_end', 'is_replay'])
if d['content'] is None:
d['content'] = b""
d["headers"] = []
@@ -131,14 +131,12 @@ def _load_http_response(o: http_pb2.HTTPResponse) -> HTTPResponse:
def _load_http_client_conn(o: http_pb2.ClientConnection) -> ClientConnection:
- d = {}
- _move_attrs(o, d, ['id', 'tls_established', 'sni', 'alpn_proto_negotiated', 'tls_version',
- 'timestamp_start', 'timestamp_tcp_setup', 'timestamp_tls_setup', 'timestamp_end'])
+ d: dict = {}
+ _move_attrs(o, d, ['id', 'tls_established', 'sni', 'cipher_name', 'alpn_proto_negotiated', 'tls_version',
+ 'timestamp_start', 'timestamp_tcp_setup', 'timestamp_tls_setup', 'timestamp_end'])
for cert in ['clientcert', 'mitmcert']:
if hasattr(o, cert) and getattr(o, cert):
- c = Cert("")
- c.from_pem(getattr(o, cert))
- d[cert] = c
+ d[cert] = Cert.from_pem(getattr(o, cert))
if o.tls_extensions:
d['tls_extensions'] = []
for extension in o.tls_extensions:
@@ -152,18 +150,17 @@ def _load_http_client_conn(o: http_pb2.ClientConnection) -> ClientConnection:
def _load_http_server_conn(o: http_pb2.ServerConnection) -> ServerConnection:
- d = {}
+ d: dict = {}
_move_attrs(o, d, ['id', 'tls_established', 'sni', 'alpn_proto_negotiated', 'tls_version',
- 'timestamp_start', 'timestamp_tcp_setup', 'timestamp_tls_setup', 'timestamp_end'])
+ 'timestamp_start', 'timestamp_tcp_setup', 'timestamp_tls_setup', 'timestamp_end'])
for addr in ['address', 'ip_address', 'source_address']:
if hasattr(o, addr):
d[addr] = (getattr(o, addr).host, getattr(o, addr).port)
if o.cert:
- c = Cert("")
- c.from_pem(o.cert)
+ c = Cert.from_pem(o.cert)
d['cert'] = c
- if len(o.via.id):
- d['via'] = _load_http_server_conn(d['via'])
+ if o.HasField('via'):
+ d['via'] = _load_http_server_conn(o.via)
sc = ServerConnection(tuple())
for k, v in d.items():
setattr(sc, k, v)
@@ -181,9 +178,11 @@ def _load_http_error(o: http_pb2.HTTPError) -> typing.Optional[flow.Error]:
def load_http(hf: http_pb2.HTTPFlow) -> HTTPFlow:
parts = {}
for p in ['request', 'response', 'client_conn', 'server_conn', 'error']:
- if hasattr(hf, p) and getattr(hf, p):
+ if hf.HasField(p):
parts[p] = eval(f"_load_http_{p}")(getattr(hf, p))
- _move_attrs(hf, parts, ['intercepted', 'marked', 'mode', 'id', 'version'])
+ else:
+ parts[p] = None
+ _move_attrs(hf, parts, ['intercepted', 'marked', 'mode', 'id'])
f = HTTPFlow(ClientConnection(None, tuple(), None), ServerConnection(tuple()))
for k, v in parts.items():
setattr(f, k, v)
@@ -195,9 +194,5 @@ def loads(b: bytes, typ="http") -> flow.Flow:
raise exceptions.TypeError("Flow types different than HTTP not supported yet!")
else:
p = http_pb2.HTTPFlow()
- try:
- p.ParseFromString(b)
- return load_http(p)
- except Exception as e:
- ctx.log(str(e))
-
+ p.ParseFromString(b)
+ return load_http(p)
diff --git a/setup.cfg b/setup.cfg
index 32b6aac3..173166d1 100644
--- a/setup.cfg
+++ b/setup.cfg
@@ -2,7 +2,7 @@
max-line-length = 140
max-complexity = 25
ignore = E251,C901,W503,W292,E722,E741
-exclude = mitmproxy/contrib/*,test/mitmproxy/data/*,release/build/*
+exclude = mitmproxy/contrib/*,test/mitmproxy/data/*,release/build/*,mitmproxy/io/proto/*
addons = file,open,basestring,xrange,unicode,long,cmp
[tool:pytest]
diff --git a/setup.py b/setup.py
index acd3f295..954327e9 100644
--- a/setup.py
+++ b/setup.py
@@ -70,11 +70,11 @@ setup(
"kaitaistruct>=0.7,<0.9",
"ldap3>=2.5,<2.6",
"passlib>=1.6.5, <1.8",
+ "protobuf>=3.6.0, <3.7",
"pyasn1>=0.3.1,<0.5",
"pyOpenSSL>=17.5,<18.1",
"pyparsing>=2.1.3, <2.3",
"pyperclip>=1.6.0, <1.7",
- "protobuf>=3.6.0, <3.7",
"ruamel.yaml>=0.13.2, <0.16",
"sortedcontainers>=1.5.4,<2.1",
"tornado>=4.3,<5.1",
diff --git a/test/filename_matching.py b/test/filename_matching.py
index 5f49725e..f5321307 100755
--- a/test/filename_matching.py
+++ b/test/filename_matching.py
@@ -9,7 +9,8 @@ import sys
def check_src_files_have_test():
missing_test_files = []
- excluded = ['mitmproxy/contrib/', 'mitmproxy/test/', 'mitmproxy/tools/', 'mitmproxy/platform/']
+ excluded = ['mitmproxy/contrib/', 'mitmproxy/io/proto/',
+ 'mitmproxy/test/', 'mitmproxy/tools/', 'mitmproxy/platform/']
src_files = glob.glob('mitmproxy/**/*.py', recursive=True) + glob.glob('pathod/**/*.py', recursive=True)
src_files = [f for f in src_files if os.path.basename(f) != '__init__.py']
src_files = [f for f in src_files if not any(os.path.normpath(p) in f for p in excluded)]
diff --git a/test/mitmproxy/io/test_db.py b/test/mitmproxy/io/test_db.py
new file mode 100644
index 00000000..4a2dfb67
--- /dev/null
+++ b/test/mitmproxy/io/test_db.py
@@ -0,0 +1,26 @@
+from mitmproxy.io import db
+from mitmproxy.test import tflow
+
+
+class TestDB:
+
+ def test_create(self, tdata):
+ dh = db.DBHandler(db_path=tdata.path("mitmproxy/data") + "/tmp.sqlite")
+ with dh._con as c:
+ cur = c.cursor()
+ cur.execute("SELECT name FROM sqlite_master WHERE type='table' AND name='FLOWS';")
+ assert cur.fetchall() == [('FLOWS',)]
+
+ def test_roundtrip(self, tdata):
+ dh = db.DBHandler(db_path=tdata.path("mitmproxy/data") + "/tmp.sqlite", mode='write')
+ flows = []
+ for i in range(10):
+ flows.append(tflow.tflow())
+ dh.store(flows)
+ dh = db.DBHandler(db_path=tdata.path("mitmproxy/data") + "/tmp.sqlite")
+ with dh._con as c:
+ cur = c.cursor()
+ cur.execute("SELECT count(*) FROM FLOWS;")
+ assert cur.fetchall()[0][0] == 10
+ loaded_flows = dh.load()
+ assert len(loaded_flows) == len(flows)
diff --git a/test/mitmproxy/io/test_protobuf.py b/test/mitmproxy/io/test_protobuf.py
new file mode 100644
index 00000000..f725b980
--- /dev/null
+++ b/test/mitmproxy/io/test_protobuf.py
@@ -0,0 +1,120 @@
+import pytest
+
+from mitmproxy import certs
+from mitmproxy import http
+from mitmproxy import exceptions
+from mitmproxy.test import tflow, tutils
+from mitmproxy.io import protobuf
+
+
+class TestProtobuf:
+
+ def test_roundtrip_client(self):
+ c = tflow.tclient_conn()
+ del c.reply
+ c.rfile = None
+ c.wfile = None
+ pc = protobuf._dump_http_client_conn(c)
+ lc = protobuf._load_http_client_conn(pc)
+ assert c.__dict__ == lc.__dict__
+
+ def test_roundtrip_client_cert(self, tdata):
+ c = tflow.tclient_conn()
+ c.rfile = None
+ c.wfile = None
+ del c.reply
+ with open(tdata.path("mitmproxy/net/data/clientcert/client.pem"), "rb") as f:
+ d = f.read()
+ c.clientcert = certs.Cert.from_pem(d)
+ pc = protobuf._dump_http_client_conn(c)
+ lc = protobuf._load_http_client_conn(pc)
+ assert c.__dict__ == lc.__dict__
+
+ def test_roundtrip_server(self):
+ s = tflow.tserver_conn()
+ del s.reply
+ s.wfile = None
+ s.rfile = None
+ ps = protobuf._dump_http_server_conn(s)
+ ls = protobuf._load_http_server_conn(ps)
+ assert s.__dict__ == ls.__dict__
+
+ def test_roundtrip_server_cert(self, tdata):
+ s = tflow.tserver_conn()
+ del s.reply
+ s.wfile = None
+ s.rfile = None
+ with open(tdata.path("mitmproxy/net/data/text_cert"), "rb") as f:
+ d = f.read()
+ s.cert = certs.Cert.from_pem(d)
+ ps = protobuf._dump_http_server_conn(s)
+ ls = protobuf._load_http_server_conn(ps)
+ assert s.__dict__ == ls.__dict__
+
+ def test_roundtrip_server_via(self):
+ s = tflow.tserver_conn()
+ s.via = tflow.tserver_conn()
+ del s.reply
+ s.wfile = None
+ s.rfile = None
+ ps = protobuf._dump_http_server_conn(s)
+ ls = protobuf._load_http_server_conn(ps)
+ assert s.__dict__ == ls.__dict__
+ del s.via.reply
+ s.via.wfile = None
+ s.via.rfile = None
+ assert s.via.__dict__ == ls.via.__dict__
+
+ def test_roundtrip_http_request(self):
+ req = http.HTTPRequest.wrap(tutils.treq())
+ preq = protobuf._dump_http_request(req)
+ lreq = protobuf._load_http_request(preq)
+ assert req.__dict__ == lreq.__dict__
+
+ def test_roundtrip_http_request_empty_content(self):
+ req = http.HTTPRequest.wrap(tutils.treq(content=b""))
+ preq = protobuf._dump_http_request(req)
+ lreq = protobuf._load_http_request(preq)
+ assert req.__dict__ == lreq.__dict__
+
+ def test_roundtrip_http_response(self):
+ res = http.HTTPResponse.wrap(tutils.tresp())
+ pres = protobuf._dump_http_response(res)
+ lres = protobuf._load_http_response(pres)
+ assert res.__dict__ == lres.__dict__
+
+ def test_roundtrip_http_response_empty_content(self):
+ res = http.HTTPResponse.wrap(tutils.tresp(content=b""))
+ pres = protobuf._dump_http_response(res)
+ lres = protobuf._load_http_response(pres)
+ assert res.__dict__ == lres.__dict__
+
+ def test_roundtrip_http_error(self):
+ err = tflow.terr()
+ perr = protobuf._dump_http_error(err)
+ lerr = protobuf._load_http_error(perr)
+ assert err.__dict__ == lerr.__dict__
+
+ def test_roundtrip_http_flow_only_req(self):
+ f = tflow.tflow()
+ f.reply = None
+ pf = protobuf.dumps(f)
+ lf = protobuf.loads(pf, "http")
+ assert f.__dict__ == lf.__dict__
+
+ def test_roundtrip_http_flow_res(self):
+ f = tflow.tflow(resp=True)
+ f.reply = None
+ pf = protobuf.dumps(f)
+ lf = protobuf.loads(pf, "http")
+ assert f.__dict__ == lf.__dict__
+
+ def test_unsupported_dumps(self):
+ w = tflow.twebsocketflow()
+ with pytest.raises(exceptions.TypeError):
+ protobuf.dumps(w)
+
+ def test_unsupported_loads(self):
+ b = b"blobs"
+ with pytest.raises(exceptions.TypeError):
+ protobuf.loads(b, 'not-http')