aboutsummaryrefslogtreecommitdiffstats
path: root/examples
diff options
context:
space:
mode:
Diffstat (limited to 'examples')
-rw-r--r--examples/README33
-rw-r--r--examples/add_header.py2
-rw-r--r--examples/change_upstream_proxy.py23
-rw-r--r--examples/dup_and_replay.py6
-rwxr-xr-xexamples/flowbasic3
-rw-r--r--examples/iframe_injector.py10
-rw-r--r--examples/modify_form.py2
-rw-r--r--examples/modify_querystring.py2
-rw-r--r--examples/modify_response_body.py8
-rw-r--r--examples/nonblocking.py2
-rwxr-xr-xexamples/proxapp47
-rw-r--r--examples/proxapp.py24
-rw-r--r--examples/read_dumpfile11
-rw-r--r--examples/redirect_requests.py6
-rwxr-xr-xexamples/stickycookies30
-rw-r--r--examples/stream.py2
-rw-r--r--examples/stub.py36
-rw-r--r--examples/upsidedownternet.py20
18 files changed, 135 insertions, 132 deletions
diff --git a/examples/README b/examples/README
index 46d25acd..85ab272a 100644
--- a/examples/README
+++ b/examples/README
@@ -1,10 +1,23 @@
-add_header.py Simple script that just adds a header to every request.
-dup_and_replay.py Duplicates each request, changes it, and then replays the modified request.
-flowbasic Basic use of mitmproxy as a library.
-modify_form.py Modify all form submissions to add a parameter.
-modify_querystring.py Modify all query strings to add a parameters.
-proxapp How to embed a WSGI app in a mitmproxy server
-stub.py Script stub with a method definition for every event.
-stickycookies An example of writing a custom proxy with libmproxy.
-upsidedownternet.py Rewrites traffic to turn PNGs upside down.
-mitmproxywrapper.py Bracket mitmproxy run with proxy enable/disable on OS X
+# inline script examples
+add_header.py Simple script that just adds a header to every request.
+change_upstream_proxy.py Dynamically change the upstream proxy
+dup_and_replay.py Duplicates each request, changes it, and then replays the modified request.
+iframe_injector.py Inject configurable iframe into pages.
+modify_form.py Modify all form submissions to add a parameter.
+modify_querystring.py Modify all query strings to add a parameters.
+modify_response_body.py Replace arbitrary strings in all responses
+nonblocking.py Demonstrate parallel processing with a blocking script.
+proxapp.py How to embed a WSGI app in a mitmproxy server
+redirect_requests.py Redirect requests or directly reply to them.
+stub.py Script stub with a method definition for every event.
+upsidedownternet.py Rewrites traffic to turn images upside down.
+
+
+# libmproxy examples
+flowbasic Basic use of mitmproxy as a library.
+stickycookies An example of writing a custom proxy with libmproxy.
+
+
+# misc
+read_dumpfile Read a dumpfile generated by mitmproxy.
+mitmproxywrapper.py Bracket mitmproxy run with proxy enable/disable on OS X
diff --git a/examples/add_header.py b/examples/add_header.py
index b9c8c1c6..291741cb 100644
--- a/examples/add_header.py
+++ b/examples/add_header.py
@@ -1,2 +1,2 @@
-def response(ctx, flow):
+def response(context, flow):
flow.response.headers["newheader"] = ["foo"] \ No newline at end of file
diff --git a/examples/change_upstream_proxy.py b/examples/change_upstream_proxy.py
index 86031d29..e063ca4f 100644
--- a/examples/change_upstream_proxy.py
+++ b/examples/change_upstream_proxy.py
@@ -4,17 +4,18 @@
# Usage: mitmdump -s "change_upstream_proxy.py host"
from libmproxy.protocol.http import send_connect_request
+alternative_upstream_proxy = ("localhost", 8082)
def should_redirect(flow):
- return (flow.request.host == "example.com")
-alternative_upstream_proxy = ("localhost",8082)
+ return flow.request.host == "example.com"
-def request(ctx, flow):
- if flow.live and should_redirect(flow):
- # If you want to change the target server, you should modify flow.request.host and flow.request.port
- # flow.live.change_server should only be used by inline scripts to change the upstream proxy,
- # unless you are sure that you know what you are doing.
- server_changed = flow.live.change_server(alternative_upstream_proxy, persistent_change=True)
- if flow.request.scheme == "https" and server_changed:
- send_connect_request(flow.live.c.server_conn, flow.request.host, flow.request.port)
- flow.live.c.establish_ssl(server=True)
+def request(context, flow):
+ if flow.live and should_redirect(flow):
+
+ # If you want to change the target server, you should modify flow.request.host and flow.request.port
+ # flow.live.change_server should only be used by inline scripts to change the upstream proxy,
+ # unless you are sure that you know what you are doing.
+ server_changed = flow.live.change_server(alternative_upstream_proxy, persistent_change=True)
+ if flow.request.scheme == "https" and server_changed:
+ send_connect_request(flow.live.c.server_conn, flow.request.host, flow.request.port)
+ flow.live.c.establish_ssl(server=True)
diff --git a/examples/dup_and_replay.py b/examples/dup_and_replay.py
index b38c2b7e..3d9279cc 100644
--- a/examples/dup_and_replay.py
+++ b/examples/dup_and_replay.py
@@ -1,4 +1,4 @@
-def request(ctx, flow):
- f = ctx.duplicate_flow(flow)
+def request(context, flow):
+ f = context.duplicate_flow(flow)
f.request.path = "/changed"
- ctx.replay_request(f) \ No newline at end of file
+ context.replay_request(f) \ No newline at end of file
diff --git a/examples/flowbasic b/examples/flowbasic
index 2b44be3f..9aeb83c5 100755
--- a/examples/flowbasic
+++ b/examples/flowbasic
@@ -12,6 +12,7 @@ import os
from libmproxy import flow, proxy
from libmproxy.proxy.server import ProxyServer
+
class MyMaster(flow.FlowMaster):
def run(self):
try:
@@ -34,7 +35,7 @@ class MyMaster(flow.FlowMaster):
config = proxy.ProxyConfig(
- ca_file = os.path.expanduser("~/.mitmproxy/mitmproxy-ca.pem")
+ ca_file=os.path.expanduser("~/.mitmproxy/mitmproxy-ca.pem")
)
state = flow.State()
server = ProxyServer(config, 8080)
diff --git a/examples/iframe_injector.py b/examples/iframe_injector.py
index 7042dbab..42260a7e 100644
--- a/examples/iframe_injector.py
+++ b/examples/iframe_injector.py
@@ -3,16 +3,16 @@
from libmproxy.protocol.http import decoded
-def start(ctx, argv):
+def start(context, argv):
if len(argv) != 2:
raise ValueError('Usage: -s "iframe_injector.py url"')
- ctx.iframe_url = argv[1]
+ context.iframe_url = argv[1]
-def handle_response(ctx, flow):
+def handle_response(context, flow):
with decoded(flow.response): # Remove content encoding (gzip, ...)
c = flow.response.replace(
'<body>',
- '<body><iframe src="%s" frameborder="0" height="0" width="0"></iframe>' % ctx.iframe_url)
+ '<body><iframe src="%s" frameborder="0" height="0" width="0"></iframe>' % context.iframe_url)
if c > 0:
- ctx.log("Iframe injected!") \ No newline at end of file
+ context.log("Iframe injected!") \ No newline at end of file
diff --git a/examples/modify_form.py b/examples/modify_form.py
index 6d651b19..3d93e392 100644
--- a/examples/modify_form.py
+++ b/examples/modify_form.py
@@ -1,5 +1,5 @@
-def request(ctx, flow):
+def request(context, flow):
if "application/x-www-form-urlencoded" in flow.request.headers["content-type"]:
form = flow.request.get_form_urlencoded()
form["mitmproxy"] = ["rocks"]
diff --git a/examples/modify_querystring.py b/examples/modify_querystring.py
index 56fbbb32..1dd4807a 100644
--- a/examples/modify_querystring.py
+++ b/examples/modify_querystring.py
@@ -1,5 +1,5 @@
-def request(ctx, flow):
+def request(context, flow):
q = flow.request.get_query()
if q:
q["mitmproxy"] = ["rocks"]
diff --git a/examples/modify_response_body.py b/examples/modify_response_body.py
index e8428cdb..4afd0421 100644
--- a/examples/modify_response_body.py
+++ b/examples/modify_response_body.py
@@ -3,13 +3,13 @@
from libmproxy.protocol.http import decoded
-def start(ctx, argv):
+def start(context, argv):
if len(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.
- ctx.old, ctx.new = argv[1], argv[2]
+ context.old, context.new = argv[1], argv[2]
-def response(ctx, flow):
+def response(context, flow):
with decoded(flow.response): # automatically decode gzipped responses.
- flow.response.content = flow.response.content.replace(ctx.old, ctx.new) \ No newline at end of file
+ flow.response.content = flow.response.content.replace(context.old, context.new) \ No newline at end of file
diff --git a/examples/nonblocking.py b/examples/nonblocking.py
index 1396742a..481c0407 100644
--- a/examples/nonblocking.py
+++ b/examples/nonblocking.py
@@ -2,7 +2,7 @@ import time
from libmproxy.script import concurrent
-@concurrent
+@concurrent # Remove this and see what happens
def request(context, flow):
print "handle request: %s%s" % (flow.request.host, flow.request.path)
time.sleep(5)
diff --git a/examples/proxapp b/examples/proxapp
deleted file mode 100755
index 9f299d25..00000000
--- a/examples/proxapp
+++ /dev/null
@@ -1,47 +0,0 @@
-#!/usr/bin/env python
-"""
-This example shows how to graft a WSGI app onto mitmproxy. In this
-instance, we're using the Bottle framework (http://bottlepy.org/) to expose
-a single simplest-possible page.
-"""
-import bottle
-import os
-from libmproxy import proxy, flow
-
-@bottle.route('/')
-def index():
- return 'Hi!'
-
-
-class MyMaster(flow.FlowMaster):
- def run(self):
- try:
- flow.FlowMaster.run(self)
- except KeyboardInterrupt:
- self.shutdown()
-
- def handle_request(self, f):
- f = flow.FlowMaster.handle_request(self, f)
- if f:
- f.reply()
- return f
-
- def handle_response(self, f):
- f = flow.FlowMaster.handle_response(self, f)
- if f:
- f.reply()
- print f
- return f
-
-
-config = proxy.ProxyConfig(
- cacert = os.path.expanduser("~/.mitmproxy/mitmproxy-ca.pem")
-)
-state = flow.State()
-server = proxy.ProxyServer(config, 8080)
-# 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.
-server.apps.add(bottle.app(), "proxapp", 80)
-m = MyMaster(server, state)
-m.run()
-
diff --git a/examples/proxapp.py b/examples/proxapp.py
new file mode 100644
index 00000000..d777d522
--- /dev/null
+++ b/examples/proxapp.py
@@ -0,0 +1,24 @@
+"""
+This example shows how to graft a WSGI app onto mitmproxy. In this
+instance, we're using the Flask framework (http://flask.pocoo.org/) to expose
+a single simplest-possible page.
+"""
+from flask import Flask
+
+app = Flask("proxapp")
+
+
+@app.route('/')
+def hello_world():
+ return '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, argv):
+ context.app_registry.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) \ No newline at end of file
diff --git a/examples/read_dumpfile b/examples/read_dumpfile
index 547f3c17..c0a50d26 100644
--- a/examples/read_dumpfile
+++ b/examples/read_dumpfile
@@ -6,12 +6,13 @@
from libmproxy import flow
import json, sys
-with open("logfile", "rb") as f:
- freader = flow.FlowReader(f)
+with open("logfile", "rb") as logfile:
+ freader = flow.FlowReader(logfile)
try:
- for i in freader.stream():
- print i.request.host
- json.dump(i._get_state(), sys.stdout, indent=4)
+ for f in freader.stream():
+ print(f)
+ print(f.request.host)
+ json.dump(f._get_state(), sys.stdout, indent=4)
print ""
except flow.FlowReadError, v:
print "Flow file corrupted. Stopped loading." \ No newline at end of file
diff --git a/examples/redirect_requests.py b/examples/redirect_requests.py
index c5561839..d9a3bfc5 100644
--- a/examples/redirect_requests.py
+++ b/examples/redirect_requests.py
@@ -6,15 +6,19 @@ This example shows two ways to redirect flows to other destinations.
"""
-def request(ctx, flow):
+def request(context, flow):
# pretty_host(hostheader=True) takes the Host: header of the request into account,
# which is useful in transparent mode where we usually only have the IP otherwise.
+
+ # Method 1: Answer with a locally generated response
if flow.request.pretty_host(hostheader=True).endswith("example.com"):
resp = HTTPResponse(
[1, 1], 200, "OK",
ODictCaseless([["Content-Type", "text/html"]]),
"helloworld")
flow.reply(resp)
+
+ # Method 2: Redirect the request to a different server
if flow.request.pretty_host(hostheader=True).endswith("example.org"):
flow.request.host = "mitmproxy.org"
flow.request.update_host_header()
diff --git a/examples/stickycookies b/examples/stickycookies
index 2aab31d6..d2368e22 100755
--- a/examples/stickycookies
+++ b/examples/stickycookies
@@ -1,9 +1,9 @@
#!/usr/bin/env python
"""
This example builds on mitmproxy's base proxying infrastructure to
-implement functionality similar to the "sticky cookies" option. This is at
-a lower level than the Flow mechanism, so we're dealing directly with
-request and response objects.
+implement functionality similar to the "sticky cookies" option.
+
+Heads Up: In the majority of cases, you want to use inline scripts.
"""
import os
from libmproxy import controller, proxy
@@ -21,19 +21,19 @@ class StickyMaster(controller.Master):
except KeyboardInterrupt:
self.shutdown()
- def handle_request(self, msg):
- hid = (msg.host, msg.port)
- if msg.headers["cookie"]:
- self.stickyhosts[hid] = msg.headers["cookie"]
+ def handle_request(self, flow):
+ hid = (flow.request.host, flow.request.port)
+ if flow.request.headers["cookie"]:
+ self.stickyhosts[hid] = flow.request.headers["cookie"]
elif hid in self.stickyhosts:
- msg.headers["cookie"] = self.stickyhosts[hid]
- msg.reply()
-
- def handle_response(self, msg):
- hid = (msg.request.host, msg.request.port)
- if msg.headers["set-cookie"]:
- self.stickyhosts[hid] = msg.headers["set-cookie"]
- msg.reply()
+ flow.request.headers["cookie"] = self.stickyhosts[hid]
+ flow.reply()
+
+ def handle_response(self, flow):
+ hid = (flow.request.host, flow.request.port)
+ if flow.response.headers["set-cookie"]:
+ self.stickyhosts[hid] = flow.response.headers["set-cookie"]
+ flow.reply()
config = proxy.ProxyConfig(
diff --git a/examples/stream.py b/examples/stream.py
index f9f03c3e..7d5efc1e 100644
--- a/examples/stream.py
+++ b/examples/stream.py
@@ -1,4 +1,4 @@
-def responseheaders(ctx, flow):
+def responseheaders(context, flow):
"""
Enables streaming for all responses.
"""
diff --git a/examples/stub.py b/examples/stub.py
index 5976dd76..c5cdad9c 100644
--- a/examples/stub.py
+++ b/examples/stub.py
@@ -1,63 +1,63 @@
"""
This is a script stub, with definitions for all events.
"""
-def start(ctx, argv):
+def start(context, argv):
"""
Called once on script startup, before any other events.
"""
- ctx.log("start")
+ context.log("start")
-def clientconnect(ctx, conn_handler):
+def clientconnect(context, conn_handler):
"""
Called when a client initiates a connection to the proxy. Note that a
connection can correspond to multiple HTTP requests
"""
- ctx.log("clientconnect")
+ context.log("clientconnect")
-def serverconnect(ctx, conn_handler):
+def serverconnect(context, conn_handler):
"""
Called when the proxy initiates a connection to the target server. Note that a
connection can correspond to multiple HTTP requests
"""
- ctx.log("serverconnect")
+ context.log("serverconnect")
-def request(ctx, flow):
+def request(context, flow):
"""
Called when a client request has been received.
"""
- ctx.log("request")
+ context.log("request")
-def responseheaders(ctx, flow):
+def responseheaders(context, 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.
"""
- ctx.log("responseheaders")
+ context.log("responseheaders")
-def response(ctx, flow):
+def response(context, flow):
"""
Called when a server response has been received.
"""
- ctx.log("response")
+ context.log("response")
-def error(ctx, flow):
+def error(context, 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.
"""
- ctx.log("error")
+ context.log("error")
-def clientdisconnect(ctx, conn_handler):
+def clientdisconnect(context, conn_handler):
"""
Called when a client disconnects from the proxy.
"""
- ctx.log("clientdisconnect")
+ context.log("clientdisconnect")
-def done(ctx):
+def done(context):
"""
Called once on script shutdown, after any other events.
"""
- ctx.log("done")
+ context.log("done")
diff --git a/examples/upsidedownternet.py b/examples/upsidedownternet.py
index a52b6d30..738eb11f 100644
--- a/examples/upsidedownternet.py
+++ b/examples/upsidedownternet.py
@@ -1,10 +1,16 @@
import cStringIO
from PIL import Image
+from libmproxy.protocol.http import decoded
-def response(ctx, flow):
- if flow.response.headers["content-type"] == ["image/png"]:
- s = cStringIO.StringIO(flow.response.content)
- img = Image.open(s).rotate(180)
- s2 = cStringIO.StringIO()
- img.save(s2, "png")
- flow.response.content = s2.getvalue()
+def response(context, flow):
+ if flow.response.headers.get_first("content-type", "").startswith("image"):
+ with decoded(flow.response): # automatically decode gzipped responses.
+ try:
+ s = cStringIO.StringIO(flow.response.content)
+ img = Image.open(s).rotate(180)
+ s2 = cStringIO.StringIO()
+ img.save(s2, "png")
+ flow.response.content = s2.getvalue()
+ flow.response.headers["content-type"] = ["image/png"]
+ except: # Unknown image types etc.
+ pass \ No newline at end of file