mirror of
https://github.com/zhigang1992/mitmproxy.git
synced 2026-04-03 22:47:19 +08:00
Compare commits
31 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
54df58b7a8 | ||
|
|
886970040b | ||
|
|
c1a60a1f6b | ||
|
|
c89378047b | ||
|
|
a386dff058 | ||
|
|
db43f1ffcc | ||
|
|
bef5662365 | ||
|
|
34f286df51 | ||
|
|
ba47690a03 | ||
|
|
d3beaa7382 | ||
|
|
1a5c27aa7d | ||
|
|
9f6657727b | ||
|
|
7ef68b5a13 | ||
|
|
19279033b3 | ||
|
|
0b5423f6a1 | ||
|
|
ebf0aaa3db | ||
|
|
df7c7796b2 | ||
|
|
ffeede9b39 | ||
|
|
82cb1dae41 | ||
|
|
aaba1bd7d1 | ||
|
|
125b3e5e5b | ||
|
|
8608cdf177 | ||
|
|
3460d56fcc | ||
|
|
50ac988363 | ||
|
|
bfb3828f37 | ||
|
|
208204d33a | ||
|
|
d48d3d4eb3 | ||
|
|
1400880d58 | ||
|
|
e951b86c21 | ||
|
|
52a4a8bbde | ||
|
|
0ad505ed7d |
15
CHANGELOG
15
CHANGELOG
@@ -1,5 +1,18 @@
|
||||
|
||||
x January 2013: mitmproxy 0.9:
|
||||
16 June 2013: mitmproxy 0.9.1:
|
||||
|
||||
* Use "correct" case for Content-Type headers added by mitmproxy.
|
||||
|
||||
* Make UTF environment detection more robust.
|
||||
|
||||
* Improved MIME-type detection for viewers.
|
||||
|
||||
* Always read files in binary mode (Windows compatibility fix).
|
||||
|
||||
* Some developer documentation.
|
||||
|
||||
|
||||
15 May 2013: mitmproxy 0.9:
|
||||
|
||||
* Upstream certs mode is now the default.
|
||||
|
||||
|
||||
30
CONTRIBUTORS
30
CONTRIBUTORS
@@ -1,35 +1,39 @@
|
||||
759 Aldo Cortesi
|
||||
777 Aldo Cortesi
|
||||
18 Henrik Nordstrom
|
||||
13 Thomas Roth
|
||||
11 Stephen Altamirano
|
||||
10 András Veres-Szentkirályi
|
||||
8 Rouli
|
||||
8 Jason A. Novak
|
||||
7 Alexis Hildebrandt
|
||||
5 Maximilian Hils
|
||||
4 Bryan Bishop
|
||||
6 Maximilian Hils
|
||||
4 Valtteri Virtanen
|
||||
4 Bryan Bishop
|
||||
3 Chris Neasbitt
|
||||
2 Michael Frister
|
||||
2 Heikki Hannikainen
|
||||
2 Jim Lloyd
|
||||
2 Mark E. Haase
|
||||
2 Michael Frister
|
||||
2 Rob Wills
|
||||
2 alts
|
||||
2 israel
|
||||
1 Jakub Nawalaniec
|
||||
1 Mathieu Mitchell
|
||||
1 Michael Bisbjerg
|
||||
1 capt8bit
|
||||
1 Nicolas Esteves
|
||||
1 Paul
|
||||
1 phil plante
|
||||
1 Rory McCann
|
||||
1 Henrik Nordström
|
||||
1 Jakub Nawalaniec
|
||||
1 Rune Halvorsen
|
||||
1 Sahn Lam
|
||||
1 Felix Wolfsteller
|
||||
1 Eric Entzel
|
||||
1 Ulrich Petri
|
||||
1 Ivaylo Popov
|
||||
1 Andy Smith
|
||||
1 Ulrich Petri
|
||||
1 Henrik Nordström
|
||||
1 Felix Wolfsteller
|
||||
1 Yuangxuan Wang
|
||||
1 Kit Randel
|
||||
1 Marc Liyanage
|
||||
1 meeee
|
||||
1 capt8bit
|
||||
1 Mathieu Mitchell
|
||||
1 Jason A. Novak
|
||||
1 Nicolas Esteves
|
||||
1 Eric Entzel
|
||||
|
||||
@@ -2,6 +2,7 @@ include LICENSE
|
||||
include CHANGELOG
|
||||
include CONTRIBUTORS
|
||||
include README.txt
|
||||
include setup.py
|
||||
exclude README.mkd
|
||||
recursive-include examples *
|
||||
recursive-include doc *
|
||||
|
||||
@@ -55,6 +55,8 @@ The following components are needed if you plan to hack on mitmproxy:
|
||||
framework and requires [pathod](http://pathod.org) and [flask](http://flask.pocoo.org/).
|
||||
* Rendering the documentation requires [countershape](http://github.com/cortesi/countershape).
|
||||
|
||||
For convenience, all dependencies save countershape, can be installed from pypi to a virtualenv with 'pip install -r requirements.txt'.
|
||||
|
||||
Please ensure that all patches are accompanied by matching changes in the test
|
||||
suite. The project maintains 100% test coverage.
|
||||
|
||||
|
||||
@@ -58,6 +58,10 @@
|
||||
<li class="nav-header">Scripting mitmproxy</li>
|
||||
$!nav("scripting/inlinescripts.html", this, state)!$
|
||||
$!nav("scripting/libmproxy.html", this, state)!$
|
||||
|
||||
<li class="nav-header">Hacking</li>
|
||||
$!nav("dev/testing.html", this, state)!$
|
||||
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
52
doc-src/dev/addingviews.html
Normal file
52
doc-src/dev/addingviews.html
Normal file
@@ -0,0 +1,52 @@
|
||||
As discussed in [the Flow View section of the mitmproxy
|
||||
overview](@!urlTo("mitmproxy.html")!@), mitmproxy allows you to inspect and
|
||||
manipulate flows. When inspecting a single flow, mitmproxy uses a number of
|
||||
heuristics to show a friendly view of various content types; if mitmproxy
|
||||
cannot show a friendly view, mitmproxy defaults to a __raw__ view.
|
||||
|
||||
Each content type invokes a different flow viewer to parse the data and display
|
||||
the friendly view. Users can add custom content viewers by adding a view class
|
||||
to contentview.py, discussed below.
|
||||
|
||||
## Adding a new View class to contentview.py
|
||||
|
||||
The content viewers used by mitmproxy to present a friendly view of various
|
||||
content types are stored in contentview.py. Reviewing this file shows a number
|
||||
of classes named ViewSomeDataType, each with the properties: __name__,
|
||||
__prompt__, and __content\_types__ and a function named __\_\_call\_\___.
|
||||
|
||||
Adding a new content viewer to parse a data type is as simple as writing a new
|
||||
View class. Your new content viewer View class should have the same properties
|
||||
as the other View classes: __name__, __prompt__, and __content\_types__ and a
|
||||
__\_\_call\_\___ function to parse the content of the request/response.
|
||||
|
||||
* The __name__ property should be a string describing the contents and new content viewer;
|
||||
* The __prompt__ property should be a two item tuple:
|
||||
|
||||
- __1__: A string that will be used to display the new content viewer's type; and
|
||||
- __2__: A one character string that will be the hotkey used to select the new content viewer from the Flow View screen;
|
||||
|
||||
* The __content\_types__ property should be a list of strings of HTTP Content\-Types that the new content viewer can parse.
|
||||
* Note that mitmproxy will use the content\_types to try and heuristically show a friendly view of content and that you can override the built-in views by populating content\_types with values for content\_types that are already parsed -- e.g. "image/png".
|
||||
|
||||
After defining the __name__, __prompt__, and __content\_types__ properties of
|
||||
the class, you should write the __\_\_call\_\___ function, which will parse the
|
||||
request/response data and provide a friendly view of the data. The
|
||||
__\_\_call\_\___ function should take the following arguments: __self__,
|
||||
__hdrs__, __content__, __limit__; __hdrs__ is a ODictCaseless object containing
|
||||
the headers of the request/response; __content__ is the content of the
|
||||
request/response, and __limit__ is an integer representing the amount of data
|
||||
to display in the view window.
|
||||
|
||||
The __\_\_call\_\___ function returns two values: (1) a string describing the
|
||||
parsed data; and (2) the parsed data for friendly display. The parsed data to
|
||||
be displayed should be a list of strings formatted for display. You can use
|
||||
the __\_view\_text__ function in contentview.py to format text for display.
|
||||
Alternatively, you can display content as a series of key-value pairs; to do
|
||||
so, prepare a list of lists, where each list item is a two item list -- a key
|
||||
that describes the data, and then the data itself; after preparing the list of
|
||||
lists, use the __common.format\_keyvals__ function on it to prepare it as text
|
||||
for display.
|
||||
|
||||
If the new content viewer fails or throws an exception, mitmproxy will default
|
||||
to a __raw__ view.
|
||||
6
doc-src/dev/index.py
Normal file
6
doc-src/dev/index.py
Normal file
@@ -0,0 +1,6 @@
|
||||
from countershape import Page
|
||||
|
||||
pages = [
|
||||
Page("testing.html", "Testing"),
|
||||
# Page("addingviews.html", "Writing Content Views"),
|
||||
]
|
||||
43
doc-src/dev/testing.html
Normal file
43
doc-src/dev/testing.html
Normal file
@@ -0,0 +1,43 @@
|
||||
|
||||
All the mitmproxy projects strive to maintain 100% code coverage. In general,
|
||||
patches and pull requests will be declined unless they're accompanied by a
|
||||
suitable extension to the test suite.
|
||||
|
||||
Our tests are written for the [nose](https://nose.readthedocs.org/en/latest/).
|
||||
At the point where you send your pull request, a command like this:
|
||||
|
||||
<pre class="terminal">
|
||||
> nosetests --with-cov --cov-report term-missing ./test
|
||||
</pre>
|
||||
|
||||
Should give output something like this:
|
||||
|
||||
<pre class="terminal">
|
||||
> ---------- coverage: platform darwin, python 2.7.2-final-0 --
|
||||
> Name Stmts Miss Cover Missing
|
||||
> ----------------------------------------------------
|
||||
> libmproxy/__init__ 0 0 100%
|
||||
> libmproxy/app 4 0 100%
|
||||
> libmproxy/cmdline 100 0 100%
|
||||
> libmproxy/controller 69 0 100%
|
||||
> libmproxy/dump 150 0 100%
|
||||
> libmproxy/encoding 39 0 100%
|
||||
> libmproxy/filt 201 0 100%
|
||||
> libmproxy/flow 891 0 100%
|
||||
> libmproxy/proxy 427 0 100%
|
||||
> libmproxy/script 27 0 100%
|
||||
> libmproxy/utils 133 0 100%
|
||||
> libmproxy/version 4 0 100%
|
||||
> ----------------------------------------------------
|
||||
> TOTAL 2045 0 100%
|
||||
> ----------------------------------------------------
|
||||
> Ran 251 tests in 11.864s
|
||||
</pre>
|
||||
|
||||
|
||||
There are exceptions to the coverage requirement - for instance, much of the
|
||||
console interface code can't sensibly be unit tested. These portions are
|
||||
excluded from coverage analysis either in the **.coveragerc** file, or using
|
||||
**#pragma no-cover** directives. To keep our coverage analysis relevant, we use
|
||||
these measures as sparingly as possible.
|
||||
|
||||
@@ -246,7 +246,7 @@ mechanism has a different way of exposing this data, so this introduces the
|
||||
second component required for working transparent proxying: a host module that
|
||||
knows how to retrieve the original destination address from the router. In
|
||||
mitmproxy, this takes the form of a built-in set of
|
||||
[modules](https://github.com/cortesi/mitmproxy/tree/master/libmproxy/platform)
|
||||
[modules](https://github.com/mitmproxy/mitmproxy/tree/master/libmproxy/platform)
|
||||
that know how to talk to each platform's redirection mechanism. Once we have
|
||||
this information, the process is fairly straight-forward.
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@ import countershape.template
|
||||
sys.path.insert(0, "..")
|
||||
from libmproxy import filt
|
||||
|
||||
MITMPROXY_SRC = "~/git/public/mitmproxy"
|
||||
MITMPROXY_SRC = "~/mitmproxy/mitmproxy"
|
||||
|
||||
if ns.options.website:
|
||||
ns.idxpath = "doc/index.html"
|
||||
|
||||
@@ -25,7 +25,7 @@ pip install /path/to/source
|
||||
</pre>
|
||||
|
||||
Note that if you're installing current git master, you will also have to
|
||||
install the current git master of [netlib](http://github.com/cortesi/netlib) by
|
||||
install the current git master of [netlib](http://github.com/mitmproxy/netlib) by
|
||||
hand.
|
||||
|
||||
## OSX
|
||||
|
||||
@@ -2,5 +2,5 @@ from countershape import Page
|
||||
|
||||
pages = [
|
||||
Page("inlinescripts.html", "Inline Scripts"),
|
||||
Page("libmproxy.html", "libmproxy")
|
||||
Page("libmproxy.html", "libmproxy"),
|
||||
]
|
||||
|
||||
@@ -7,3 +7,4 @@ 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
|
||||
|
||||
89
examples/mitmproxywrapper.py
Executable file
89
examples/mitmproxywrapper.py
Executable file
@@ -0,0 +1,89 @@
|
||||
#!/usr/bin/env python
|
||||
#
|
||||
# Helper tool to enable/disable OS X proxy and wrap mitmproxy
|
||||
#
|
||||
# Get usage information with:
|
||||
#
|
||||
# mitmproxywrapper.py -h
|
||||
#
|
||||
|
||||
import subprocess
|
||||
import re
|
||||
import argparse
|
||||
|
||||
class Wrapper(object):
|
||||
|
||||
def __init__(self, port):
|
||||
self.port = port
|
||||
self.primary_service_name = self.find_primary_service_name()
|
||||
|
||||
def run_networksetup_command(self, *arguments):
|
||||
return subprocess.check_output(['sudo', 'networksetup'] + list(arguments))
|
||||
|
||||
def proxy_state_for_service(self, service):
|
||||
state = self.run_networksetup_command('-getwebproxy', service).splitlines()
|
||||
return dict([re.findall(r'([^:]+): (.*)', line)[0] for line in state])
|
||||
|
||||
def enable_proxy_for_service(self, service):
|
||||
print 'Enabling proxy on {}...'.format(service)
|
||||
for subcommand in ['-setwebproxy', '-setsecurewebproxy']:
|
||||
self.run_networksetup_command(subcommand, service, '127.0.0.1', str(self.port))
|
||||
|
||||
def disable_proxy_for_service(self, service):
|
||||
print 'Disabling proxy on {}...'.format(service)
|
||||
for subcommand in ['-setwebproxystate', '-setsecurewebproxystate']:
|
||||
self.run_networksetup_command(subcommand, service, 'Off')
|
||||
|
||||
def interface_name_to_service_name_map(self):
|
||||
order = self.run_networksetup_command('-listnetworkserviceorder')
|
||||
mapping = re.findall(r'\(\d+\)\s(.*)$\n\(.*Device: (.+)\)$', order, re.MULTILINE)
|
||||
return dict([(b, a) for (a, b) in mapping])
|
||||
|
||||
def run_command_with_input(self, command, input):
|
||||
popen = subprocess.Popen(command, stdin=subprocess.PIPE, stdout=subprocess.PIPE)
|
||||
(stdout, stderr) = popen.communicate(input)
|
||||
return stdout
|
||||
|
||||
def primary_interace_name(self):
|
||||
scutil_script = 'get State:/Network/Global/IPv4\nd.show\n'
|
||||
stdout = self.run_command_with_input('/usr/sbin/scutil', scutil_script)
|
||||
interface, = re.findall(r'PrimaryInterface\s*:\s*(.+)', stdout)
|
||||
return interface
|
||||
|
||||
def find_primary_service_name(self):
|
||||
return self.interface_name_to_service_name_map()[self.primary_interace_name()]
|
||||
|
||||
def proxy_enabled_for_service(self, service):
|
||||
return self.proxy_state_for_service(service)['Enabled'] == 'Yes'
|
||||
|
||||
def toggle_proxy(self):
|
||||
if self.proxy_enabled_for_service(self.primary_service_name):
|
||||
self.disable_proxy_for_service(self.primary_service_name)
|
||||
else:
|
||||
self.enable_proxy_for_service(self.primary_service_name)
|
||||
|
||||
def wrap_mitmproxy(self):
|
||||
if not self.proxy_enabled_for_service(self.primary_service_name):
|
||||
self.enable_proxy_for_service(self.primary_service_name)
|
||||
|
||||
subprocess.check_call(['mitmproxy', '-p', str(self.port), '--palette', 'light'])
|
||||
|
||||
if self.proxy_enabled_for_service(self.primary_service_name):
|
||||
self.disable_proxy_for_service(self.primary_service_name)
|
||||
|
||||
@classmethod
|
||||
def main(cls):
|
||||
parser = argparse.ArgumentParser(description='Helper tool for OS X proxy configuration and mitmproxy')
|
||||
parser.add_argument('-t', '--toggle', action='store_true', help='just toggle the proxy configuration')
|
||||
parser.add_argument('-p', '--port', type=int, help='override the default port of 8080', default=8080)
|
||||
args = parser.parse_args()
|
||||
|
||||
wrapper = cls(port=args.port)
|
||||
if args.toggle:
|
||||
wrapper.toggle_proxy()
|
||||
else:
|
||||
wrapper.wrap_mitmproxy()
|
||||
|
||||
if __name__ == '__main__':
|
||||
Wrapper.main()
|
||||
|
||||
@@ -124,7 +124,7 @@ def get_common_options(options):
|
||||
except ParseException, e:
|
||||
raise OptionException(e.message)
|
||||
try:
|
||||
v = open(path, "r").read()
|
||||
v = open(path, "rb").read()
|
||||
except IOError, e:
|
||||
raise OptionException("Could not read replace file: %s"%path)
|
||||
reps.append((patt, rex, v))
|
||||
|
||||
@@ -479,7 +479,7 @@ class ConsoleMaster(flow.FlowMaster):
|
||||
def _readflow(self, path):
|
||||
path = os.path.expanduser(path)
|
||||
try:
|
||||
f = file(path, "r")
|
||||
f = file(path, "rb")
|
||||
flows = list(flow.FlowReader(f).stream())
|
||||
except (IOError, flow.FlowReadError), v:
|
||||
return True, v.strerror
|
||||
@@ -519,13 +519,14 @@ class ConsoleMaster(flow.FlowMaster):
|
||||
except:
|
||||
self.statusbar.message("Can't start editor: %s" % " ".join(c))
|
||||
else:
|
||||
data = open(name).read()
|
||||
data = open(name,"rb").read()
|
||||
self.ui.start()
|
||||
os.unlink(name)
|
||||
return data
|
||||
|
||||
def spawn_external_viewer(self, data, contenttype):
|
||||
if contenttype:
|
||||
contenttype = contenttype.split(";")[0]
|
||||
ext = mimetypes.guess_extension(contenttype) or ""
|
||||
else:
|
||||
ext = ""
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
import os, sys
|
||||
import urwid
|
||||
import common, grideditor, contentview
|
||||
from .. import utils, flow
|
||||
from .. import utils, flow, controller
|
||||
|
||||
def _mkhelp():
|
||||
text = []
|
||||
@@ -341,7 +341,12 @@ class FlowView(common.WWrap):
|
||||
conn = self.flow.request
|
||||
else:
|
||||
if not self.flow.response:
|
||||
self.flow.response = flow.Response(self.flow.request, 200, "OK", flow.ODictCaseless(), "", None)
|
||||
self.flow.response = flow.Response(
|
||||
self.flow.request,
|
||||
self.flow.request.httpversion,
|
||||
200, "OK", flow.ODictCaseless(), "", None
|
||||
)
|
||||
self.flow.response.reply = controller.DummyReply()
|
||||
conn = self.flow.response
|
||||
|
||||
self.flow.backup()
|
||||
|
||||
@@ -294,7 +294,7 @@ class GridEditor(common.WWrap):
|
||||
if p:
|
||||
try:
|
||||
p = os.path.expanduser(p)
|
||||
d = file(p, "r").read()
|
||||
d = file(p, "rb").read()
|
||||
self.walker.set_current_value(d, unescaped)
|
||||
self.walker._modified()
|
||||
except IOError, v:
|
||||
|
||||
@@ -141,7 +141,7 @@ class DumpMaster(flow.FlowMaster):
|
||||
def _readflow(self, path):
|
||||
path = os.path.expanduser(path)
|
||||
try:
|
||||
f = file(path, "r")
|
||||
f = file(path, "rb")
|
||||
flows = list(flow.FlowReader(f).stream())
|
||||
except (IOError, flow.FlowReadError), v:
|
||||
raise DumpError(v.strerror)
|
||||
|
||||
@@ -542,7 +542,7 @@ class Request(HTTPMsg):
|
||||
headers["host"] = [utils.hostport(self.scheme, self.host, self.port)]
|
||||
content = self.content
|
||||
if content:
|
||||
headers["content-length"] = [str(len(content))]
|
||||
headers["Content-Length"] = [str(len(content))]
|
||||
else:
|
||||
content = ""
|
||||
if self.close:
|
||||
@@ -737,7 +737,7 @@ class Response(HTTPMsg):
|
||||
['proxy-connection', 'transfer-encoding']
|
||||
)
|
||||
if self.content:
|
||||
headers["content-length"] = [str(len(self.content))]
|
||||
headers["Content-Length"] = [str(len(self.content))]
|
||||
proto = "HTTP/%s.%s %s %s"%(self.httpversion[0], self.httpversion[1], self.code, str(self.msg))
|
||||
data = (proto, str(headers))
|
||||
return FMT%data
|
||||
@@ -1548,7 +1548,7 @@ class FlowMaster(controller.Master):
|
||||
if f.request:
|
||||
f.request._set_replay()
|
||||
if f.request.content:
|
||||
f.request.headers["content-length"] = [str(len(f.request.content))]
|
||||
f.request.headers["Content-Length"] = [str(len(f.request.content))]
|
||||
f.response = None
|
||||
f.error = None
|
||||
self.process_new_request(f)
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
IVERSION = (0, 9)
|
||||
IVERSION = (0, 9, 1)
|
||||
VERSION = ".".join(str(i) for i in IVERSION)
|
||||
NAME = "mitmproxy"
|
||||
NAMEVERSION = NAME + " " + VERSION
|
||||
|
||||
@@ -62,12 +62,14 @@ if __name__ == '__main__':
|
||||
opts.debug = options.debug
|
||||
opts.palette = options.palette
|
||||
|
||||
if "utf" not in os.environ.get("LANG", "").lower():
|
||||
spec = ""
|
||||
for i in ["LANG", "LC_CTYPE", "LC_ALL"]:
|
||||
spec += os.environ.get(i, "").lower()
|
||||
if "utf" not in spec:
|
||||
print >> sys.stderr, "Error: mitmproxy requires a UTF console environment."
|
||||
print >> sys.stderr, "Set your LANG enviroment variable to something like en_US.UTF-8"
|
||||
sys.exit(1)
|
||||
|
||||
|
||||
m = console.ConsoleMaster(server, opts)
|
||||
try:
|
||||
m.run()
|
||||
|
||||
23
release/osx-binaries
Executable file
23
release/osx-binaries
Executable file
@@ -0,0 +1,23 @@
|
||||
#!/bin/sh
|
||||
|
||||
# Quick and dangerous script for building OSX binaries.
|
||||
|
||||
# First, have a recent checkout of the dev version of pyinstaller. Change into
|
||||
# the pyinstaller directory, and then run this script.
|
||||
|
||||
DST=/tmp/osx-mitmproxy
|
||||
MITMPROXY=~/mitmproxy/mitmproxy
|
||||
PYINST_CMD="./pyinstaller.py -F --clean"
|
||||
|
||||
rm -rf $DST
|
||||
mkdir -p $DST
|
||||
rm -rf mitmproxy
|
||||
rm -rf mitmdump
|
||||
|
||||
$PYINST_CMD $MITMPROXY/mitmproxy
|
||||
cp mitmproxy/dist/mitmproxy $DST
|
||||
|
||||
$PYINST_CMD $MITMPROXY/mitmdump
|
||||
cp mitmdump/dist/mitmdump $DST
|
||||
|
||||
cshape $MITMPROXY/doc-src $DST/doc
|
||||
@@ -1,20 +0,0 @@
|
||||
# -*- mode: python -*-
|
||||
|
||||
# Copy into the pyinstaller directory
|
||||
# ./pyinstaller.py --clean -F ./pyinstaller-mitmdump.spec
|
||||
|
||||
a = Analysis(['/Users/aldo/git/public/mitmproxy/mitmdump'],
|
||||
hiddenimports=["pyamf"],
|
||||
hookspath=None,
|
||||
runtime_hooks=None)
|
||||
pyz = PYZ(a.pure)
|
||||
exe = EXE(pyz,
|
||||
a.scripts,
|
||||
a.binaries,
|
||||
a.zipfiles,
|
||||
a.datas,
|
||||
name='mitmdump',
|
||||
debug=False,
|
||||
strip=None,
|
||||
upx=True,
|
||||
console=True )
|
||||
@@ -1,16 +0,0 @@
|
||||
# -*- mode: python -*-
|
||||
a = Analysis(['/Users/aldo/git/public/mitmproxy/mitmproxy'],
|
||||
hiddenimports=["pyamf"],
|
||||
hookspath=None,
|
||||
runtime_hooks=None)
|
||||
pyz = PYZ(a.pure)
|
||||
exe = EXE(pyz,
|
||||
a.scripts,
|
||||
a.binaries,
|
||||
a.zipfiles,
|
||||
a.datas,
|
||||
name='mitmproxy',
|
||||
debug=False,
|
||||
strip=None,
|
||||
upx=True,
|
||||
console=True )
|
||||
14
requirements.txt
Normal file
14
requirements.txt
Normal file
@@ -0,0 +1,14 @@
|
||||
Flask==0.9
|
||||
Jinja2==2.7
|
||||
MarkupSafe==0.18
|
||||
PIL==1.1.7
|
||||
Werkzeug==0.8.3
|
||||
lxml==3.2.1
|
||||
netlib==0.9
|
||||
nose==1.3.0
|
||||
pathod==0.9
|
||||
pyOpenSSL==0.13
|
||||
pyasn1==0.1.7
|
||||
requests==1.2.2
|
||||
urwid==1.1.1
|
||||
wsgiref==0.1.2
|
||||
4
setup.py
4
setup.py
@@ -79,7 +79,7 @@ setup(
|
||||
package_data = package_data,
|
||||
scripts = ["mitmproxy", "mitmdump"],
|
||||
classifiers = [
|
||||
"License :: OSI Approved :: GNU General Public License (GPL)",
|
||||
"License :: OSI Approved :: MIT License",
|
||||
"Development Status :: 5 - Production/Stable",
|
||||
"Environment :: Console",
|
||||
"Environment :: Console :: Curses",
|
||||
@@ -96,7 +96,7 @@ setup(
|
||||
"netlib>=%s"%version.VERSION,
|
||||
"urwid>=1.1",
|
||||
"pyasn1>0.1.2",
|
||||
"pyopenssl>=0.12",
|
||||
"pyopenssl>=0.13",
|
||||
"PIL",
|
||||
"lxml",
|
||||
"flask"
|
||||
|
||||
@@ -114,16 +114,16 @@ class TestContentView:
|
||||
def test_view_image(self):
|
||||
v = cv.ViewImage()
|
||||
p = tutils.test_data.path("data/image.png")
|
||||
assert v([], file(p).read(), sys.maxint)
|
||||
assert v([], file(p,"rb").read(), sys.maxint)
|
||||
|
||||
p = tutils.test_data.path("data/image.gif")
|
||||
assert v([], file(p).read(), sys.maxint)
|
||||
assert v([], file(p,"rb").read(), sys.maxint)
|
||||
|
||||
p = tutils.test_data.path("data/image-err1.jpg")
|
||||
assert v([], file(p).read(), sys.maxint)
|
||||
assert v([], file(p,"rb").read(), sys.maxint)
|
||||
|
||||
p = tutils.test_data.path("data/image.ico")
|
||||
assert v([], file(p).read(), sys.maxint)
|
||||
assert v([], file(p,"rb").read(), sys.maxint)
|
||||
|
||||
assert not v([], "flibble", sys.maxint)
|
||||
|
||||
@@ -224,22 +224,22 @@ if pyamf:
|
||||
v = cv.ViewAMF()
|
||||
|
||||
p = tutils.test_data.path("data/amf01")
|
||||
assert v([], file(p).read(), sys.maxint)
|
||||
assert v([], file(p,"rb").read(), sys.maxint)
|
||||
|
||||
p = tutils.test_data.path("data/amf02")
|
||||
assert v([], file(p).read(), sys.maxint)
|
||||
assert v([], file(p,"rb").read(), sys.maxint)
|
||||
|
||||
def test_view_amf_response():
|
||||
v = cv.ViewAMF()
|
||||
p = tutils.test_data.path("data/amf03")
|
||||
assert v([], file(p).read(), sys.maxint)
|
||||
assert v([], file(p,"rb").read(), sys.maxint)
|
||||
|
||||
if cv.ViewProtobuf.is_available():
|
||||
def test_view_protobuf_request():
|
||||
v = cv.ViewProtobuf()
|
||||
|
||||
p = tutils.test_data.path("data/protobuf01")
|
||||
content_type, output = v([], file(p).read(), sys.maxint)
|
||||
content_type, output = v([], file(p,"rb").read(), sys.maxint)
|
||||
assert content_type == "Protobuf"
|
||||
assert output[0].text == '1: "3bbc333c-e61c-433b-819a-0b9a8cc103b8"'
|
||||
|
||||
|
||||
@@ -46,7 +46,7 @@ class TestDumpMaster:
|
||||
return cs.getvalue()
|
||||
|
||||
def _flowfile(self, path):
|
||||
f = open(path, "w")
|
||||
f = open(path, "wb")
|
||||
fw = flow.FlowWriter(f)
|
||||
t = tutils.tflow_full()
|
||||
t.response = tutils.tresp(t.request)
|
||||
@@ -128,7 +128,7 @@ class TestDumpMaster:
|
||||
with tutils.tmpdir() as d:
|
||||
p = os.path.join(d, "a")
|
||||
self._dummy_cycle(1, None, "", wfile=p, verbosity=0)
|
||||
assert len(list(flow.FlowReader(open(p)).stream())) == 1
|
||||
assert len(list(flow.FlowReader(open(p,"rb")).stream())) == 1
|
||||
|
||||
def test_write_err(self):
|
||||
tutils.raises(
|
||||
|
||||
@@ -733,7 +733,7 @@ class TestFlowMaster:
|
||||
with tutils.tmpdir() as tdir:
|
||||
p = os.path.join(tdir, "foo")
|
||||
def r():
|
||||
r = flow.FlowReader(open(p))
|
||||
r = flow.FlowReader(open(p,"rb"))
|
||||
return list(r.stream())
|
||||
|
||||
s = flow.State()
|
||||
|
||||
@@ -5,7 +5,7 @@ from libmproxy.platform import pf
|
||||
class TestLookup:
|
||||
def test_simple(self):
|
||||
p = tutils.test_data.path("data/pf01")
|
||||
d = open(p).read()
|
||||
d = open(p,"rb").read()
|
||||
assert pf.lookup("192.168.1.111", 40000, d) == ("5.5.5.5", 80)
|
||||
assert not pf.lookup("192.168.1.112", 40000, d)
|
||||
assert not pf.lookup("192.168.1.111", 40001, d)
|
||||
|
||||
@@ -20,7 +20,7 @@ def tresp(req=None):
|
||||
req = treq()
|
||||
headers = flow.ODictCaseless()
|
||||
headers["header_response"] = ["svalue"]
|
||||
cert = certutils.SSLCert.from_der(file(test_data.path("data/dercert")).read())
|
||||
cert = certutils.SSLCert.from_der(file(test_data.path("data/dercert"),"rb").read())
|
||||
resp = flow.Response(req, (1, 1), 200, "message", headers, "content_response", cert)
|
||||
resp.reply = controller.DummyReply()
|
||||
return resp
|
||||
|
||||
Reference in New Issue
Block a user