diff --git a/doc-src/_layout.html b/doc-src/_layout.html
index f48f1e58e..89b14f59c 100644
--- a/doc-src/_layout.html
+++ b/doc-src/_layout.html
@@ -14,7 +14,7 @@
$!nav if this.title!="docs" else ""!$
-
+
diff --git a/doc-src/_websitelayout.html b/doc-src/_websitelayout.html
index 061e8504e..ab079c0a6 100644
--- a/doc-src/_websitelayout.html
+++ b/doc-src/_websitelayout.html
@@ -29,7 +29,7 @@
$!nav if this.title!="docs" else ""!$
- $!title if this.title!="docs" else "
mitmproxy 0.7 docs
"!$
+ $!title if this.title!="docs" else "
mitmproxy 0.8 docs
"!$
$!body!$
diff --git a/doc-src/index.html b/doc-src/index.html
index 557deafdb..3caf41eb2 100644
--- a/doc-src/index.html
+++ b/doc-src/index.html
@@ -9,6 +9,8 @@
Server-side replay
Sticky cookies and auth
Reverse proxy mode
+ Upstream Certs
+ Replacements
Anticache
Filter expressions
diff --git a/doc-src/index.py b/doc-src/index.py
index a2296e70d..17fa8b194 100644
--- a/doc-src/index.py
+++ b/doc-src/index.py
@@ -73,6 +73,8 @@ pages = [
Page("clientreplay.html", "Client-side replay"),
Page("serverreplay.html", "Server-side replay"),
Page("sticky.html", "Sticky cookies and auth"),
+ Page("upstreamcerts.html", "Upstream Certs"),
+ Page("replacements.html", "Replacements"),
Page("reverseproxy.html", "Reverse proxy mode"),
Page("anticache.html", "Anticache"),
Page("filters.html", "Filter expressions"),
diff --git a/doc-src/mitmproxy.html b/doc-src/mitmproxy.html
index 3910aa2d8..5d7d15d9a 100644
--- a/doc-src/mitmproxy.html
+++ b/doc-src/mitmproxy.html
@@ -45,19 +45,22 @@ which shows you exactly what's there without any changes. You can change modes
using the _m_ key.
-## Key/Value Editor
+## Grid Editor
-It turns out that ordered key/value data is pervasive in HTTP communications,
-so mitmproxy has a built-in editor to help edit and create this kind of data.
-There are three ways to reach the __K/V Editor__ from the __Flow View__ screen:
+Much of the data that we'd like to interact with in mitmproxy is structured.
+For instance, headers, queries and form data can all be thought of as a list of
+key/value pairs. Mitmproxy has a built-in editor that lays this type of data
+out in a grid for easy manipulation.
-- Editing request or response headers (_e_ for edit, then _h_ for headers)
-- Editing a query string (_e_ for edit, then _q_ for query)
-- Editing a URL-encoded form (_e_ for edit, then _f_ for form)
+At the moment, the Grid Editor is used in four parts of mitmproxy:
-If there is is no form or query string, an empty __K/V Editor__ will be started
-to let you add one. Here is the __K/V Editor__ showing the headers from a
-request:
+- Editing request or response headers (_e_ for edit, then _h_ for headers in flow view)
+- Editing a query string (_e_ for edit, then _q_ for query in flow view)
+- Editing a URL-encoded form (_e_ for edit, then _f_ for form in flow view)
+- Editing replacement patterns (_R_ globally)
+
+If there is is no data, an empty editor will be started to let you add some.
+Here is the editor showing the headers from a request:
@@ -67,10 +70,10 @@ you are in edit mode for the specified field:
-Modify the field as desired, and press escape or enter to exit edit mode when
-you're done. You can also add a key/value pair (_a_ key), delete a pair (_d_
-key), spawn an external editor on a field (_e_ key). Be sure to consult the
-context-sensitive help (_?_ key) for more.
+Modify the field as desired, then press escape to exit edit mode when you're
+done. You can also add a row (_a_ key), delete a row (_d_ key), spawn an
+external editor on a field (_e_ key). Be sure to consult the context-sensitive
+help (_?_ key) for more.
# Example: Interception
diff --git a/doc-src/replacements.html b/doc-src/replacements.html
new file mode 100644
index 000000000..e69de29bb
diff --git a/doc-src/upstreamcerts.html b/doc-src/upstreamcerts.html
new file mode 100644
index 000000000..804286d9b
--- /dev/null
+++ b/doc-src/upstreamcerts.html
@@ -0,0 +1,15 @@
+- command-line: _--upstream-cert_
+- mitmproxy shortcut: _o_, then _u_
+
+In its normal mode of operation, mitmproxy will use the target domain specified
+in a client's proxy request to generate an interception certificate. When
+__upstream-cert__ mode is activated a different procedure is followed: we first
+connect to the specified remote server to retrieve the server's __Common Name__
+and __Subject Alternative Names__. This feature is especially useful when the
+client specifies an IP address rather than a host name in the proxy request. If
+this is the case, we can only generate a certificate if we can establish the
+__CN__ and __SANs__ from the upstream server.
+
+Note that __upstream-cert__ mode does not work when the remote server relies on
+[Server Name Indication](http://en.wikipedia.org/wiki/Server_Name_Indication).
+Luckily, SNI is still not very widely used.
diff --git a/libmproxy/console/__init__.py b/libmproxy/console/__init__.py
index a63551609..6b480d570 100644
--- a/libmproxy/console/__init__.py
+++ b/libmproxy/console/__init__.py
@@ -168,6 +168,8 @@ class StatusBar(common.WWrap):
opts.append("norefresh")
if self.master.killextra:
opts.append("killextra")
+ if self.master.server.config.upstream_cert:
+ opts.append("upstream-cert")
if opts:
r.append("[%s]"%(":".join(opts)))
@@ -842,6 +844,7 @@ class ConsoleMaster(flow.FlowMaster):
("anticomp", "c"),
("killextra", "k"),
("norefresh", "n"),
+ ("upstream-certs", "u"),
),
self._change_options
)
@@ -882,6 +885,8 @@ class ConsoleMaster(flow.FlowMaster):
self.killextra = not self.killextra
elif a == "n":
self.refresh_server_playback = not self.refresh_server_playback
+ elif a == "u":
+ self.server.config.upstream_cert = not self.server.config.upstream_cert
def shutdown(self):
self.state.killall(self)
diff --git a/libmproxy/console/flowdetailview.py b/libmproxy/console/flowdetailview.py
index e589d01df..ad2a47033 100644
--- a/libmproxy/console/flowdetailview.py
+++ b/libmproxy/console/flowdetailview.py
@@ -55,6 +55,7 @@ class FlowDetailsView(urwid.ListBox):
text.append(urwid.Text([("head", "Server Certificate:")]))
parts = [
["Type", "%s, %s bits"%c.keyinfo],
+ ["SHA1 digest", c.digest("sha1")],
["Valid to", str(c.notafter)],
["Valid from", str(c.notbefore)],
["Serial", str(c.serial)],
diff --git a/libmproxy/console/help.py b/libmproxy/console/help.py
index 9abdcd12d..ba9c9f2ef 100644
--- a/libmproxy/console/help.py
+++ b/libmproxy/console/help.py
@@ -117,6 +117,7 @@ class HelpView(urwid.ListBox):
("q", "quit / return to flow list"),
("Q", "quit without confirm prompt"),
("P", "set reverse proxy mode"),
+ ("R", "edit replacement patterns"),
("s", "set/unset script"),
("S", "server replay"),
("t", "set sticky cookie expression"),