diff --git a/docs/src/content/_index.md b/docs/src/content/_index.md index 6283343d4..89ee79744 100644 --- a/docs/src/content/_index.md +++ b/docs/src/content/_index.md @@ -8,20 +8,7 @@ menu: # Introduction -The mitmproxy project's tools are a set of front-ends that expose common -underlying functionality. - -**mitmproxy** is an interactive, SSL/TLS-capable intercepting proxy with a console interface for HTTP/1, HTTP/2, and WebSockets. - -**mitmdump** is the command-line version of mitmproxy. Think tcpdump for HTTP. - -**mitmweb** is a web-based interface for mitmproxy. - -Documentation, tutorials and distribution packages can be found on the -[mitmproxy website](https://mitmproxy.org). - -Development information and our source code can be found in our -[GitHub repository](https://github.com/mitmproxy/mitmproxy). +mitmproxy is a set of tools that provide an interactive, SSL/TLS-capable intercepting proxy for HTTP/1, HTTP/2, and WebSockets. ## Features @@ -34,4 +21,114 @@ Development information and our source code can be found in our - Transparent proxy mode on macOS and Linux - Make scripted changes to HTTP traffic using Python - SSL/TLS certificates for interception are generated on the fly -- And much, much more... +- And [much, much more...]({{< relref "concepts-advancedfeatures">}}) + + +## 3 Powerful Core Tools + +The mitmproxy project's tools are a set of front-ends that expose common +underlying functionality. When we talk about "mitmproxy" we usually refer to any of the three tools - they +are just different front-ends to the same core proxy. + +**mitmproxy** is an interactive, SSL/TLS-capable intercepting proxy with a console interface for HTTP/1, HTTP/2, and WebSockets. + +**mitmdump** is the command-line version of mitmproxy. Think tcpdump for HTTP. + +**mitmweb** is a web-based interface for mitmproxy. + +Distribution packages can be found on the [mitmproxy website](https://mitmproxy.org). +Development information and our source code can be found in our +[GitHub repository](https://github.com/mitmproxy/mitmproxy). + +### mitmproxy + +{{< figure src="/screenshots/mitmproxy.png" >}} + +**mitmproxy** is a console tool that allows interactive examination and +modification of HTTP traffic. It differs from mitmdump in that all flows are +kept in memory, which means that it's intended for taking and manipulating +small-ish samples. Use the `?` shortcut key to view, context-sensitive +documentation from any **mitmproxy** screen. + +--- + +### mitmweb + +{{< figure src="/screenshots/mitmweb.png" >}} + +**mitmweb** is mitmproxy's web-based user interface that allows +interactive examination and modification of HTTP traffic. Like +mitmproxy, it differs from mitmdump in that all flows are kept in +memory, which means that it's intended for taking and manipulating +small-ish samples. + +{{% note %}} +Mitmweb is currently in beta. We consider it stable for all features +currently exposed in the UI, but it still misses a lot of mitmproxy's +features. +{{% /note %}} + +--- + +### mitmdump + +**mitmdump** is the command-line companion to mitmproxy. It provides +tcpdump-like functionality to let you view, record, and programmatically +transform HTTP traffic. See the `--help` flag output for complete +documentation. + + +#### Example: Saving traffic + +```bash +mitmdump -w outfile +``` + +Start up mitmdump in proxy mode, and write all traffic to **outfile**. + +#### Filtering saved traffic + +```bash +mitmdump -nr infile -w outfile "~m post" +``` + +Start mitmdump without binding to the proxy port (`-n`), read all flows +from infile, apply the specified filter expression (only match POSTs), +and write to outfile. + +#### Client replay + +```bash +mitmdump -nC outfile +``` + +Start mitmdump without binding to the proxy port (`-n`), then replay all +requests from outfile (`-C filename`). Flags combine in the obvious way, +so you can replay requests from one file, and write the resulting flows +to another: + +```bash +mitmdump -nC srcfile -w dstfile +``` + +See the [client-side replay]({{< relref "concepts-advancedfeatures#client-side-replay" +>}}) section for more information. + +#### Running a script + +```bash +mitmdump -s examples/simple/add_header.py +``` + +This runs the **add_header.py** example script, which simply adds a new +header to all responses. + +#### Scripted data transformation + +```bash +mitmdump -ns examples/simple/add_header.py -r srcfile -w dstfile +``` + +This command loads flows from **srcfile**, transforms it according to +the specified script, then writes it back to **dstfile**. + diff --git a/docs/src/content/addons-overview.md b/docs/src/content/addons-overview.md index cc35eaa28..e286d6efc 100644 --- a/docs/src/content/addons-overview.md +++ b/docs/src/content/addons-overview.md @@ -20,8 +20,8 @@ Addons are an exceptionally powerful part of mitmproxy. In fact, much of mitmproxy's own functionality is defined in [a suite of built-in addons](https://github.com/mitmproxy/mitmproxy/tree/master/mitmproxy/addons), implementing everything from functionality like [anticaching]({{< relref -"overview-features#anticache" >}}) and [sticky cookies]({{< relref -"overview-features#sticky-cookies" >}}) to our onboarding webapp. The built-in +"concepts-advancedfeatures#anticache" >}}) and [sticky cookies]({{< relref +"concepts-advancedfeatures#sticky-cookies" >}}) to our onboarding webapp. The built-in addons make for instructive reading, and you will quickly see that quite complex functionality can often boil down to a very small, completely self-contained modules. Mitmproxy provides the exact same set of facilities it uses for its own diff --git a/docs/src/content/overview-features.md b/docs/src/content/concepts-advancedfeatures.md similarity index 99% rename from docs/src/content/overview-features.md rename to docs/src/content/concepts-advancedfeatures.md index 6723c6589..f63e69c0f 100644 --- a/docs/src/content/overview-features.md +++ b/docs/src/content/concepts-advancedfeatures.md @@ -1,12 +1,11 @@ --- -title: "Features" -menu: "overview" +title: "Advanced features" menu: - overview: + concepts: weight: 4 --- -# Mitmproxy Core Features +# Mitmproxy Advanced Features - [Anticache](#anticache) @@ -79,7 +78,7 @@ Pattern | Description If *local-path* is a file, this file will always be served. File changes will be reflected immediately, there is no caching. If *local-path* is a directory, *url-regex* is used to split the request URL in two parts and part on the right is appended to *local-path*, excluding the query string. -However, if *url-regex* contains a regex capturing group, this behavior changes and the first capturing group is appended instead (and query strings are not stripped). +However, if *url-regex* contains a regex capturing group, this behavior changes and the first capturing group is appended instead (and query strings are not stripped). Special characters are mapped to `_`. If the file cannot be found, `/index.html` is appended and we try again. Directory traversal outside of the originally specified directory is not possible. To illustrate this, consider the following example which maps all requests for `example.org/css*` to the local directory `~/static-css`. @@ -98,7 +97,7 @@ Served File: Preferred: ~/static-css -If the file depends on the query string, we can use regex capturing groups. In this example, all `GET` requests for +If the file depends on the query string, we can use regex capturing groups. In this example, all `GET` requests for `example.org/index.php?page=` are mapped to `~/static-dir/`:
diff --git a/docs/src/content/concepts-howmitmproxyworks.md b/docs/src/content/concepts-howmitmproxyworks.md
index e8d41cb0d..a93843b22 100644
--- a/docs/src/content/concepts-howmitmproxyworks.md
+++ b/docs/src/content/concepts-howmitmproxyworks.md
@@ -100,7 +100,7 @@ information to initiate the pipe, even though it doesn't reveal the
 remote hostname.
 
 Mitmproxy has a cunning mechanism that smooths this over - [upstream certificate
-sniffing]({{< relref "overview-features#upstream-certificates" >}}). As soon as
+sniffing]({{< relref "concepts-advancedfeatures#upstream-certificates" >}}). As soon as
 we see the CONNECT request, we pause the client part of the conversation, and
 initiate a simultaneous connection to the server. We complete the TLS handshake
 with the server, and inspect the certificates it used. Now, we use the Common
