aboutsummaryrefslogtreecommitdiffstats
path: root/examples
diff options
context:
space:
mode:
Diffstat (limited to 'examples')
-rw-r--r--examples/complex/README.md2
-rw-r--r--examples/complex/dns_spoofing.py3
-rw-r--r--examples/complex/har_dump.py43
-rw-r--r--examples/complex/remote_debug.py2
-rw-r--r--examples/complex/tls_passthrough.py14
-rw-r--r--examples/simple/add_header.py5
-rw-r--r--examples/simple/add_header_class.py8
-rw-r--r--examples/simple/custom_contentview.py8
-rw-r--r--examples/simple/custom_option.py8
-rw-r--r--examples/simple/filter_flows.py23
-rw-r--r--examples/simple/io_read_dumpfile.py4
-rw-r--r--examples/simple/io_write_dumpfile.py14
-rw-r--r--examples/simple/log_events.py2
-rw-r--r--examples/simple/modify_body_inject_iframe.py39
-rw-r--r--examples/simple/modify_form.py5
-rw-r--r--examples/simple/modify_querystring.py5
-rw-r--r--examples/simple/redirect_requests.py3
-rw-r--r--examples/simple/script_arguments.py17
-rw-r--r--examples/simple/send_reply_from_proxy.py2
-rw-r--r--examples/simple/upsidedownternet.py4
-rw-r--r--examples/simple/wsgi_flask_app.py8
21 files changed, 109 insertions, 110 deletions
diff --git a/examples/complex/README.md b/examples/complex/README.md
index 452f2395..77dbe2f5 100644
--- a/examples/complex/README.md
+++ b/examples/complex/README.md
@@ -5,7 +5,6 @@
| change_upstream_proxy.py | Dynamically change the upstream proxy. |
| dns_spoofing.py | Use mitmproxy in a DNS spoofing scenario. |
| dup_and_replay.py | Duplicates each request, changes it, and then replays the modified request. |
-| flowbasic.py | Basic use of mitmproxy's FlowMaster directly. |
| full_transparency_shim.c | Setuid wrapper that can be used to run mitmproxy in full transparency mode, as a normal user. |
| har_dump.py | Dump flows as HAR files. |
| mitmproxywrapper.py | Bracket mitmproxy run with proxy enable/disable on OS X |
@@ -16,3 +15,4 @@
| stream_modify.py | Modify a streamed response body. |
| tcp_message.py | Modify a raw TCP connection |
| tls_passthrough.py | Use conditional TLS interception based on a user-defined strategy. |
+| xss_scanner.py | Scan all visited webpages. |
diff --git a/examples/complex/dns_spoofing.py b/examples/complex/dns_spoofing.py
index ca2bcd35..632783a7 100644
--- a/examples/complex/dns_spoofing.py
+++ b/examples/complex/dns_spoofing.py
@@ -54,5 +54,4 @@ class Rerouter:
flow.request.port = port
-def start(opts):
- return Rerouter()
+addons = [Rerouter()]
diff --git a/examples/complex/har_dump.py b/examples/complex/har_dump.py
index 9a86e45e..21bcc341 100644
--- a/examples/complex/har_dump.py
+++ b/examples/complex/har_dump.py
@@ -4,7 +4,6 @@ This inline script can be used to dump flows as HAR files.
import json
-import sys
import base64
import zlib
import os
@@ -15,6 +14,7 @@ from datetime import timezone
import mitmproxy
from mitmproxy import version
+from mitmproxy import ctx
from mitmproxy.utils import strutils
from mitmproxy.net.http import cookies
@@ -25,17 +25,13 @@ HAR = {}
SERVERS_SEEN = set()
-def start(opts):
- """
- Called once on script startup before any other events.
- """
- if len(sys.argv) != 2:
- raise ValueError(
- 'Usage: -s "har_dump.py filename" '
- '(- will output to stdout, filenames ending with .zhar '
- 'will result in compressed har)'
- )
+def load(l):
+ l.add_option(
+ "hardump", str, "", "HAR dump path.",
+ )
+
+def configure(updated):
HAR.update({
"log": {
"version": "1.2",
@@ -156,21 +152,20 @@ def done():
"""
Called once on script shutdown, after any other events.
"""
- dump_file = sys.argv[1]
+ if ctx.options.hardump:
+ json_dump = json.dumps(HAR, indent=2) # type: str
- json_dump = json.dumps(HAR, indent=2) # type: str
-
- if dump_file == '-':
- mitmproxy.ctx.log(json_dump)
- else:
- raw = json_dump.encode() # type: bytes
- if dump_file.endswith('.zhar'):
- raw = zlib.compress(raw, 9)
+ if ctx.options.hardump == '-':
+ mitmproxy.ctx.log(json_dump)
+ else:
+ raw = json_dump.encode() # type: bytes
+ if ctx.options.hardump.endswith('.zhar'):
+ raw = zlib.compress(raw, 9)
- with open(os.path.expanduser(dump_file), "wb") as f:
- f.write(raw)
+ with open(os.path.expanduser(ctx.options.hardump), "wb") as f:
+ f.write(raw)
- mitmproxy.ctx.log("HAR dump finished (wrote %s bytes to file)" % len(json_dump))
+ mitmproxy.ctx.log("HAR dump finished (wrote %s bytes to file)" % len(json_dump))
def format_cookies(cookie_list):
@@ -206,7 +201,7 @@ def format_request_cookies(fields):
def format_response_cookies(fields):
- return format_cookies((c[0], c[1].value, c[1].attrs) for c in fields)
+ return format_cookies((c[0], c[1][0], c[1][1]) for c in fields)
def name_value(obj):
diff --git a/examples/complex/remote_debug.py b/examples/complex/remote_debug.py
index ae0dffc1..fa6f3d33 100644
--- a/examples/complex/remote_debug.py
+++ b/examples/complex/remote_debug.py
@@ -14,6 +14,6 @@ Usage:
"""
-def start(opts):
+def load(l):
import pydevd
pydevd.settrace("localhost", port=5678, stdoutToServer=True, stderrToServer=True)
diff --git a/examples/complex/tls_passthrough.py b/examples/complex/tls_passthrough.py
index 6dba7ca1..9bb27d25 100644
--- a/examples/complex/tls_passthrough.py
+++ b/examples/complex/tls_passthrough.py
@@ -23,10 +23,10 @@ Authors: Maximilian Hils, Matthew Tuusberg
import collections
import random
-import sys
from enum import Enum
import mitmproxy
+from mitmproxy import ctx
from mitmproxy.exceptions import TlsProtocolException
from mitmproxy.proxy.protocol import TlsLayer, RawTCPLayer
@@ -112,10 +112,16 @@ class TlsFeedback(TlsLayer):
tls_strategy = None
-def start(opts):
+def load(l):
+ l.add_option(
+ "tlsstrat", int, 0, "TLS passthrough strategy (0-100)",
+ )
+
+
+def configure(updated):
global tls_strategy
- if len(sys.argv) == 2:
- tls_strategy = ProbabilisticStrategy(float(sys.argv[1]))
+ if ctx.options.tlsstrat > 0:
+ tls_strategy = ProbabilisticStrategy(float(ctx.options.tlsstrat) / 100.0)
else:
tls_strategy = ConservativeStrategy()
diff --git a/examples/simple/add_header.py b/examples/simple/add_header.py
index 3e0b5f1e..64fc6267 100644
--- a/examples/simple/add_header.py
+++ b/examples/simple/add_header.py
@@ -1,2 +1,5 @@
-def response(flow):
+from mitmproxy import http
+
+
+def response(flow: http.HTTPFlow) -> None:
flow.response.headers["newheader"] = "foo"
diff --git a/examples/simple/add_header_class.py b/examples/simple/add_header_class.py
index 9270be09..419c99ac 100644
--- a/examples/simple/add_header_class.py
+++ b/examples/simple/add_header_class.py
@@ -1,7 +1,9 @@
+from mitmproxy import http
+
+
class AddHeader:
- def response(self, flow):
+ def response(self, flow: http.HTTPFlow) -> None:
flow.response.headers["newheader"] = "foo"
-def start(opts):
- return AddHeader()
+addons = [AddHeader()]
diff --git a/examples/simple/custom_contentview.py b/examples/simple/custom_contentview.py
index 4bc17af0..71f92575 100644
--- a/examples/simple/custom_contentview.py
+++ b/examples/simple/custom_contentview.py
@@ -3,6 +3,10 @@ This example shows how one can add a custom contentview to mitmproxy.
The content view API is explained in the mitmproxy.contentviews module.
"""
from mitmproxy import contentviews
+import typing
+
+
+CVIEWSWAPCASE = typing.Tuple[str, typing.Iterable[typing.List[typing.Tuple[str, typing.AnyStr]]]]
class ViewSwapCase(contentviews.View):
@@ -13,14 +17,14 @@ class ViewSwapCase(contentviews.View):
prompt = ("swap case text", "z")
content_types = ["text/plain"]
- def __call__(self, data: bytes, **metadata):
+ def __call__(self, data: typing.AnyStr, **metadata) -> CVIEWSWAPCASE:
return "case-swapped text", contentviews.format_text(data.swapcase())
view = ViewSwapCase()
-def start(opts):
+def load(l):
contentviews.add(view)
diff --git a/examples/simple/custom_option.py b/examples/simple/custom_option.py
index 324d27e7..5b6070dd 100644
--- a/examples/simple/custom_option.py
+++ b/examples/simple/custom_option.py
@@ -1,11 +1,11 @@
from mitmproxy import ctx
-def start(options):
+def load(l):
ctx.log.info("Registering option 'custom'")
- options.add_option("custom", bool, False, "A custom option")
+ l.add_option("custom", bool, False, "A custom option")
-def configure(options, updated):
+def configure(updated):
if "custom" in updated:
- ctx.log.info("custom option value: %s" % options.custom)
+ ctx.log.info("custom option value: %s" % ctx.options.custom)
diff --git a/examples/simple/filter_flows.py b/examples/simple/filter_flows.py
index 24e8b6c1..70979591 100644
--- a/examples/simple/filter_flows.py
+++ b/examples/simple/filter_flows.py
@@ -1,23 +1,26 @@
"""
This scripts demonstrates how to use mitmproxy's filter pattern in scripts.
-Usage:
- mitmdump -s "flowfilter.py FILTER"
"""
-import sys
from mitmproxy import flowfilter
+from mitmproxy import ctx, http
class Filter:
- def __init__(self, spec):
- self.filter = flowfilter.parse(spec)
+ def __init__(self):
+ self.filter = None # type: flowfilter.TFilter
- def response(self, flow):
+ def configure(self, updated):
+ self.filter = flowfilter.parse(ctx.options.flowfilter)
+
+ def load(self, l):
+ l.add_option(
+ "flowfilter", str, "", "Check that flow matches filter."
+ )
+
+ def response(self, flow: http.HTTPFlow) -> None:
if flowfilter.match(self.filter, flow):
print("Flow matches filter:")
print(flow)
-def start(opts):
- if len(sys.argv) != 2:
- raise ValueError("Usage: -s 'filt.py FILTER'")
- return Filter(sys.argv[1])
+addons = [Filter()]
diff --git a/examples/simple/io_read_dumpfile.py b/examples/simple/io_read_dumpfile.py
index edbbe2dd..ea544cc4 100644
--- a/examples/simple/io_read_dumpfile.py
+++ b/examples/simple/io_read_dumpfile.py
@@ -1,13 +1,15 @@
#!/usr/bin/env python
+
+# type: ignore
#
# Simple script showing how to read a mitmproxy dump file
#
-
from mitmproxy import io
from mitmproxy.exceptions import FlowReadException
import pprint
import sys
+
with open(sys.argv[1], "rb") as logfile:
freader = io.FlowReader(logfile)
pp = pprint.PrettyPrinter(indent=4)
diff --git a/examples/simple/io_write_dumpfile.py b/examples/simple/io_write_dumpfile.py
index 311950af..cf7c4f52 100644
--- a/examples/simple/io_write_dumpfile.py
+++ b/examples/simple/io_write_dumpfile.py
@@ -7,23 +7,21 @@ to multiple files in parallel.
"""
import random
import sys
-from mitmproxy import io
+from mitmproxy import io, http
+import typing # noqa
class Writer:
- def __init__(self, path):
+ def __init__(self, path: str) -> None:
if path == "-":
- f = sys.stdout
+ f = sys.stdout # type: typing.IO[typing.Any]
else:
f = open(path, "wb")
self.w = io.FlowWriter(f)
- def response(self, flow):
+ def response(self, flow: http.HTTPFlow) -> None:
if random.choice([True, False]):
self.w.add(flow)
-def start(opts):
- if len(sys.argv) != 2:
- raise ValueError('Usage: -s "flowriter.py filename"')
- return Writer(sys.argv[1])
+addons = [Writer(sys.argv[1])]
diff --git a/examples/simple/log_events.py b/examples/simple/log_events.py
index a81892aa..581b99f3 100644
--- a/examples/simple/log_events.py
+++ b/examples/simple/log_events.py
@@ -7,6 +7,6 @@ If you want to help us out: https://github.com/mitmproxy/mitmproxy/issues/1530 :
from mitmproxy import ctx
-def start(opts):
+def load(l):
ctx.log.info("This is some informative text.")
ctx.log.error("This is an error.")
diff --git a/examples/simple/modify_body_inject_iframe.py b/examples/simple/modify_body_inject_iframe.py
index ab5abf27..595bd9f2 100644
--- a/examples/simple/modify_body_inject_iframe.py
+++ b/examples/simple/modify_body_inject_iframe.py
@@ -1,29 +1,26 @@
-# Usage: mitmdump -s "iframe_injector.py url"
# (this script works best with --anticache)
-import sys
from bs4 import BeautifulSoup
+from mitmproxy import ctx, http
class Injector:
- def __init__(self, iframe_url):
- self.iframe_url = iframe_url
+ def load(self, loader):
+ loader.add_option(
+ "iframe", str, "", "IFrame to inject"
+ )
- def response(self, flow):
- if flow.request.host in self.iframe_url:
- return
- html = BeautifulSoup(flow.response.content, "html.parser")
- if html.body:
- iframe = html.new_tag(
- "iframe",
- src=self.iframe_url,
- frameborder=0,
- height=0,
- width=0)
- html.body.insert(0, iframe)
- flow.response.content = str(html).encode("utf8")
+ def response(self, flow: http.HTTPFlow) -> None:
+ if ctx.options.iframe:
+ html = BeautifulSoup(flow.response.content, "html.parser")
+ if html.body:
+ iframe = html.new_tag(
+ "iframe",
+ src=ctx.options.iframe,
+ frameborder=0,
+ height=0,
+ width=0)
+ html.body.insert(0, iframe)
+ flow.response.content = str(html).encode("utf8")
-def start(opts):
- if len(sys.argv) != 2:
- raise ValueError('Usage: -s "iframe_injector.py url"')
- return Injector(sys.argv[1])
+addons = [Injector()]
diff --git a/examples/simple/modify_form.py b/examples/simple/modify_form.py
index b425efb0..8742a976 100644
--- a/examples/simple/modify_form.py
+++ b/examples/simple/modify_form.py
@@ -1,4 +1,7 @@
-def request(flow):
+from mitmproxy import http
+
+
+def request(flow: http.HTTPFlow) -> None:
if flow.request.urlencoded_form:
# If there's already a form, one can just add items to the dict:
flow.request.urlencoded_form["mitmproxy"] = "rocks"
diff --git a/examples/simple/modify_querystring.py b/examples/simple/modify_querystring.py
index ee8a89ad..12b16fda 100644
--- a/examples/simple/modify_querystring.py
+++ b/examples/simple/modify_querystring.py
@@ -1,2 +1,5 @@
-def request(flow):
+from mitmproxy import http
+
+
+def request(flow: http.HTTPFlow) -> None:
flow.request.query["mitmproxy"] = "rocks"
diff --git a/examples/simple/redirect_requests.py b/examples/simple/redirect_requests.py
index 51876df7..ddb89961 100644
--- a/examples/simple/redirect_requests.py
+++ b/examples/simple/redirect_requests.py
@@ -1,9 +1,10 @@
"""
This example shows two ways to redirect flows to another server.
"""
+from mitmproxy import http
-def request(flow):
+def request(flow: http.HTTPFlow) -> None:
# pretty_host takes the "Host" header of the request into account,
# which is useful in transparent mode where we usually only have the IP
# otherwise.
diff --git a/examples/simple/script_arguments.py b/examples/simple/script_arguments.py
deleted file mode 100644
index b46a1960..00000000
--- a/examples/simple/script_arguments.py
+++ /dev/null
@@ -1,17 +0,0 @@
-import argparse
-
-
-class Replacer:
- def __init__(self, src, dst):
- self.src, self.dst = src, dst
-
- def response(self, flow):
- flow.response.replace(self.src, self.dst)
-
-
-def start(opts):
- parser = argparse.ArgumentParser()
- parser.add_argument("src", type=str)
- parser.add_argument("dst", type=str)
- args = parser.parse_args()
- return Replacer(args.src, args.dst)
diff --git a/examples/simple/send_reply_from_proxy.py b/examples/simple/send_reply_from_proxy.py
index bef2e7e7..5011fd2e 100644
--- a/examples/simple/send_reply_from_proxy.py
+++ b/examples/simple/send_reply_from_proxy.py
@@ -5,7 +5,7 @@ without sending any data to the remote server.
from mitmproxy import http
-def request(flow):
+def request(flow: http.HTTPFlow) -> None:
# pretty_url takes the "Host" header of the request into account, which
# is useful in transparent mode where we usually only have the IP otherwise.
diff --git a/examples/simple/upsidedownternet.py b/examples/simple/upsidedownternet.py
index 8ba450ab..f150a5c3 100644
--- a/examples/simple/upsidedownternet.py
+++ b/examples/simple/upsidedownternet.py
@@ -2,11 +2,11 @@
This script rotates all images passing through the proxy by 180 degrees.
"""
import io
-
from PIL import Image
+from mitmproxy import http
-def response(flow):
+def response(flow: http.HTTPFlow) -> None:
if flow.response.headers.get("content-type", "").startswith("image"):
s = io.BytesIO(flow.response.content)
img = Image.open(s).rotate(180)
diff --git a/examples/simple/wsgi_flask_app.py b/examples/simple/wsgi_flask_app.py
index db3b1adf..4be38000 100644
--- a/examples/simple/wsgi_flask_app.py
+++ b/examples/simple/wsgi_flask_app.py
@@ -10,14 +10,14 @@ app = Flask("proxapp")
@app.route('/')
-def hello_world():
+def hello_world() -> str:
return 'Hello World!'
-def start(opts):
- # Host app at the magic domain "proxapp" on port 80. Requests to this
+def load(l):
+ # Host app at the magic domain "proxapp.local" on port 80. Requests to this
# domain and port combination will now be routed to the WSGI app instance.
- return wsgiapp.WSGIApp(app, "proxapp", 80)
+ return wsgiapp.WSGIApp(app, "proxapp.local", 80)
# SSL works too, but the magic domain needs to be resolvable from the mitmproxy machine due to mitmproxy's design.
# mitmproxy will connect to said domain and use serve its certificate (unless --no-upstream-cert is set)