aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--doc-src/_nav.html2
-rw-r--r--doc-src/custom-routing.txt24
-rw-r--r--doc-src/dev/architecture.html8
-rw-r--r--doc-src/dev/index.py1
-rw-r--r--doc-src/features/reverseproxy.html3
-rw-r--r--doc-src/features/upstreamproxy.html2
-rw-r--r--doc-src/index.py1
-rw-r--r--doc-src/modes.html210
-rw-r--r--doc-src/schematics/architecture.pngbin0 -> 87365 bytes
-rw-r--r--doc-src/schematics/architecture.vsdxbin60572 -> 60922 bytes
-rw-r--r--doc-src/schematics/proxy-flowchart/proxy-flowchart.pdfbin292625 -> 0 bytes
-rw-r--r--doc-src/schematics/proxy-flowchart/proxy-flowchart.vsdxbin218325 -> 0 bytes
-rw-r--r--doc-src/schematics/proxy-modes-flowchart.pngbin0 -> 34635 bytes
-rw-r--r--doc-src/schematics/proxy-modes-regular.pngbin0 -> 18283 bytes
-rw-r--r--doc-src/schematics/proxy-modes-reverse.pngbin0 -> 16719 bytes
-rw-r--r--doc-src/schematics/proxy-modes-transparent-1.pngbin0 -> 16305 bytes
-rw-r--r--doc-src/schematics/proxy-modes-transparent-2.pngbin0 -> 23041 bytes
-rw-r--r--doc-src/schematics/proxy-modes-transparent-3.pngbin0 -> 23855 bytes
-rw-r--r--doc-src/schematics/proxy-modes-transparent-wrong.pngbin0 -> 17568 bytes
-rw-r--r--doc-src/schematics/proxy-modes-upstream.pngbin0 -> 14781 bytes
-rw-r--r--doc-src/schematics/proxy-modes.pdfbin265000 -> 335485 bytes
-rw-r--r--doc-src/schematics/proxy-modes.vsdxbin160439 -> 195186 bytes
-rw-r--r--doc-src/screenshots/ios-gateway.pngbin0 -> 154469 bytes
-rw-r--r--doc-src/screenshots/ios-manual.pngbin0 -> 196431 bytes
-rw-r--r--doc-src/screenshots/ios-reverse.pngbin0 -> 66150 bytes
-rw-r--r--libmproxy/proxy/server.py12
-rw-r--r--test/test_proxy.py15
-rw-r--r--test/test_server.py19
-rw-r--r--test/tutils.py10
29 files changed, 292 insertions, 15 deletions
diff --git a/doc-src/_nav.html b/doc-src/_nav.html
index cd70cc25..02ea68e4 100644
--- a/doc-src/_nav.html
+++ b/doc-src/_nav.html
@@ -2,6 +2,7 @@
$!nav(idxpath, this, state)!$
$!nav("install.html", this, state)!$
$!nav("howmitmproxy.html", this, state)!$
+ $!nav("modes.html", this, state)!$
<li class="nav-header">Tools</li>
$!nav("mitmproxy.html", this, state)!$
@@ -47,5 +48,6 @@
$!nav("tutorials/transparent-dhcp.html", this, state)!$
<li class="nav-header">Hacking</li>
+ $!nav("dev/architecture.html", this, state)!$
$!nav("dev/testing.html", this, state)!$
</ul>
diff --git a/doc-src/custom-routing.txt b/doc-src/custom-routing.txt
new file mode 100644
index 00000000..2ba2281f
--- /dev/null
+++ b/doc-src/custom-routing.txt
@@ -0,0 +1,24 @@
+# Adapted from http://tldp.org/HOWTO/TransparentProxy-6.html (6.2 Second method)
+# Note that the choice of firewall mark (3) and routing table (2) was fairly arbitrary.
+# If you are already using policy routing or firewall marking for some other purpose,
+# make sure you choose unique numbers here. Otherwise, don't worry about it.
+
+
+
+# On the router, run
+
+PROXY_IP=192.168.1.100
+TARGET_IP=192.168.1.110
+
+iptables -t mangle -A PREROUTING -j ACCEPT -p tcp -m multiport --dports 80,443 -s ! $TARGET_IP
+# Alternative to MITM the whole network:
+# iptables -t mangle -A PREROUTING -j ACCEPT -p tcp -m multiport --dports 80,443 -s $PROXY_IP
+iptables -t mangle -A PREROUTING -j MARK --set-mark 3 -p tcp -m multiport --dports 80,443
+ip rule add fwmark 3 table 2
+ip route add default via $PROXY_IP dev br0 table 2
+
+
+
+# On the proxy machine, run
+
+iptables -A PREROUTING -t nat -i eth0 -p tcp -m multiport --dports 80,443 -j REDIRECT --to-port 8080
diff --git a/doc-src/dev/architecture.html b/doc-src/dev/architecture.html
new file mode 100644
index 00000000..8ab8821f
--- /dev/null
+++ b/doc-src/dev/architecture.html
@@ -0,0 +1,8 @@
+To give you a better understanding of how mitmproxy works, mitmproxy's high-level architecture is detailed
+in the following graphic:
+
+<img src="@!urlTo('schematics/architecture.png')!@">
+
+<a href="@!urlTo('schematics/architecture.pdf')!@">(architecture.pdf)</a>
+<p>Please don't refrain from asking any further
+questions on the mailing list, the IRC channel or the GitHub issue tracker.</p> \ No newline at end of file
diff --git a/doc-src/dev/index.py b/doc-src/dev/index.py
index 001c2b89..bb7872c7 100644
--- a/doc-src/dev/index.py
+++ b/doc-src/dev/index.py
@@ -2,5 +2,6 @@ from countershape import Page
pages = [
Page("testing.html", "Testing"),
+ Page("architecture.html", "Architecture"),
# Page("addingviews.html", "Writing Content Views"),
]
diff --git a/doc-src/features/reverseproxy.html b/doc-src/features/reverseproxy.html
index 7ad1c26c..e6de4f33 100644
--- a/doc-src/features/reverseproxy.html
+++ b/doc-src/features/reverseproxy.html
@@ -4,9 +4,6 @@ them to the specified upstream server. This is in contrast to
<a href="@!urlTo("upstreamproxy.html")!@">upstream proxy mode</a>, in which
mitmproxy forwards HTTP proxy requests to an upstream proxy server.
-Note that the displayed URL for flows in this mode will use the value of the
-__Host__ header field from the request, not the reverse proxy server.
-
<table class="table">
<tbody>
<tr>
diff --git a/doc-src/features/upstreamproxy.html b/doc-src/features/upstreamproxy.html
index 5b9c2289..6039f4df 100644
--- a/doc-src/features/upstreamproxy.html
+++ b/doc-src/features/upstreamproxy.html
@@ -7,7 +7,7 @@ mitmproxy forwards ordinary HTTP requests to an upstream server.
<table class="table">
<tbody>
<tr>
- <th width="20%">command-line</th> <td>-U http[s]://hostname[:port]</td>
+ <th width="20%">command-line</th> <td>-U http://hostname[:port]</td>
</tr>
<tr>
<th>mitmproxy shortcut</th> <td><b>U</b></td>
diff --git a/doc-src/index.py b/doc-src/index.py
index f222de14..b7ab9995 100644
--- a/doc-src/index.py
+++ b/doc-src/index.py
@@ -79,6 +79,7 @@ pages = [
Page("mitmproxy.html", "mitmproxy"),
Page("mitmdump.html", "mitmdump"),
Page("howmitmproxy.html", "How mitmproxy works"),
+ Page("modes.html", "Modes of Operation"),
Page("ssl.html", "Overview"),
Directory("certinstall"),
diff --git a/doc-src/modes.html b/doc-src/modes.html
new file mode 100644
index 00000000..77bd1b05
--- /dev/null
+++ b/doc-src/modes.html
@@ -0,0 +1,210 @@
+Mitmproxy comes with several modes of operation, which allow you to use mitmproxy in a variety of scenarios.
+This documents briefly explains each mode and possible setups.
+<hr>
+Mitmproxy has four modes of operation:
+<ul>
+ <li>Regular Mode (this is what you get by default)</li>
+ <li>Transparent Mode</li>
+ <li>Reverse Proxy Mode</li>
+ <li>Upstream Proxy Mode</li>
+</ul>
+
+<p>Now, which one should you pick? Use this flow chart:
+</p>
+
+<img src="@!urlTo('schematics/proxy-modes-flowchart.png')!@"><br><br>
+
+<div class="page-header">
+ <h1>Regular Proxy</h1>
+</div>
+
+Mitmproxy's regular mode it the most simple one and the easiest to set up.
+
+<ol>
+ <li>Start mitmproxy.</li>
+ <li>Configure your client to use mitmproxy. This means that you either adjust the proxy setting of your local browser
+ or point an external device to your proxy (which should look like
+ <a href="@!urlTo('screenshots/ios-manual.png')!@">this</a>).</li>
+ <li>Quick Check: You can already visit an unencrypted HTTP site over the proxy.</li>
+ <li>Open the magic domain <strong>mitm.it</strong> and install the certificate for your device.</li>
+</ol>
+
+<div class="well">
+ <strong>Heads Up:</strong> Unfortunately, some applications prefer to bypass the HTTP proxy settings of the system -
+ Android applications are a common example. In these cases, you need to use mitmproxy's transparent mode.
+</div>
+
+<p>If you are proxying an external device, your network will probably look like this:</p>
+<img src="@!urlTo('schematics/proxy-modes-regular.png')!@">
+<br><br>
+<p>The square brackets signify the source and destination IP addresses. Your client explicitly connects
+ to mitmproxy and mitmproxy explicitly connects to the target server.
+</p>
+
+<div class="page-header">
+ <h1>Transparent Proxy</h1>
+</div>
+
+When a transparent proxy is used, traffic is redirected into a proxy at the network layer, without any client
+configuration being required. This makes transparent proxying ideal for those situations where you can't change client
+behaviour. The basic principle is that mitmproxy sits somewhere on the line from the client to the internet and
+transparently intercepts the request. In the graphic below, a machine running mitmproxy has been inserted between
+the router and the internet:
+
+<a href="@!urlTo('schematics/proxy-modes-transparent-1.png')!@">
+ <img src="@!urlTo('schematics/proxy-modes-transparent-1.png')!@"></a>
+<p>The square brackets signify the source and destination IP addresses. Round brackets mark the next
+ hop on the <strong>Ethernet</strong>/data link layer. This distinction is important to make: When the packet arrives
+ at the mitmproxy machine, it must still be addressed to the target server. In other words: A simple IP redirect on
+ the router does not work - this would remove the target information, leaving mitmproxy unable to
+ determine the real destination.
+</p>
+<a href="@!urlTo('schematics/proxy-modes-transparent-wrong.png')!@">
+ <img src="@!urlTo('schematics/proxy-modes-transparent-wrong.png')!@"></a>
+
+<h2>Common Configurations</h2>
+
+The first graphic is a little bit idealistic: Usually, you'll have your local wireless lan network and no
+machines between your router and the internet. Fortunately, there are other ways to configure your network:
+(a) Configuring the client to use a custom gateway/router/"next hop", (b) Implementing custom routing on the router
+or (c) setting up a separate wireless network router which gets proxied.
+There are of course other options, but we'll look at these three. In most cases, setting (a) is recommended due to its
+ease of use.
+
+<h3>(a) Custom Gateway</h3>
+
+<p>Looking at your local home network, it's clear what happens if you enter "example.com" into your address bar: After you
+press enter, your OS sends a packet to your router, which then sends this to your ISP, which then sends it to some
+Tier-1 carrier, which then sends it... I think you get the idea. The important part for us is the first step here:
+Your machine is configured to use your router as the next hop. Your router certainly doesn't host example.com, but your
+machine knows that your router will forward it upstream. On the technical level, your router probably provides a DHCP
+server, which instructs all clients to use his address as the <em>Default Gateway</em> for connections that leave the
+current subnet (your local network).</p>
+<p>
+How does this help us? Here comes our trick: By configuring the client to use our machine as its Gateway, all traffic
+will be sent to our machine, which then forwards it to the router. This provides us with the scenario we'd like to have,
+namely packets on our doorstep that are addressed for someone else:
+</p>
+<a href="@!urlTo('schematics/proxy-modes-transparent-2.png')!@">
+ <img src="@!urlTo('schematics/proxy-modes-transparent-2.png')!@"></a>
+
+Given this concept, we can set up mitmproxy:
+<ol>
+ <li>Configure your proxy machine for transparent mode.<br>You can find instructions
+ in the <em>Transparent Proxying</em> section of the mitmproxy docs.</li>
+ <li>Configure your client to use your proxy machine's IP as the default gateway. This setting is usually called
+ <em>Standard Gateway, Router</em> or something along these lines
+ (<a href="@!urlTo('screenshots/ios-gateway.png')!@">iOS screenshot</a>).</li>
+ <li>Quick Check: You can already visit an unencrypted HTTP site over the proxy.</li>
+ <li>Open the magic domain <strong>mitm.it</strong> and install the certificate for your device.</li>
+</ol>
+
+<div class="well">
+ <strong style="text-align: center; display: block">Troubleshooting Transparent Mode</strong>
+ <p>Wrong transparent mode configurations are a frequent source of
+ error. If it doesn't work for you, try the following things:</p>
+ <ul>
+ <li>Open mitmproxy's event log (press `e`) - can you spot clientconnect messages?
+ If not, the packets are not arriving at the proxy. A common source is the occurence of ICMP redirects,
+ which means that your machine is telling the client that there's a faster way to the internet by contacting
+ your router directly (see the <em>Transparent Proxying</em> section on how to disable them). If in doubt,
+ <a href="https://wireshark.org/">Wireshark</a> may help you to see whether something arrives at your machine
+ or not.
+ </li>
+ <li>
+ Have you explicitly configured an HTTP proxy on your device? You do not need mitmproxy's transparent mode
+ then, just start mitmproxy normally. Explicitly setting a proxy and transparent mode contradict each other,
+ settle for one. Do not explicitly redirect traffic to mitmproxy anywhere except for the Gateway setting.
+ </li>
+ <li>
+ Re-check the instructions in the <em>Transparent Proxying</em> section. Anything you missed?
+ </li>
+ </ul>
+ If you encounter any other pitfalls that should be listed here, please let us know!
+</div>
+
+<h3>(b) Custom Routing</h3>
+
+Custom routing is a fairly advanced setup which we'll only document briefly here.
+First and foremost, it usually requires root on your router. The basic idea is to teach your router a custom routing
+table that says "for requests from ip X, the proxy machine is the next gateway".
+
+<a href="@!urlTo('schematics/proxy-modes-transparent-3.png')!@">
+ <img src="@!urlTo('schematics/proxy-modes-transparent-3.png')!@"></a>
+
+For this setup, we expect you to have a basic understanding of networking in general. In short, you should get started
+with <a href="@!urlTo('custom-routing.txt')!@">these routing commands</a>. The Troubleshooting part directly above this
+section might be helpful for you as well.
+
+<h3>(c) Separate Network</h3>
+
+Setting up a separate network using a cheap router might be a viable option, too. Such a configuration mostly resembles
+the idealistic graphic from the beginning (Variant 1). Take a look at the
+<a href="@!urlTo('tutorials/transparent-dhcp.html')!@">Transparently proxify virtual machines</a> tutorial to see how
+such a network could be implemented. The troubleshooting section for custom gateways may be helpful for you, too.
+
+
+<div class="page-header">
+ <h1>Reverse Proxy</h1>
+</div>
+
+Mitmproxy is usually used with a client that uses the proxy to access the Internet. Using reverse proxy mode, you can
+use mitmproxy to represent a server:
+
+<a href="@!urlTo('schematics/proxy-modes-reverse.png')!@">
+ <img src="@!urlTo('schematics/proxy-modes-reverse.png')!@"></a>
+
+There are various use-cases:
+<ul>
+<li>
+ Say you have an internal API running at http://example.local/. You could now setup mitmproxy in
+ reverse proxy mode at http://debug.example.local/ and dynamically point clients to this new API endpoint,
+ which provides clients with the same data and you with debug information. Similarly, you could move your real server
+ to a different ip/port and setup mitmproxy at the original place to debug all sessions.
+</li>
+<li>
+ Say you're a web developer working on example.com (with a development version running on localhost:8000).
+ You can modify your hosts file so that example.com points to 127.0.0.1 and then run mitmproxy in reverse proxy
+ mode on port 80. You can test your app on the example.com domain and get all requests recorded in mitmproxy.
+</li>
+<li>
+ Say you have some toy project that should get SSL support. Simply setup mitmproxy with SSL termination and you're
+ done (<code>mitmdump -p 443 -R https2http://localhost:80/</code>). There are better tools for this specific task (we don't
+ have C performance obviously), but it's definitely a nice and very quick way to setup an SSL-speaking server.
+</li>
+<li>
+ Want to add a non-SSL-capable compression proxy in front of your server? You could even spawn a mitmproxy instance
+ that terminates SSL (https2http://...), point it to the compression proxy and let the compression proxy point
+ to a SSL-initiating mitmproxy (http2https://...), which then points to the real server. As you see, it's a fairly
+ flexible thing.
+</li>
+</ul>
+
+<p>
+Please note that cloning Google by using <code>mitmproxy -R http://google.com/</code> does <em>not</em> really work
+(as in <a href="@!urlTo('screenshots/ios-reverse.png')!@">this screenshot</a>).
+This may work for the first request, but the HTML remains unchanged: As soon as the user clicks on an non-relative URL
+(or downloads a non-relative image resource), they speak with Google directly again.
+</p>
+<p>
+ On another note, mitmproxy either supports an HTTP or an HTTPS upstream server, not both at the same time. You can
+ simply work around this by spawning a second mitmproxy instance. Each instance listens to one port and talks to one
+ port.
+</p>
+
+<div class="page-header">
+ <h1>Upstream Proxy</h1>
+</div>
+
+<p>
+If you want to add mitmproxy in front of a different proxy appliance, you can use mitmproxy's upstream mode.
+In upstream mode, all requests are unconditionally transferred to an upstream proxy or your choice.
+</p>
+
+<a href="@!urlTo('schematics/proxy-modes-upstream.png')!@">
+ <img src="@!urlTo('schematics/proxy-modes-upstream.png')!@"></a>
+
+<p>
+mitmproxy supports both explicit HTTP and explicit HTTPS in upstream proxy mode. You could in theory chain multiple
+mitmproxy instances in a row, but that doesn't make any sense in practice (i.e. outside of our tests).
+</p> \ No newline at end of file
diff --git a/doc-src/schematics/architecture.png b/doc-src/schematics/architecture.png
new file mode 100644
index 00000000..67d6c718
--- /dev/null
+++ b/doc-src/schematics/architecture.png
Binary files differ
diff --git a/doc-src/schematics/architecture.vsdx b/doc-src/schematics/architecture.vsdx
index 9820434a..c4ff13d2 100644
--- a/doc-src/schematics/architecture.vsdx
+++ b/doc-src/schematics/architecture.vsdx
Binary files differ
diff --git a/doc-src/schematics/proxy-flowchart/proxy-flowchart.pdf b/doc-src/schematics/proxy-flowchart/proxy-flowchart.pdf
deleted file mode 100644
index ae98eea3..00000000
--- a/doc-src/schematics/proxy-flowchart/proxy-flowchart.pdf
+++ /dev/null
Binary files differ
diff --git a/doc-src/schematics/proxy-flowchart/proxy-flowchart.vsdx b/doc-src/schematics/proxy-flowchart/proxy-flowchart.vsdx
deleted file mode 100644
index 4d75f49f..00000000
--- a/doc-src/schematics/proxy-flowchart/proxy-flowchart.vsdx
+++ /dev/null
Binary files differ
diff --git a/doc-src/schematics/proxy-modes-flowchart.png b/doc-src/schematics/proxy-modes-flowchart.png
new file mode 100644
index 00000000..716b5ee2
--- /dev/null
+++ b/doc-src/schematics/proxy-modes-flowchart.png
Binary files differ
diff --git a/doc-src/schematics/proxy-modes-regular.png b/doc-src/schematics/proxy-modes-regular.png
new file mode 100644
index 00000000..95bada08
--- /dev/null
+++ b/doc-src/schematics/proxy-modes-regular.png
Binary files differ
diff --git a/doc-src/schematics/proxy-modes-reverse.png b/doc-src/schematics/proxy-modes-reverse.png
new file mode 100644
index 00000000..071d3fc8
--- /dev/null
+++ b/doc-src/schematics/proxy-modes-reverse.png
Binary files differ
diff --git a/doc-src/schematics/proxy-modes-transparent-1.png b/doc-src/schematics/proxy-modes-transparent-1.png
new file mode 100644
index 00000000..c2027432
--- /dev/null
+++ b/doc-src/schematics/proxy-modes-transparent-1.png
Binary files differ
diff --git a/doc-src/schematics/proxy-modes-transparent-2.png b/doc-src/schematics/proxy-modes-transparent-2.png
new file mode 100644
index 00000000..1129e343
--- /dev/null
+++ b/doc-src/schematics/proxy-modes-transparent-2.png
Binary files differ
diff --git a/doc-src/schematics/proxy-modes-transparent-3.png b/doc-src/schematics/proxy-modes-transparent-3.png
new file mode 100644
index 00000000..ee26cb4f
--- /dev/null
+++ b/doc-src/schematics/proxy-modes-transparent-3.png
Binary files differ
diff --git a/doc-src/schematics/proxy-modes-transparent-wrong.png b/doc-src/schematics/proxy-modes-transparent-wrong.png
new file mode 100644
index 00000000..6bac491f
--- /dev/null
+++ b/doc-src/schematics/proxy-modes-transparent-wrong.png
Binary files differ
diff --git a/doc-src/schematics/proxy-modes-upstream.png b/doc-src/schematics/proxy-modes-upstream.png
new file mode 100644
index 00000000..d40a6494
--- /dev/null
+++ b/doc-src/schematics/proxy-modes-upstream.png
Binary files differ
diff --git a/doc-src/schematics/proxy-modes.pdf b/doc-src/schematics/proxy-modes.pdf
index d1cf97eb..f07ea05e 100644
--- a/doc-src/schematics/proxy-modes.pdf
+++ b/doc-src/schematics/proxy-modes.pdf
Binary files differ
diff --git a/doc-src/schematics/proxy-modes.vsdx b/doc-src/schematics/proxy-modes.vsdx
index ae76f80b..74d425fc 100644
--- a/doc-src/schematics/proxy-modes.vsdx
+++ b/doc-src/schematics/proxy-modes.vsdx
Binary files differ
diff --git a/doc-src/screenshots/ios-gateway.png b/doc-src/screenshots/ios-gateway.png
new file mode 100644
index 00000000..2489cba3
--- /dev/null
+++ b/doc-src/screenshots/ios-gateway.png
Binary files differ
diff --git a/doc-src/screenshots/ios-manual.png b/doc-src/screenshots/ios-manual.png
new file mode 100644
index 00000000..3977acfe
--- /dev/null
+++ b/doc-src/screenshots/ios-manual.png
Binary files differ
diff --git a/doc-src/screenshots/ios-reverse.png b/doc-src/screenshots/ios-reverse.png
new file mode 100644
index 00000000..6ab5b7c0
--- /dev/null
+++ b/doc-src/screenshots/ios-reverse.png
Binary files differ
diff --git a/libmproxy/proxy/server.py b/libmproxy/proxy/server.py
index aacc908e..31c50fce 100644
--- a/libmproxy/proxy/server.py
+++ b/libmproxy/proxy/server.py
@@ -68,9 +68,9 @@ class ConnectionHandler:
self.sni = None
def handle(self):
- self.log("clientconnect", "info")
-
try:
+ self.log("clientconnect", "info")
+
# Can we already identify the target server and connect to it?
client_ssl, server_ssl = False, False
if self.config.get_upstream_server:
@@ -94,6 +94,10 @@ class ConnectionHandler:
# Delegate handling to the protocol handler
protocol_handler(self.conntype)(self).handle_messages()
+ self.del_server_connection()
+ self.log("clientdisconnect", "info")
+ self.channel.tell("clientdisconnect", self)
+
except ProxyError as e:
protocol_handler(self.conntype)(self).handle_error(e)
except Exception:
@@ -104,10 +108,6 @@ class ConnectionHandler:
print >> sys.stderr, "mitmproxy has crashed!"
print >> sys.stderr, "Please lodge a bug report at: https://github.com/mitmproxy/mitmproxy"
- self.del_server_connection()
- self.log("clientdisconnect", "info")
- self.channel.tell("clientdisconnect", self)
-
def del_server_connection(self):
"""
Deletes (and closes) an existing server connection.
diff --git a/test/test_proxy.py b/test/test_proxy.py
index 2f455992..d13c7ba9 100644
--- a/test/test_proxy.py
+++ b/test/test_proxy.py
@@ -3,7 +3,7 @@ from libmproxy import cmdline
from libmproxy.proxy.config import process_proxy_options
from libmproxy.proxy.connection import ServerConnection
from libmproxy.proxy.primitives import ProxyError
-from libmproxy.proxy.server import DummyServer, ProxyServer
+from libmproxy.proxy.server import DummyServer, ProxyServer, ConnectionHandler
import tutils
from libpathod import test
from netlib import http, tcp
@@ -128,6 +128,12 @@ class TestProxyServer:
opts = parser.parse_args(args=[])
tutils.raises("error starting proxy server", ProxyServer, opts, 1)
+ def test_err_2(self):
+ parser = argparse.ArgumentParser()
+ cmdline.common_options(parser)
+ opts = parser.parse_args(args=[])
+ tutils.raises("error starting proxy server", ProxyServer, opts, 8080, "invalidhost")
+
class TestDummyServer:
def test_simple(self):
@@ -135,3 +141,10 @@ class TestDummyServer:
d.start_slave()
d.shutdown()
+
+class TestConnectionHandler:
+ def test_fatal_error(self):
+ config = dict(get_upstream_server=mock.Mock(side_effect=RuntimeError))
+ c = ConnectionHandler(config, mock.MagicMock(), ("127.0.0.1", 8080), None, mock.MagicMock(), None)
+ with tutils.capture_stderr(c.handle) as output:
+ assert "mitmproxy has crashed" in output
diff --git a/test/test_server.py b/test/test_server.py
index a6d591ed..d33bcc89 100644
--- a/test/test_server.py
+++ b/test/test_server.py
@@ -199,11 +199,22 @@ class TestHTTP(tservers.HTTPProxTest, CommonMixin, AppMixin):
connection.connect(("127.0.0.1", self.proxy.port))
spec = '301:h"Transfer-Encoding"="chunked":r:b"0\\r\\n\\r\\n"'
connection.send("GET http://localhost:%d/p/%s HTTP/1.1\r\n"%(self.server.port, spec))
- connection.send("\r\n");
+ connection.send("\r\n")
resp = connection.recv(50000)
connection.close()
assert "content-length" in resp.lower()
+ def test_stream(self):
+ self.master.set_stream_large_bodies(1024 * 2)
+
+ self.pathod("200:b@1k")
+ assert not self.master.state.view[-1].response.stream
+ assert len(self.master.state.view[-1].response.content) == 1024 * 1
+
+ self.pathod("200:b@3k")
+ assert self.master.state.view[-1].response.stream
+ assert self.master.state.view[-1].response.content == CONTENT_MISSING
+ self.master.set_stream_large_bodies(None)
class TestHTTPAuth(tservers.HTTPProxTest):
authenticator = http_auth.BasicProxyAuth(http_auth.PassManSingleUser("test", "test"), "realm")
@@ -313,7 +324,7 @@ class TestProxy(tservers.HTTPProxTest):
# call pathod server, wait a second to complete the request
connection.send("GET http://localhost:%d/p/304:b@1k HTTP/1.1\r\n"%self.server.port)
time.sleep(1)
- connection.send("\r\n");
+ connection.send("\r\n")
connection.recv(50000)
connection.close()
@@ -340,10 +351,10 @@ class TestProxy(tservers.HTTPProxTest):
connection = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
connection.connect(("localhost", self.proxy.port))
connection.send("GET http://localhost:%d/p/304:b@1k HTTP/1.1\r\n"%self.server.port)
- connection.send("\r\n");
+ connection.send("\r\n")
connection.recv(5000)
connection.send("GET http://localhost:%d/p/304:b@1k HTTP/1.1\r\n"%self.server.port)
- connection.send("\r\n");
+ connection.send("\r\n")
connection.recv(5000)
connection.close()
diff --git a/test/tutils.py b/test/tutils.py
index 84a9bba0..69f79a91 100644
--- a/test/tutils.py
+++ b/test/tutils.py
@@ -1,5 +1,7 @@
+from cStringIO import StringIO
import os, shutil, tempfile, argparse
from contextlib import contextmanager
+import sys
from libmproxy import flow, utils, controller
from libmproxy.protocol import http
from libmproxy.proxy.connection import ClientConnection, ServerConnection
@@ -189,4 +191,12 @@ def raises(exc, obj, *args, **kwargs):
)
raise AssertionError("No exception raised.")
+
+@contextmanager
+def capture_stderr(command, *args, **kwargs):
+ out, sys.stderr = sys.stderr, StringIO()
+ command(*args, **kwargs)
+ yield sys.stderr.getvalue()
+ sys.stderr = out
+
test_data = utils.Data(__name__)