diff --git a/docs/src/content/howto-ignoredomains.md b/docs/src/content/howto-ignoredomains.md
index e2bb222cf..262d0f8ec 100644
--- a/docs/src/content/howto-ignoredomains.md
+++ b/docs/src/content/howto-ignoredomains.md
@@ -21,7 +21,7 @@ mitmproxy's interception mechanism:
 
 If you want to peek into (SSL-protected) non-HTTP connections, check out the
 **tcp_proxy** feature. If you want to ignore traffic from mitmproxy's processing
-because of large response bodies, take a look at the [streaming]({{< relref "overview-features#streaming" >}}) feature.
+because of large response bodies, take a look at the [streaming]({{< relref "concepts-advancedfeatures#streaming" >}}) feature.
 
 
 ## ignore_hosts
diff --git a/docs/src/content/mitmproxytutorial-interceptrequests.md b/docs/src/content/mitmproxytutorial-interceptrequests.md
index 542cd60a3..67612e562 100644
--- a/docs/src/content/mitmproxytutorial-interceptrequests.md
+++ b/docs/src/content/mitmproxytutorial-interceptrequests.md
@@ -1,12 +1,12 @@
 ---
-title: "Intercepting Requests"
+title: "Intercept Requests"
 menu:
     mitmproxytutorial:
         weight: 2
 has_asciinema: true
 ---
 
