Skip to content

Instantly share code, notes, and snippets.

@vfaronov
Created December 22, 2018 17:23
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 2 You must be signed in to fork a gist
  • Save vfaronov/3f7848932ed96a264c382902262ce7b3 to your computer and use it in GitHub Desktop.
Save vfaronov/3f7848932ed96a264c382902262ce7b3 to your computer and use it in GitHub Desktop.
mitmproxy scripting cheat sheet / snippets collection
# Copy this file and run mitmproxy like this::
#
# mitmproxy -s mitmproxy-quicker.py --mode reverse:http://dummy.invalid
#
# Then edit the code below. For example,
# http://localhost:8080/index.html will serve the HTML page defined below.
# mitmproxy will automatically reload the script whenever you save it to disk.
# You can specify a real fallback upstream instead of ``dummy.invalid``,
# or remove the ``--mode`` option altogether for a regular (forward) proxy.
#
# This has been checked with mitmproxy 4.0.4. Later versions may need changes.
def request(flow):
if random.random() < 0.2: # randomly wreck every 5th request
flow.response = text_response('Wrecked!\r\n', status_code=500)
return
if flowfilter.match('~u api/products', flow): # mock an HTTP API
if 'json' in flow.request.headers.get('Accept') or '':
flow.response = json_response({'hello': ['world']})
else:
flow.response = xml_response('<hello><world/></hello>\r\n')
return
if flowfilter.match('~u index.html', flow): # mock a Web site
flow.response = html_page('<p>Welcome to our site!</p>',
title='ACME Corp.',
head='<script>alert("hi")</script>')
return
def response(flow):
ctx.log.info('this will be printed to mitmproxy log')
if flowfilter.match('~ts xml', flow): # tweak every XML response body
flow.response.content = \
flow.response.content.replace(b'WonderWidgets', b'SuperStuff')
##############################################################################
# pylint: disable=wrong-import-position,import-error
import email
import json
import random
from mitmproxy import ctx, flowfilter
import mitmproxy.http
import mitmproxy.net.http
def make_response(status_code=200, content=b'', headers=None, content_type=None):
headers = dict(headers or {})
headers.setdefault('Date', email.utils.formatdate(usegmt=True))
if content_type:
headers.setdefault('Content-Type', content_type)
return mitmproxy.http.HTTPResponse.wrap(
mitmproxy.net.http.Response.make(status_code, content, headers),
)
def text_response(text='Hello world!\r\n', status_code=200, headers=None):
return make_response(status_code, text, headers,
content_type='text/plain')
def json_response(data=None, status_code=200, headers=None):
return make_response(
status_code,
json.dumps(data, indent=4, ensure_ascii=False).encode('utf-8'),
headers, content_type='application/json',
)
def xml_response(code='<hello/>\r\n', status_code=200, headers=None):
return make_response(status_code, code, headers,
content_type='text/xml')
def html_page(body='<p>Hello world!</p>', title='Hello world!', head='',
status_code=200, headers=None):
return make_response(
status_code,
f'<!DOCTYPE html>\r\n'
f'<html>\r\n'
f'<head><title>{title}</title> {head}</head>\r\n'
f'<body>{body}</body>\r\n'
f'</html>\r\n',
headers,
content_type='text/html; charset=utf-8',
)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment