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