-# Intercepting Requests
+# Intercept Requests
 
 A powerful feature of mitmproxy is the interception of requests.
 An intercepted request is paused so that the user can modify (or discard) the request before sending it to the server.
@@ -14,7 +14,7 @@ mitmproxy's `set intercept` command configures interceptions.
 The command is bound to shortcut `i` by default.
 
 Intercepting *all* requests is usually not desired as it constantly interrupts your browsing.
-Thus, mitmproxy expects a [flow filter expression](https://docs.mitmproxy.org/stable/concepts-filters/) as the first argument to `set intercept` to selectively intercept requests.
+Thus, mitmproxy expects a [flow filter expression]({{< relref "concepts-filters" >}}) as the first argument to `set intercept` to selectively intercept requests.
 In the tutorial below we use the flow filter `~u ` that filters flows by matching the regular expressing on the URL of the request.
 
 {{% asciicast file="mitmproxy_intercept_requests" poster="0:3" instructions=true %}}
diff --git a/docs/src/content/mitmproxytutorial-replayrequests.md b/docs/src/content/mitmproxytutorial-replayrequests.md
index dbf696086..cd895798e 100644
--- a/docs/src/content/mitmproxytutorial-replayrequests.md
+++ b/docs/src/content/mitmproxytutorial-replayrequests.md
@@ -15,6 +15,6 @@ Two types of replays are supported:
 * **Server-side Replay:** mitmproxy replays server responses for requests that match an earlier recorded request.
 
 In this tutorial we focus on the more common use case of client-side replays.
-See the docs for more info on [server-side replay](https://docs.mitmproxy.org/stable/gettingstarted-features/#server-side-replay).
+See the docs for more info on [server-side replay]({{< relref "concepts-advancedfeatures#server-side-replay" >}}).
 
 {{% asciicast file="mitmproxy_replay_requests" poster="0:3" instructions=true %}}
diff --git a/docs/src/content/mitmproxytutorial-userinterface.md b/docs/src/content/mitmproxytutorial-userinterface.md
index b913bd86d..86523c80e 100644
--- a/docs/src/content/mitmproxytutorial-userinterface.md
+++ b/docs/src/content/mitmproxytutorial-userinterface.md
@@ -15,3 +15,5 @@ You should see your browser's HTTP requests to load this tutorial.
 mitmproxy adds rows to the view as new requests come in.
 
 {{% asciicast file="mitmproxy_user_interface" poster="0:3" instructions=true %}}
+
+In the next lesson, you will learn to intercept requests before sending them to the server.
diff --git a/docs/src/content/mitmproxytutorial-whatsnext.md b/docs/src/content/mitmproxytutorial-whatsnext.md
new file mode 100644
index 000000000..5ff3773c6
--- /dev/null
+++ b/docs/src/content/mitmproxytutorial-whatsnext.md
@@ -0,0 +1,42 @@
+---
+title: "What's Next"
+menu:
+    mitmproxytutorial:
+        weight: 5
+---
+
+# What's Next
+
+Congratulations! You have successfully completed the mitmproxy tutorial. 🎉
+
+We hope it was worthwhile and helped you getting up to speed with mitmproxy.
+Is there anything you feel is missing? Or anything that is not clear? Please let us know in our  dedicated issue on GitHub.
+
+## Advanced usage
+
+In this tutorial we have used mitmproxy to inspect requests initiated by curl.
+You probably also want to inspect web traffic from your browser or some other tool.
+To do so, you need to [configure mitmproxy as your client's proxy]({{< relref "overview-getting-started#configure-your-browser-or-device" >}}).
+
+This tutorial is not meant as a replacement for our extensive docs.
+mitmproxy has far more features than what we've shown you.
+We recommend to read the documentation to get the full picture.
+
+If you want to get in touch with the developers or other users, please use our [Slack channel](https://mitmproxy.slack.com).
+If you want to contribute to mitmproxy or submit a bug report or other feedback, please do so on [GitHub](https://github.com/mitmproxy/).
+
+
+### Customize Key bindings
+
+Mitmproxy's key bindings can be customized to your needs in the
+`~/.mitmproxy/keys.yaml` file. This file consists of a sequence of maps, with
+the following keys:
+
+* `key` (**mandatory**): The key to bind.
+* `cmd` (**mandatory**): The command to execute when the key is pressed.
+* `context`: A list of contexts in which the key should be bound. By default this is **global** (i.e. the key is bound everywhere). Valid contexts are `chooser`, `commands`, `dataviewer`, `eventlog`, `flowlist`, `flowview`, `global`, `grideditor`, `help`, `keybindings`, `options`.
+* `help`: A help string for the binding which will be shown in the key binding browser.
+
+#### Example
+
+{{< example src="examples/keys.yaml" lang="yaml" >}}
diff --git a/docs/src/content/overview-getting-started.md b/docs/src/content/overview-getting-started.md
index 6061fdc32..dc220a98c 100644
--- a/docs/src/content/overview-getting-started.md
+++ b/docs/src/content/overview-getting-started.md
@@ -8,21 +8,22 @@ menu:
 
 # Getting Started
 
-You have already [installed]({{< relref "overview-installation">}}) mitmproxy on
+We assume you have already [installed]({{< relref "overview-installation">}}) mitmproxy on
 your machine.
 
-# Launch the tool you need
 
-You can start any of our three tools from the command line / terminal:
+## Launch the tool you need
 
-  * [mitmproxy]({{< relref "tools-mitmproxy">}}) -> gives you an interactive TUI
-  * [mitmdump]({{< relref "tools-mitmdump">}}) -> gives you a plain and simple terminal output
-  * [mitmweb]({{< relref "tools-mitmweb">}}) -> gives you a browser-based GUI
+You can start any of our three tools from the command line / terminal.
 
-When we talk about "mitmproxy" we usually refer to any of the three tools - they
-are just different front-ends to the same core proxy.
+  * **mitmproxy** gives you an interactive TUI
+  * **mitmweb** gives you a browser-based GUI
+  * **mitmdump** gives you a plain and simple terminal output
 
-# Configure your browser or device
+In case you use the console-based version of mitmproxy, we highly recommend you to take the [tutorial]({{< relref "mitmproxytutorial-userinterface" >}}) to get started.
+
+
+## Configure your browser or device
 
 For the basic setup as [regular proxy]({{< relref
 "concepts-modes#regular-proxy">}}), you need to configure your browser or device
@@ -39,11 +40,16 @@ Authority - which is also the next steps. Follow the instructions for your OS /
 system and install the CA (and make sure to enable it, some system require
 multiple steps!).
 
-# Verifying everything works
+
+## Verifying everything works
 
 At this point your running mitmproxy instance should already show the first HTTP
 flows from your client. You can test that all TLS-encrypted web traffic is
 working as expected by browsing to https://mitmproxy.org - it should show up as
 new flow and you can inspect it.
 
-Done.
+
+## Resources
+
+* [**GitHub**](https://github.com/mitmproxy/): If you want to contribute to mitmproxy or submit a bug report or other feedback, please do so on GitHub.
+* [**Slack**](https://mitmproxy.slack.com): If you want to get in touch with the developers or other users, please use our Slack channel.
\ No newline at end of file
diff --git a/docs/src/content/overview-installation.md b/docs/src/content/overview-installation.md
index 9dd5d8db5..7f078ecf7 100644
--- a/docs/src/content/overview-installation.md
+++ b/docs/src/content/overview-installation.md
@@ -46,16 +46,16 @@ After installation, you'll find shortcuts for mitmweb and mitmdump in the start
 menu. Both executables are added to your PATH and can be invoked from the
 command line.
 
-# Advanced Installation
+## Advanced Installation
 
-## Development Setup
+### Development Setup
 
 If you would like to install mitmproxy directly from source code or the
 GitHub master branch, please see the our
 [README](https://github.com/mitmproxy/mitmproxy#installation)
 on GitHub.
 
-## Installation from the Python Package Index (PyPI)
+### Installation from the Python Package Index (PyPI)
 
 If your mitmproxy addons require the installation of additional Python packages,
 you can install mitmproxy from [PyPI](https://pypi.org/project/mitmproxy/).
@@ -72,12 +72,12 @@ While there are plenty of options around[^1], we recommend the installation usin
 
 To install additional Python packages, run `pipx inject mitmproxy `.
 
-## Docker Images
+### Docker Images
 
 You can use the official mitmproxy images from
 [DockerHub](https://hub.docker.com/r/mitmproxy/mitmproxy/).
 
-## Security Considerations for Binary Packages
+### Security Considerations for Binary Packages
 
 Our pre-compiled binary packages and Docker images include a self-contained
 Python 3 environment,  a recent version of OpenSSL that support ALPN and HTTP/2,
diff --git a/docs/src/content/tools-mitmdump.md b/docs/src/content/tools-mitmdump.md
deleted file mode 100644
index 6a9b39210..000000000
--- a/docs/src/content/tools-mitmdump.md
+++ /dev/null
@@ -1,70 +0,0 @@
----
-title: "mitmdump"
-menu: "tools"
-menu:
-    tools:
-        weight: 2
----
-
-## mitmdump
-
-**mitmdump** is the command-line companion to mitmproxy. It provides
-tcpdump-like functionality to let you view, record, and programmatically
-transform HTTP traffic. See the `--help` flag output for complete
-documentation.
-
-
-### Example: Saving traffic
-
-```bash
-mitmdump -w outfile
-```
-
-Start up mitmdump in proxy mode, and write all traffic to **outfile**.
-
-### Filtering saved traffic
-
-```bash
-mitmdump -nr infile -w outfile "~m post"
-```
-
-Start mitmdump without binding to the proxy port (`-n`), read all flows
-from infile, apply the specified filter expression (only match POSTs),
-and write to outfile.
-
-### Client replay
-
-```bash
-mitmdump -nC outfile
-```
-
-Start mitmdump without binding to the proxy port (`-n`), then replay all
-requests from outfile (`-C filename`). Flags combine in the obvious way,
-so you can replay requests from one file, and write the resulting flows
-to another:
-
-```bash
-mitmdump -nC srcfile -w dstfile
-```
-
-See the [client-side replay]({{< relref "overview-features#client-side-replay"
->}}) section for more information.
-
-### Running a script
-
-```bash
-mitmdump -s examples/simple/add_header.py
-```
-
-This runs the **add_header.py** example script, which simply adds a new
-header to all responses.
-
-### Scripted data transformation
-
-```bash
-mitmdump -ns examples/simple/add_header.py -r srcfile -w dstfile
-```
-
-This command loads flows from **srcfile**, transforms it according to
-the specified script, then writes it back to **dstfile**.
-
diff --git a/docs/src/content/tools-mitmproxy.md b/docs/src/content/tools-mitmproxy.md
deleted file mode 100644
index d3f05aef4..000000000
--- a/docs/src/content/tools-mitmproxy.md
+++ /dev/null
@@ -1,36 +0,0 @@
----
-title: "mitmproxy"
-menu: "tools"
-menu:
-    tools:
-        weight: 1
----
-
-## mitmproxy
-
-{{< figure src="/screenshots/mitmproxy.png" >}}
-
-**mitmproxy** is a console tool that allows interactive examination and
-modification of HTTP traffic. It differs from mitmdump in that all flows are
-kept in memory, which means that it's intended for taking and manipulating
-small-ish samples. Use the `?` shortcut key to view, context-sensitive
-documentation from any **mitmproxy** screen.
-
-### Key binding configuration
-
-Mitmproxy's key bindings can be customized through in the
-`~/.mitmproxy/keys.yaml` file. This file consists of a sequence of maps, with
-the following keys:
-
-* `key` (**mandatory**): The key to bind.
-* `cmd` (**mandatory**): The command to execute when the key is pressed.
-* `context`: A list of contexts in which the key should be bound. By default this is **global** (i.e. the key is bound everywhere). Valid contexts are `chooser`, `commands`, `dataviewer`, `eventlog`, `flowlist`, `flowview`, `global`, `grideditor`, `help`, `keybindings`, `options`.
-* `help`: A help string for the binding which will be shown in the key binding browser.
-
-#### Example
-
-{{< example src="examples/keys.yaml" lang="yaml" >}}
-
-
-
-
diff --git a/docs/src/content/tools-mitmweb.md b/docs/src/content/tools-mitmweb.md
deleted file mode 100644
index a3205377a..000000000
--- a/docs/src/content/tools-mitmweb.md
+++ /dev/null
@@ -1,23 +0,0 @@
----
-title: "mitmweb"
-menu: "tools"
-menu:
-    tools:
-        weight: 3
----
-
-## mitmweb
-
-{{< figure src="/screenshots/mitmweb.png" >}}
-
-**mitmweb** is mitmproxy's web-based user interface that allows
-interactive examination and modification of HTTP traffic. Like
-mitmproxy, it differs from mitmdump in that all flows are kept in
-memory, which means that it's intended for taking and manipulating
-small-ish samples.
-
-{{% note %}}
-Mitmweb is currently in beta. We consider it stable for all features
-currently exposed in the UI, but it still misses a lot of mitmproxy's
-features.
-{{% /note %}}
diff --git a/docs/src/layouts/partials/sidebar.html b/docs/src/layouts/partials/sidebar.html
index caabda564..34d358ee9 100644
--- a/docs/src/layouts/partials/sidebar.html
+++ b/docs/src/layouts/partials/sidebar.html
@@ -11,9 +11,6 @@
     
     {{ partial "sidemenu" (dict "ctx" . "menuname" "mitmproxytutorial") }}
 
-    
-    {{ partial "sidemenu" (dict "ctx" . "menuname" "tools") }}
-
     
     {{ partial "sidemenu" (dict "ctx" . "menuname" "concepts") }}
 
diff --git a/mitmproxy/tools/web/static/app.js b/mitmproxy/tools/web/static/app.js
index e02d7eb69..54d45f395 100644
--- a/mitmproxy/tools/web/static/app.js
+++ b/mitmproxy/tools/web/static/app.js
@@ -101,7 +101,7 @@
 "use strict";function _interopRequireDefault(e){return e&&e.__esModule?e:{default:e}}function _defineProperty(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function MenuToggle(e){var t=e.value,n=e.onChange,r=e.children;return React.createElement("div",{className:"menu-entry"},React.createElement("label",null,React.createElement("input",{type:"checkbox",checked:t,onChange:n}),r))}function SettingsToggle(e){var t=e.setting,n=e.children,r=e.settings,g=e.updateSettings;return React.createElement(MenuToggle,{value:r[t]||!1,onChange:function(){return g(_defineProperty({},t,!r[t]))}},n)}function EventlogToggle(e){var t=e.toggleVisibility,n=e.eventLogVisible;return React.createElement(MenuToggle,{value:n,onChange:t},"Display Event Log")}Object.defineProperty(exports,"__esModule",{value:!0}),exports.MenuToggle=MenuToggle,exports.SettingsToggle=SettingsToggle,exports.EventlogToggle=EventlogToggle;var _propTypes=require("prop-types"),_propTypes2=_interopRequireDefault(_propTypes),_reactRedux=require("react-redux"),_settings=require("../../ducks/settings"),_eventLog=require("../../ducks/eventLog");MenuToggle.propTypes={value:_propTypes2.default.bool.isRequired,onChange:_propTypes2.default.func.isRequired,children:_propTypes2.default.node.isRequired},SettingsToggle.propTypes={setting:_propTypes2.default.string.isRequired,children:_propTypes2.default.node.isRequired},exports.SettingsToggle=SettingsToggle=(0,_reactRedux.connect)(function(e){return{settings:e.settings}},{updateSettings:_settings.update})(SettingsToggle),exports.EventlogToggle=EventlogToggle=(0,_reactRedux.connect)(function(e){return{eventLogVisible:e.eventLog.visible}},{toggleVisibility:_eventLog.toggleVisibility})(EventlogToggle);
 
 },{"../../ducks/eventLog":55,"../../ducks/settings":59,"prop-types":"prop-types","react-redux":"react-redux"}],35:[function(require,module,exports){
-"use strict";function _interopRequireWildcard(e){if(e&&e.__esModule)return e;var t={};if(null!=e)for(var a in e)Object.prototype.hasOwnProperty.call(e,a)&&(t[a]=e[a]);return t.default=e,t}function _interopRequireDefault(e){return e&&e.__esModule?e:{default:e}}function OptionMenu(e){var t=e.openOptions;return _react2.default.createElement("div",null,_react2.default.createElement(_HideInStatic2.default,null,_react2.default.createElement("div",{className:"menu-group"},_react2.default.createElement("div",{className:"menu-content"},_react2.default.createElement(_Button2.default,{title:"Open Options",icon:"fa-cogs text-primary",onClick:t},"Edit Options ",_react2.default.createElement("sup",null,"alpha"))),_react2.default.createElement("div",{className:"menu-legend"},"Options Editor")),_react2.default.createElement("div",{className:"menu-group"},_react2.default.createElement("div",{className:"menu-content"},_react2.default.createElement(_MenuToggle.SettingsToggle,{setting:"anticache"},"Strip cache headers ",_react2.default.createElement(_DocsLink2.default,{resource:"overview-features/#anticache"})),_react2.default.createElement(_MenuToggle.SettingsToggle,{setting:"showhost"},"Use host header for display"),_react2.default.createElement(_MenuToggle.SettingsToggle,{setting:"ssl_insecure"},"Don't verify server certificates")),_react2.default.createElement("div",{className:"menu-legend"},"Quick Options"))),_react2.default.createElement("div",{className:"menu-group"},_react2.default.createElement("div",{className:"menu-content"},_react2.default.createElement(_MenuToggle.EventlogToggle,null)),_react2.default.createElement("div",{className:"menu-legend"},"View Options")))}Object.defineProperty(exports,"__esModule",{value:!0});var _react=require("react"),_react2=_interopRequireDefault(_react),_reactRedux=require("react-redux"),_MenuToggle=require("./MenuToggle"),_Button=require("../common/Button"),_Button2=_interopRequireDefault(_Button),_DocsLink=require("../common/DocsLink"),_DocsLink2=_interopRequireDefault(_DocsLink),_HideInStatic=require("../common/HideInStatic"),_HideInStatic2=_interopRequireDefault(_HideInStatic),_modal=require("../../ducks/ui/modal"),modalActions=_interopRequireWildcard(_modal);OptionMenu.title="Options",exports.default=(0,_reactRedux.connect)(null,{openOptions:function(){return modalActions.setActiveModal("OptionModal")}})(OptionMenu);
+"use strict";function _interopRequireWildcard(e){if(e&&e.__esModule)return e;var t={};if(null!=e)for(var a in e)Object.prototype.hasOwnProperty.call(e,a)&&(t[a]=e[a]);return t.default=e,t}function _interopRequireDefault(e){return e&&e.__esModule?e:{default:e}}function OptionMenu(e){var t=e.openOptions;return _react2.default.createElement("div",null,_react2.default.createElement(_HideInStatic2.default,null,_react2.default.createElement("div",{className:"menu-group"},_react2.default.createElement("div",{className:"menu-content"},_react2.default.createElement(_Button2.default,{title:"Open Options",icon:"fa-cogs text-primary",onClick:t},"Edit Options ",_react2.default.createElement("sup",null,"alpha"))),_react2.default.createElement("div",{className:"menu-legend"},"Options Editor")),_react2.default.createElement("div",{className:"menu-group"},_react2.default.createElement("div",{className:"menu-content"},_react2.default.createElement(_MenuToggle.SettingsToggle,{setting:"anticache"},"Strip cache headers ",_react2.default.createElement(_DocsLink2.default,{resource:"concepts-advancedfeatures/#anticache"})),_react2.default.createElement(_MenuToggle.SettingsToggle,{setting:"showhost"},"Use host header for display"),_react2.default.createElement(_MenuToggle.SettingsToggle,{setting:"ssl_insecure"},"Don't verify server certificates")),_react2.default.createElement("div",{className:"menu-legend"},"Quick Options"))),_react2.default.createElement("div",{className:"menu-group"},_react2.default.createElement("div",{className:"menu-content"},_react2.default.createElement(_MenuToggle.EventlogToggle,null)),_react2.default.createElement("div",{className:"menu-legend"},"View Options")))}Object.defineProperty(exports,"__esModule",{value:!0});var _react=require("react"),_react2=_interopRequireDefault(_react),_reactRedux=require("react-redux"),_MenuToggle=require("./MenuToggle"),_Button=require("../common/Button"),_Button2=_interopRequireDefault(_Button),_DocsLink=require("../common/DocsLink"),_DocsLink2=_interopRequireDefault(_DocsLink),_HideInStatic=require("../common/HideInStatic"),_HideInStatic2=_interopRequireDefault(_HideInStatic),_modal=require("../../ducks/ui/modal"),modalActions=_interopRequireWildcard(_modal);OptionMenu.title="Options",exports.default=(0,_reactRedux.connect)(null,{openOptions:function(){return modalActions.setActiveModal("OptionModal")}})(OptionMenu);
 
 },{"../../ducks/ui/modal":64,"../common/Button":45,"../common/DocsLink":46,"../common/HideInStatic":49,"./MenuToggle":34,"react":"react","react-redux":"react-redux"}],36:[function(require,module,exports){
 "use strict";function _interopRequireDefault(e){return e&&e.__esModule?e:{default:e}}function MainView(e){var t=e.hasSelection;return _react2.default.createElement("div",{className:"main-view"},_react2.default.createElement(_FlowTable2.default,null),t&&_react2.default.createElement(_Splitter2.default,{key:"splitter"}),t&&_react2.default.createElement(_FlowView2.default,{key:"flowDetails"}))}Object.defineProperty(exports,"__esModule",{value:!0});var _react=require("react"),_react2=_interopRequireDefault(_react),_propTypes=require("prop-types"),_propTypes2=_interopRequireDefault(_propTypes),_reactRedux=require("react-redux"),_Splitter=require("./common/Splitter"),_Splitter2=_interopRequireDefault(_Splitter),_FlowTable=require("./FlowTable"),_FlowTable2=_interopRequireDefault(_FlowTable),_FlowView=require("./FlowView"),_FlowView2=_interopRequireDefault(_FlowView);MainView.propTypes={hasSelection:_propTypes2.default.bool.isRequired},exports.default=(0,_reactRedux.connect)(function(e){return{hasSelection:!!e.flows.byId[e.flows.selected[0]]}},{})(MainView);
diff --git a/web/src/js/__tests__/components/Header/__snapshots__/OptionMenuSpec.js.snap b/web/src/js/__tests__/components/Header/__snapshots__/OptionMenuSpec.js.snap
index 57ba99e90..f76a0e914 100644
--- a/web/src/js/__tests__/components/Header/__snapshots__/OptionMenuSpec.js.snap
+++ b/web/src/js/__tests__/components/Header/__snapshots__/OptionMenuSpec.js.snap
@@ -17,7 +17,7 @@ exports[`OptionMenu Component should render correctly 1`] = `
         
-        Edit Options 
+        Edit Options
         
           alpha
         
@@ -44,9 +44,9 @@ exports[`OptionMenu Component should render correctly 1`] = `
             onChange={[Function]}
             type="checkbox"
           />
-          Strip cache headers 
+          Strip cache headers
           
             
                     
- Strip cache headers + Strip cache headers Use host header for display