First draft of scripting docs.

This commit is contained in:
Aldo Cortesi 2011-08-05 13:26:39 +12:00
parent 89a58d7e30
commit cd0e2f18e6
5 changed files with 106 additions and 52 deletions

View File

@ -52,14 +52,21 @@ a {
color: #181818;
}
#bd h3 {
margin-bottom: 0px;
}
#bd p {
margin: 1em 0;
margin-top: 0.5em;
}
/* Keyboard shortcuts */
#bd em {
font-weight: bold;
color: #04B404;
color: #00A700;
font-style: normal;
}
@ -86,10 +93,9 @@ pre {
}
.terminal {
color: #ffffff;
color: #c0c0c0;
font-size: 1em;
background: #000000;
}
.docindex {
@ -118,5 +124,22 @@ li a {
.highlight {
font-size: 14px;
}
.example_legend{
float: right;
line-height: 1;
margin-left: 20px;
font-size: 12px;
}
.example pre {
margin: 0;
}
.kvtable th {
text-align: left;
white-space: nowrap;
}

View File

@ -34,7 +34,8 @@ ns.index_contents = file(mpath("README.mkd")).read()
top = os.path.abspath(os.getcwd())
def example(s):
d = file(mpath(s)).read()
return countershape.template.Syntax("py")(d)
extemp = """<div class="example">%s<div class="example_legend">(%s)</div></div>"""
return extemp%(countershape.template.Syntax("py")(d), s)
ns.example = example

View File

@ -8,28 +8,36 @@ documentation.
## Example: saving traffic
mitmdump -w outfile
<pre class="terminal">
mitmdump -w outfile
</pre>
Start up mitmdump in proxy mode, and write all traffic to __outfile__.
## Example: client replay
mitmdump -nc outfile
<pre class="terminal">
mitmdump -nc outfile
</pre>
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:
mitmdump -nc srcfile -w dstfile
<pre class="terminal">
mitmdump -nc srcfile -w dstfile
</pre>
See the [Client-side Replay](@!urlTo("clientreplay.html")!@) section for more information.
## Example: running a script
mitmdump -s examples/add_header.py
<pre class="terminal">
mitmdump -s examples/add_header.py
</pre>
This runs the __add_header.py__ example script, which simply adds a new header
to all responses.
@ -37,7 +45,9 @@ to all responses.
## Example: scripted data transformation
mitmdump -ns examples/add_header.py -r srcfile -w dstfile
<pre class="terminal">
mitmdump -ns examples/add_header.py -r srcfile -w dstfile
</pre>
This command loads flows from __srcfile__, transforms it according to the
specified script, then writes it back to __dstfile__.

View File

@ -1,47 +1,71 @@
__mitmproxy__ has a powerful event-drive scripting API, that allows you to
modify flows on-the-fly or rewrite previously saved flows locally.
__mitmproxy__ has a powerful scripting API that allows you to modify flows
on-the-fly or rewrite previously saved flows locally.
The mitmproxy scripting API is event driven - a script is simply a Python
module that exposes a set of event methods. Here's a complete mitmproxy script
that adds a new header to every HTTP response before it is returned to the
client:
$!example("examples/add_header.py")!$
The first argument to each event method is an instance of ScriptContext that
lets the script interact with the global mitmproxy state. The __response__
event also gets an instance of Flow, which we can use to manipulate the
response itself.
## Events
<table>
<tr>
<td>start(ctx)</td>
<td>Called once on startup, before any other events.</td>
</tr>
<tr>
<td>clientconnect(ctx, ClientConnect)</td>
<td>Called when a client initiates a connection to the proxy. Note that
a connection can correspond to multiple HTTP requests.</td>
</tr>
<tr>
<td>request(ctx, Flow)</td>
<td>Called when a client request has been received.</td>
</tr>
<tr>
<td>response(ctx, Flow)</td>
<td>Called when a server response has been received.</td>
</tr>
<tr>
<td>error(ctx, Flow)</td>
<td>Called when a flow error has occured, e.g. invalid server
responses, or interrupted connections. This is distinct from a valid
server HTTP error response, which is simply a response with an HTTP
error code. </td>
</tr>
<tr>
<td>clientdisconnect(ctx, ClientDisconnect)</td>
<td>Called when a client disconnects from the proxy.</td>
</tr>
<tr>
<td>done(ctx)</td>
<td>Called once on script shutdown, after any other events.</td>
</tr>
</table>
### start(ScriptContext)
Called once on startup, before any other events.
###clientconnect(ScriptContext, ClientConnect)
Called when a client initiates a connection to the proxy. Note that
a connection can correspond to multiple HTTP requests.
###request(ScriptContext, Flow)
Called when a client request has been received. The __Flow__ object is
guaranteed to have a non-None __request__ attribute.
### response(ScriptContext, Flow)
Called when a server response has been received. The __Flow__ object is
guaranteed to have non-None __request__ and __response__ attributes.
### error(ScriptContext, Flow)
Called when a flow error has occured, e.g. invalid server responses, or
interrupted connections. This is distinct from a valid server HTTP error
response, which is simply a response with an HTTP error code. The __Flow__
object is guaranteed to have non-None __request__ and __error__ attributes.
### clientdisconnect(ScriptContext, ClientDisconnect)
Called when a client disconnects from the proxy.
### done(ScriptContext)
Called once on script shutdown, after any other events.
## Scripts on saved flows
There are a few circumstances in which a script may run on Flows that are
already complete. For example, you could start a script, and then load a saved
set of flows from a file (see the scripted data transformation example on the
[mitmdump](@!urlTo("mitmdump.html")!@) page). This also happens when you run a
one-shot script on a single flow through the _|_ (pipe) shortcut in mitmproxy.
In this case, there are no client connections, and the events are run in the
following order: __start__, __request__, __response__, __error__, __done__. If
the flow doesn't have a __response__ or __error__ associated with it, the
matching event will be skipped.

View File

@ -1,6 +1,2 @@
"""
This script adds a new header to all responses.
"""
def response(ctx, f):
f.response.headers["newheader"] = ["foo"]
def response(context, flow):
flow.response.headers["newheader"] = ["foo"]