aboutsummaryrefslogtreecommitdiffstats
path: root/examples
diff options
context:
space:
mode:
Diffstat (limited to 'examples')
-rw-r--r--examples/add_header.py2
-rw-r--r--examples/change_upstream_proxy.py2
-rw-r--r--examples/custom_contentviews.py8
-rw-r--r--examples/dns_spoofing.py2
-rw-r--r--examples/dup_and_replay.py9
-rw-r--r--examples/fail_with_500.py2
-rw-r--r--examples/filt.py10
-rw-r--r--examples/flowwriter.py10
-rw-r--r--examples/har_extractor.py12
-rw-r--r--examples/iframe_injector.py14
-rw-r--r--examples/modify_form.py2
-rw-r--r--examples/modify_querystring.py2
-rw-r--r--examples/modify_response_body.py14
-rw-r--r--examples/nonblocking.py7
-rw-r--r--examples/proxapp.py7
-rw-r--r--examples/redirect_requests.py2
-rw-r--r--examples/sslstrip.py14
-rw-r--r--examples/stream.py2
-rw-r--r--examples/stream_modify.py2
-rw-r--r--examples/stub.py41
-rw-r--r--examples/tcp_message.py2
-rw-r--r--examples/tls_passthrough.py24
-rw-r--r--examples/upsidedownternet.py2
23 files changed, 107 insertions, 85 deletions
diff --git a/examples/add_header.py b/examples/add_header.py
index cf1b53cc..3e0b5f1e 100644
--- a/examples/add_header.py
+++ b/examples/add_header.py
@@ -1,2 +1,2 @@
-def response(context, flow):
+def response(flow):
flow.response.headers["newheader"] = "foo"
diff --git a/examples/change_upstream_proxy.py b/examples/change_upstream_proxy.py
index 34a6eece..49d5379f 100644
--- a/examples/change_upstream_proxy.py
+++ b/examples/change_upstream_proxy.py
@@ -14,7 +14,7 @@ def proxy_address(flow):
return ("localhost", 8081)
-def request(context, flow):
+def request(flow):
if flow.request.method == "CONNECT":
# If the decision is done by domain, one could also modify the server address here.
# We do it after CONNECT here to have the request data available as well.
diff --git a/examples/custom_contentviews.py b/examples/custom_contentviews.py
index 92fb6a58..5a63e2a0 100644
--- a/examples/custom_contentviews.py
+++ b/examples/custom_contentviews.py
@@ -62,9 +62,9 @@ class ViewPigLatin(contentviews.View):
pig_view = ViewPigLatin()
-def start(context):
- context.add_contentview(pig_view)
+def start():
+ contentviews.add(pig_view)
-def done(context):
- context.remove_contentview(pig_view)
+def done():
+ contentviews.remove(pig_view)
diff --git a/examples/dns_spoofing.py b/examples/dns_spoofing.py
index 8d715f33..c020047f 100644
--- a/examples/dns_spoofing.py
+++ b/examples/dns_spoofing.py
@@ -28,7 +28,7 @@ import re
parse_host_header = re.compile(r"^(?P<host>[^:]+|\[.+\])(?::(?P<port>\d+))?$")
-def request(context, flow):
+def request(flow):
if flow.client_conn.ssl_established:
flow.request.scheme = "https"
sni = flow.client_conn.connection.get_servername()
diff --git a/examples/dup_and_replay.py b/examples/dup_and_replay.py
index 9ba91d3b..b47bf951 100644
--- a/examples/dup_and_replay.py
+++ b/examples/dup_and_replay.py
@@ -1,4 +1,7 @@
-def request(context, flow):
- f = context.duplicate_flow(flow)
+from mitmproxy import master
+
+
+def request(flow):
+ f = master.duplicate_flow(flow)
f.request.path = "/changed"
- context.replay_request(f)
+ master.replay_request(f, block=True, run_scripthooks=False)
diff --git a/examples/fail_with_500.py b/examples/fail_with_500.py
index aec85b50..9710f74a 100644
--- a/examples/fail_with_500.py
+++ b/examples/fail_with_500.py
@@ -1,3 +1,3 @@
-def response(context, flow):
+def response(flow):
flow.response.status_code = 500
flow.response.content = b""
diff --git a/examples/filt.py b/examples/filt.py
index 1a423845..21744edd 100644
--- a/examples/filt.py
+++ b/examples/filt.py
@@ -3,14 +3,16 @@
import sys
from mitmproxy import filt
+state = {}
-def start(context):
+
+def start():
if len(sys.argv) != 2:
raise ValueError("Usage: -s 'filt.py FILTER'")
- context.filter = filt.parse(sys.argv[1])
+ state["filter"] = filt.parse(sys.argv[1])
-def response(context, flow):
- if flow.match(context.filter):
+def response(flow):
+ if flow.match(state["filter"]):
print("Flow matches filter:")
print(flow)
diff --git a/examples/flowwriter.py b/examples/flowwriter.py
index cb5ccb0d..07c7ca20 100644
--- a/examples/flowwriter.py
+++ b/examples/flowwriter.py
@@ -3,8 +3,10 @@ import sys
from mitmproxy.flow import FlowWriter
+state = {}
-def start(context):
+
+def start():
if len(sys.argv) != 2:
raise ValueError('Usage: -s "flowriter.py filename"')
@@ -12,9 +14,9 @@ def start(context):
f = sys.stdout
else:
f = open(sys.argv[1], "wb")
- context.flow_writer = FlowWriter(f)
+ state["flow_writer"] = FlowWriter(f)
-def response(context, flow):
+def response(flow):
if random.choice([True, False]):
- context.flow_writer.add(flow)
+ state["flow_writer"].add(flow)
diff --git a/examples/har_extractor.py b/examples/har_extractor.py
index a5c05519..b136bd40 100644
--- a/examples/har_extractor.py
+++ b/examples/har_extractor.py
@@ -54,7 +54,13 @@ class _HARLog(HAR.log):
return self.__page_list__
-def start(context):
+class Context(object):
+ pass
+
+context = Context()
+
+
+def start():
"""
On start we create a HARLog instance. You will have to adapt this to
suit your actual needs of HAR generation. As it will probably be
@@ -79,7 +85,7 @@ def start(context):
context.seen_server = set()
-def response(context, flow):
+def response(flow):
"""
Called when a server response has been received. At the time of this
message both a request and a response are present and completely done.
@@ -201,7 +207,7 @@ def response(context, flow):
context.HARLog.add(entry)
-def done(context):
+def done():
"""
Called once on script shutdown, after any other events.
"""
diff --git a/examples/iframe_injector.py b/examples/iframe_injector.py
index ebb5fd02..70247d31 100644
--- a/examples/iframe_injector.py
+++ b/examples/iframe_injector.py
@@ -4,25 +4,27 @@ import sys
from bs4 import BeautifulSoup
from mitmproxy.models import decoded
+iframe_url = None
-def start(context):
+
+def start():
if len(sys.argv) != 2:
raise ValueError('Usage: -s "iframe_injector.py url"')
- context.iframe_url = sys.argv[1]
+ global iframe_url
+ iframe_url = sys.argv[1]
-def response(context, flow):
- if flow.request.host in context.iframe_url:
+def response(flow):
+ if flow.request.host in iframe_url:
return
with decoded(flow.response): # Remove content encoding (gzip, ...)
html = BeautifulSoup(flow.response.content, "lxml")
if html.body:
iframe = html.new_tag(
"iframe",
- src=context.iframe_url,
+ src=iframe_url,
frameborder=0,
height=0,
width=0)
html.body.insert(0, iframe)
flow.response.content = str(html).encode("utf8")
- context.log("Iframe inserted.")
diff --git a/examples/modify_form.py b/examples/modify_form.py
index 3fe0cf96..b63a1586 100644
--- a/examples/modify_form.py
+++ b/examples/modify_form.py
@@ -1,4 +1,4 @@
-def request(context, flow):
+def request(flow):
if flow.request.urlencoded_form:
flow.request.urlencoded_form["mitmproxy"] = "rocks"
else:
diff --git a/examples/modify_querystring.py b/examples/modify_querystring.py
index b89e5c8d..ee8a89ad 100644
--- a/examples/modify_querystring.py
+++ b/examples/modify_querystring.py
@@ -1,2 +1,2 @@
-def request(context, flow):
+def request(flow):
flow.request.query["mitmproxy"] = "rocks"
diff --git a/examples/modify_response_body.py b/examples/modify_response_body.py
index 994932a1..23ad0151 100644
--- a/examples/modify_response_body.py
+++ b/examples/modify_response_body.py
@@ -5,16 +5,20 @@ import sys
from mitmproxy.models import decoded
-def start(context):
+state = {}
+
+
+def start():
if len(sys.argv) != 3:
raise ValueError('Usage: -s "modify_response_body.py old new"')
# You may want to use Python's argparse for more sophisticated argument
# parsing.
- context.old, context.new = sys.argv[1].encode(), sys.argv[2].encode()
+ state["old"], state["new"] = sys.argv[1].encode(), sys.argv[2].encode()
-def response(context, flow):
+def response(flow):
with decoded(flow.response): # automatically decode gzipped responses.
flow.response.content = flow.response.content.replace(
- context.old,
- context.new)
+ state["old"],
+ state["new"]
+ )
diff --git a/examples/nonblocking.py b/examples/nonblocking.py
index 4609f389..05a26921 100644
--- a/examples/nonblocking.py
+++ b/examples/nonblocking.py
@@ -1,9 +1,10 @@
import time
+import mitmproxy
from mitmproxy.script import concurrent
@concurrent # Remove this and see what happens
-def request(context, flow):
- context.log("handle request: %s%s" % (flow.request.host, flow.request.path))
+def request(flow):
+ mitmproxy.log("handle request: %s%s" % (flow.request.host, flow.request.path))
time.sleep(5)
- context.log("start request: %s%s" % (flow.request.host, flow.request.path))
+ mitmproxy.log("start request: %s%s" % (flow.request.host, flow.request.path))
diff --git a/examples/proxapp.py b/examples/proxapp.py
index 613d3f8b..ddc38544 100644
--- a/examples/proxapp.py
+++ b/examples/proxapp.py
@@ -4,6 +4,7 @@ instance, we're using the Flask framework (http://flask.pocoo.org/) to expose
a single simplest-possible page.
"""
from flask import Flask
+import mitmproxy
app = Flask("proxapp")
@@ -15,10 +16,10 @@ def hello_world():
# Register the app using the magic domain "proxapp" on port 80. Requests to
# this domain and port combination will now be routed to the WSGI app instance.
-def start(context):
- context.app_registry.add(app, "proxapp", 80)
+def start():
+ mitmproxy.master.apps.add(app, "proxapp", 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)
# but won't send any data.
- context.app_registry.add(app, "example.com", 443)
+ mitmproxy.master.apps.add(app, "example.com", 443)
diff --git a/examples/redirect_requests.py b/examples/redirect_requests.py
index af2aa907..36594bcd 100644
--- a/examples/redirect_requests.py
+++ b/examples/redirect_requests.py
@@ -5,7 +5,7 @@ from mitmproxy.models import HTTPResponse
from netlib.http import Headers
-def request(context, flow):
+def request(flow):
# 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/sslstrip.py b/examples/sslstrip.py
index 8dde8e3e..afc95fc8 100644
--- a/examples/sslstrip.py
+++ b/examples/sslstrip.py
@@ -2,23 +2,21 @@ from netlib.http import decoded
import re
from six.moves import urllib
+# set of SSL/TLS capable hosts
+secure_hosts = set()
-def start(context):
- # set of SSL/TLS capable hosts
- context.secure_hosts = set()
-
-def request(context, flow):
+def request(flow):
flow.request.headers.pop('If-Modified-Since', None)
flow.request.headers.pop('Cache-Control', None)
# proxy connections to SSL-enabled hosts
- if flow.request.pretty_host in context.secure_hosts:
+ if flow.request.pretty_host in secure_hosts:
flow.request.scheme = 'https'
flow.request.port = 443
-def response(context, flow):
+def response(flow):
with decoded(flow.response):
flow.request.headers.pop('Strict-Transport-Security', None)
flow.request.headers.pop('Public-Key-Pins', None)
@@ -31,7 +29,7 @@ def response(context, flow):
location = flow.response.headers['Location']
hostname = urllib.parse.urlparse(location).hostname
if hostname:
- context.secure_hosts.add(hostname)
+ secure_hosts.add(hostname)
flow.response.headers['Location'] = location.replace('https://', 'http://', 1)
# strip secure flag from 'Set-Cookie' headers
diff --git a/examples/stream.py b/examples/stream.py
index 3adbe437..8598f329 100644
--- a/examples/stream.py
+++ b/examples/stream.py
@@ -1,4 +1,4 @@
-def responseheaders(context, flow):
+def responseheaders(flow):
"""
Enables streaming for all responses.
"""
diff --git a/examples/stream_modify.py b/examples/stream_modify.py
index aa395c03..5e5da95b 100644
--- a/examples/stream_modify.py
+++ b/examples/stream_modify.py
@@ -16,5 +16,5 @@ def modify(chunks):
yield chunk.replace("foo", "bar")
-def responseheaders(context, flow):
+def responseheaders(flow):
flow.response.stream = modify
diff --git a/examples/stub.py b/examples/stub.py
index a0f73538..a4f16699 100644
--- a/examples/stub.py
+++ b/examples/stub.py
@@ -1,79 +1,80 @@
+import mitmproxy
"""
This is a script stub, with definitions for all events.
"""
-def start(context):
+def start():
"""
Called once on script startup, before any other events.
"""
- context.log("start")
+ mitmproxy.log("start")
-def clientconnect(context, root_layer):
+def clientconnect(root_layer):
"""
Called when a client initiates a connection to the proxy. Note that a
connection can correspond to multiple HTTP requests
"""
- context.log("clientconnect")
+ mitmproxy.log("clientconnect")
-def request(context, flow):
+def request(flow):
"""
Called when a client request has been received.
"""
- context.log("request")
+ mitmproxy.log("request")
-def serverconnect(context, server_conn):
+def serverconnect(server_conn):
"""
Called when the proxy initiates a connection to the target server. Note that a
connection can correspond to multiple HTTP requests
"""
- context.log("serverconnect")
+ mitmproxy.log("serverconnect")
-def responseheaders(context, flow):
+def responseheaders(flow):
"""
Called when the response headers for a server response have been received,
but the response body has not been processed yet. Can be used to tell mitmproxy
to stream the response.
"""
- context.log("responseheaders")
+ mitmproxy.log("responseheaders")
-def response(context, flow):
+def response(flow):
"""
Called when a server response has been received.
"""
- context.log("response")
+ mitmproxy.log("response")
-def error(context, flow):
+def error(flow):
"""
Called when a flow error has occured, e.g. invalid server responses, or
interrupted connections. This is distinct from a valid server HTTP error
response, which is simply a response with an HTTP error code.
"""
- context.log("error")
+ mitmproxy.log("error")
-def serverdisconnect(context, server_conn):
+def serverdisconnect(server_conn):
"""
Called when the proxy closes the connection to the target server.
"""
- context.log("serverdisconnect")
+ mitmproxy.log("serverdisconnect")
-def clientdisconnect(context, root_layer):
+def clientdisconnect(root_layer):
"""
Called when a client disconnects from the proxy.
"""
- context.log("clientdisconnect")
+ mitmproxy.log("clientdisconnect")
-def done(context):
+def done():
"""
Called once on script shutdown, after any other events.
"""
- context.log("done")
+ mitmproxy.log("done")
diff --git a/examples/tcp_message.py b/examples/tcp_message.py
index 6eced0dc..b431c23f 100644
--- a/examples/tcp_message.py
+++ b/examples/tcp_message.py
@@ -11,7 +11,7 @@ mitmdump -T --host --tcp ".*" -q -s examples/tcp_message.py
from netlib import strutils
-def tcp_message(ctx, tcp_msg):
+def tcp_message(tcp_msg):
modified_msg = tcp_msg.message.replace("foo", "bar")
is_modified = False if modified_msg == tcp_msg.message else True
diff --git a/examples/tls_passthrough.py b/examples/tls_passthrough.py
index 50aab65b..374020e7 100644
--- a/examples/tls_passthrough.py
+++ b/examples/tls_passthrough.py
@@ -20,13 +20,14 @@ Example:
Authors: Maximilian Hils, Matthew Tuusberg
"""
-from __future__ import (absolute_import, print_function, division)
+from __future__ import absolute_import, print_function, division
import collections
import random
import sys
from enum import Enum
+import mitmproxy
from mitmproxy.exceptions import TlsProtocolException
from mitmproxy.protocol import TlsLayer, RawTCPLayer
@@ -97,7 +98,6 @@ class TlsFeedback(TlsLayer):
def _establish_tls_with_client(self):
server_address = self.server_conn.address
- tls_strategy = self.script_context.tls_strategy
try:
super(TlsFeedback, self)._establish_tls_with_client()
@@ -110,15 +110,18 @@ class TlsFeedback(TlsLayer):
# inline script hooks below.
+tls_strategy = None
-def start(context):
+
+def start():
+ global tls_strategy
if len(sys.argv) == 2:
- context.tls_strategy = ProbabilisticStrategy(float(sys.argv[1]))
+ tls_strategy = ProbabilisticStrategy(float(sys.argv[1]))
else:
- context.tls_strategy = ConservativeStrategy()
+ tls_strategy = ConservativeStrategy()
-def next_layer(context, next_layer):
+def next_layer(next_layer):
"""
This hook does the actual magic - if the next layer is planned to be a TLS layer,
we check if we want to enter pass-through mode instead.
@@ -126,14 +129,13 @@ def next_layer(context, next_layer):
if isinstance(next_layer, TlsLayer) and next_layer._client_tls:
server_address = next_layer.server_conn.address
- if context.tls_strategy.should_intercept(server_address):
+ if tls_strategy.should_intercept(server_address):
# We try to intercept.
# Monkey-Patch the layer to get feedback from the TLSLayer if interception worked.
next_layer.__class__ = TlsFeedback
- next_layer.script_context = context
else:
# We don't intercept - reply with a pass-through layer and add a "skipped" entry.
- context.log("TLS passthrough for %s" % repr(next_layer.server_conn.address), "info")
- next_layer_replacement = RawTCPLayer(next_layer.ctx, logging=False)
+ mitmproxy.log("TLS passthrough for %s" % repr(next_layer.server_conn.address), "info")
+ next_layer_replacement = RawTCPLayer(next_layer.ctx, ignore=True)
next_layer.reply.send(next_layer_replacement)
- context.tls_strategy.record_skipped(server_address)
+ tls_strategy.record_skipped(server_address)
diff --git a/examples/upsidedownternet.py b/examples/upsidedownternet.py
index 9aac9f05..fafdefce 100644
--- a/examples/upsidedownternet.py
+++ b/examples/upsidedownternet.py
@@ -3,7 +3,7 @@ from PIL import Image
from mitmproxy.models import decoded
-def response(context, flow):
+def response(flow):
if flow.response.headers.get("content-type", "").startswith("image"):
with decoded(flow.response): # automatically decode gzipped responses.
try: