mirror of
https://github.com/Grasscutters/mitmproxy.git
synced 2024-11-22 07:08:10 +00:00
Merge pull request #3898 from Kriechi/websocket-docs
improve scripting docs
This commit is contained in:
commit
ac83db3b84
@ -21,4 +21,18 @@ header with a count of the number of responses seen:
|
||||
Below is an addon class that implements stubs for all events. We've added
|
||||
annotations to illustrate the argument types for the various events.
|
||||
|
||||
### Generic Events
|
||||
|
||||
{{< example src="examples/addons/events.py" lang="py" >}}
|
||||
|
||||
### HTTP Events
|
||||
|
||||
{{< example src="examples/addons/events-http-specific.py" lang="py" >}}
|
||||
|
||||
### WebSocket Events
|
||||
|
||||
{{< example src="examples/addons/events-websocket-specific.py" lang="py" >}}
|
||||
|
||||
### TCP Events
|
||||
|
||||
{{< example src="examples/addons/events-tcp-specific.py" lang="py" >}}
|
||||
|
@ -5,7 +5,7 @@ menu:
|
||||
weight: 5
|
||||
---
|
||||
|
||||
# Scripting
|
||||
# Scripting HTTP/1.1 and HTTP/2.0
|
||||
|
||||
Sometimes, we would like to write a quick script without going through the
|
||||
trouble of creating a class. The addons mechanism has a shorthand that allows a
|
||||
@ -13,7 +13,6 @@ module as a whole to be treated as an addon object. This lets us place event
|
||||
handler functions in the module scope. For instance, here is a complete script
|
||||
that adds a header to every request.
|
||||
|
||||
|
||||
{{< example src="examples/addons/scripting-headers.py" lang="py" >}}
|
||||
|
||||
|
||||
@ -22,11 +21,31 @@ an arbitrary response instead:
|
||||
|
||||
{{< example src="examples/simple/send_reply_from_proxy.py" lang="py" >}}
|
||||
|
||||
All events around the HTTP protocol [can be found here]({{< relref "addons-events#http-events">}}).
|
||||
|
||||
You can look at the [http][] module, or the [Request][], and
|
||||
[Response][] classes for other attributes that you can use when
|
||||
For HTTP-related objects, please look at the [http][] module, or the
|
||||
[Request][], and [Response][] classes for other attributes that you can use when
|
||||
scripting.
|
||||
|
||||
[http]: https://github.com/mitmproxy/mitmproxy/blob/master/mitmproxy/http.py
|
||||
[Request]: https://github.com/mitmproxy/mitmproxy/blob/master/mitmproxy/net/http/request.py
|
||||
[Response]: https://github.com/mitmproxy/mitmproxy/blob/master/mitmproxy/net/http/response.py
|
||||
# Scripting WebSocket
|
||||
|
||||
The WebSocket protocol initially looks like a regular HTTP request, before the client and server agree to upgrade the connection to WebSocket. All scripting events for initial HTTP handshake, and also the dedicated WebSocket events [can be found here]({{< relref "addons-events#websocket-events">}}).
|
||||
|
||||
{{< example src="examples/simple/websocket_messages.py" lang="py" >}}
|
||||
|
||||
For WebSocket-related objects please look at the [websocket][] module to find
|
||||
all attributes that you can use when scripting.
|
||||
|
||||
[websocket]: https://github.com/mitmproxy/mitmproxy/blob/master/mitmproxy/websocket.py
|
||||
|
||||
|
||||
# Scripting TCP
|
||||
|
||||
All events around the TCP protocol [can be found here]({{< relref "addons-events#tcp-events">}}).
|
||||
|
||||
{{< example src="examples/complex/tcp_message.py" lang="py" >}}
|
||||
|
||||
For WebSocket-related objects please look at the [tcp][] module to find
|
||||
all attributes that you can use when scripting.
|
||||
|
||||
[tcp]: https://github.com/mitmproxy/mitmproxy/blob/master/mitmproxy/tcp.py
|
||||
|
@ -60,13 +60,3 @@ just replay flows for a specific domain:
|
||||
{{< highlight none >}}
|
||||
:replay.client "~d google.com"
|
||||
{{< /highlight >}}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -20,6 +20,6 @@
|
||||
{{ if .RSSLink -}}
|
||||
<link href="{{ .RSSLink }}" rel="feed" type="application/rss+xml" title="{{ .Site.Title }}">
|
||||
{{- end }}
|
||||
{{ .Hugo.Generator }}
|
||||
{{ hugo.Generator }}
|
||||
</head>
|
||||
<body>
|
||||
|
42
examples/addons/events-http-specific.py
Normal file
42
examples/addons/events-http-specific.py
Normal file
@ -0,0 +1,42 @@
|
||||
import mitmproxy.http
|
||||
|
||||
|
||||
class Events:
|
||||
# HTTP lifecycle
|
||||
def http_connect(self, flow: mitmproxy.http.HTTPFlow):
|
||||
"""
|
||||
An HTTP CONNECT request was received. Setting a non 2xx response on
|
||||
the flow will return the response to the client abort the
|
||||
connection. CONNECT requests and responses do not generate the usual
|
||||
HTTP handler events. CONNECT requests are only valid in regular and
|
||||
upstream proxy modes.
|
||||
"""
|
||||
|
||||
def requestheaders(self, flow: mitmproxy.http.HTTPFlow):
|
||||
"""
|
||||
HTTP request headers were successfully read. At this point, the body
|
||||
is empty.
|
||||
"""
|
||||
|
||||
def request(self, flow: mitmproxy.http.HTTPFlow):
|
||||
"""
|
||||
The full HTTP request has been read.
|
||||
"""
|
||||
|
||||
def responseheaders(self, flow: mitmproxy.http.HTTPFlow):
|
||||
"""
|
||||
HTTP response headers were successfully read. At this point, the body
|
||||
is empty.
|
||||
"""
|
||||
|
||||
def response(self, flow: mitmproxy.http.HTTPFlow):
|
||||
"""
|
||||
The full HTTP response has been read.
|
||||
"""
|
||||
|
||||
def error(self, flow: mitmproxy.http.HTTPFlow):
|
||||
"""
|
||||
An HTTP error has occurred, 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.
|
||||
"""
|
25
examples/addons/events-tcp-specific.py
Normal file
25
examples/addons/events-tcp-specific.py
Normal file
@ -0,0 +1,25 @@
|
||||
import mitmproxy.tcp
|
||||
|
||||
|
||||
class Events:
|
||||
# TCP lifecycle
|
||||
def tcp_start(self, flow: mitmproxy.tcp.TCPFlow):
|
||||
"""
|
||||
A TCP connection has started.
|
||||
"""
|
||||
|
||||
def tcp_message(self, flow: mitmproxy.tcp.TCPFlow):
|
||||
"""
|
||||
A TCP connection has received a message. The most recent message
|
||||
will be flow.messages[-1]. The message is user-modifiable.
|
||||
"""
|
||||
|
||||
def tcp_error(self, flow: mitmproxy.tcp.TCPFlow):
|
||||
"""
|
||||
A TCP error has occurred.
|
||||
"""
|
||||
|
||||
def tcp_end(self, flow: mitmproxy.tcp.TCPFlow):
|
||||
"""
|
||||
A TCP connection has ended.
|
||||
"""
|
36
examples/addons/events-websocket-specific.py
Normal file
36
examples/addons/events-websocket-specific.py
Normal file
@ -0,0 +1,36 @@
|
||||
import mitmproxy.http
|
||||
import mitmproxy.websocket
|
||||
|
||||
|
||||
class Events:
|
||||
# Websocket lifecycle
|
||||
def websocket_handshake(self, flow: mitmproxy.http.HTTPFlow):
|
||||
"""
|
||||
Called when a client wants to establish a WebSocket connection. The
|
||||
WebSocket-specific headers can be manipulated to alter the
|
||||
handshake. The flow object is guaranteed to have a non-None request
|
||||
attribute.
|
||||
"""
|
||||
|
||||
def websocket_start(self, flow: mitmproxy.websocket.WebSocketFlow):
|
||||
"""
|
||||
A websocket connection has commenced.
|
||||
"""
|
||||
|
||||
def websocket_message(self, flow: mitmproxy.websocket.WebSocketFlow):
|
||||
"""
|
||||
Called when a WebSocket message is received from the client or
|
||||
server. The most recent message will be flow.messages[-1]. The
|
||||
message is user-modifiable. Currently there are two types of
|
||||
messages, corresponding to the BINARY and TEXT frame types.
|
||||
"""
|
||||
|
||||
def websocket_error(self, flow: mitmproxy.websocket.WebSocketFlow):
|
||||
"""
|
||||
A websocket connection has had an error.
|
||||
"""
|
||||
|
||||
def websocket_end(self, flow: mitmproxy.websocket.WebSocketFlow):
|
||||
"""
|
||||
A websocket connection has ended.
|
||||
"""
|
@ -10,99 +10,6 @@ import mitmproxy.proxy.protocol
|
||||
|
||||
|
||||
class Events:
|
||||
# HTTP lifecycle
|
||||
def http_connect(self, flow: mitmproxy.http.HTTPFlow):
|
||||
"""
|
||||
An HTTP CONNECT request was received. Setting a non 2xx response on
|
||||
the flow will return the response to the client abort the
|
||||
connection. CONNECT requests and responses do not generate the usual
|
||||
HTTP handler events. CONNECT requests are only valid in regular and
|
||||
upstream proxy modes.
|
||||
"""
|
||||
|
||||
def requestheaders(self, flow: mitmproxy.http.HTTPFlow):
|
||||
"""
|
||||
HTTP request headers were successfully read. At this point, the body
|
||||
is empty.
|
||||
"""
|
||||
|
||||
def request(self, flow: mitmproxy.http.HTTPFlow):
|
||||
"""
|
||||
The full HTTP request has been read.
|
||||
"""
|
||||
|
||||
def responseheaders(self, flow: mitmproxy.http.HTTPFlow):
|
||||
"""
|
||||
HTTP response headers were successfully read. At this point, the body
|
||||
is empty.
|
||||
"""
|
||||
|
||||
def response(self, flow: mitmproxy.http.HTTPFlow):
|
||||
"""
|
||||
The full HTTP response has been read.
|
||||
"""
|
||||
|
||||
def error(self, flow: mitmproxy.http.HTTPFlow):
|
||||
"""
|
||||
An HTTP error has occurred, 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.
|
||||
"""
|
||||
|
||||
# TCP lifecycle
|
||||
def tcp_start(self, flow: mitmproxy.tcp.TCPFlow):
|
||||
"""
|
||||
A TCP connection has started.
|
||||
"""
|
||||
|
||||
def tcp_message(self, flow: mitmproxy.tcp.TCPFlow):
|
||||
"""
|
||||
A TCP connection has received a message. The most recent message
|
||||
will be flow.messages[-1]. The message is user-modifiable.
|
||||
"""
|
||||
|
||||
def tcp_error(self, flow: mitmproxy.tcp.TCPFlow):
|
||||
"""
|
||||
A TCP error has occurred.
|
||||
"""
|
||||
|
||||
def tcp_end(self, flow: mitmproxy.tcp.TCPFlow):
|
||||
"""
|
||||
A TCP connection has ended.
|
||||
"""
|
||||
|
||||
# Websocket lifecycle
|
||||
def websocket_handshake(self, flow: mitmproxy.http.HTTPFlow):
|
||||
"""
|
||||
Called when a client wants to establish a WebSocket connection. The
|
||||
WebSocket-specific headers can be manipulated to alter the
|
||||
handshake. The flow object is guaranteed to have a non-None request
|
||||
attribute.
|
||||
"""
|
||||
|
||||
def websocket_start(self, flow: mitmproxy.websocket.WebSocketFlow):
|
||||
"""
|
||||
A websocket connection has commenced.
|
||||
"""
|
||||
|
||||
def websocket_message(self, flow: mitmproxy.websocket.WebSocketFlow):
|
||||
"""
|
||||
Called when a WebSocket message is received from the client or
|
||||
server. The most recent message will be flow.messages[-1]. The
|
||||
message is user-modifiable. Currently there are two types of
|
||||
messages, corresponding to the BINARY and TEXT frame types.
|
||||
"""
|
||||
|
||||
def websocket_error(self, flow: mitmproxy.websocket.WebSocketFlow):
|
||||
"""
|
||||
A websocket connection has had an error.
|
||||
"""
|
||||
|
||||
def websocket_end(self, flow: mitmproxy.websocket.WebSocketFlow):
|
||||
"""
|
||||
A websocket connection has ended.
|
||||
"""
|
||||
|
||||
# Network lifecycle
|
||||
def clientconnect(self, layer: mitmproxy.proxy.protocol.Layer):
|
||||
"""
|
||||
|
@ -13,7 +13,7 @@ class InjectWebSocketMessage:
|
||||
i = 0
|
||||
while not flow.ended and not flow.error:
|
||||
await asyncio.sleep(5)
|
||||
flow.inject_message(flow.client_conn, 'This is the #{} an injected message!'.format(i))
|
||||
flow.inject_message(flow.client_conn, 'This is the #{} injected message!'.format(i))
|
||||
i += 1
|
||||
|
||||
def websocket_start(self, flow):
|
||||
|
@ -6,8 +6,15 @@ def websocket_message(flow):
|
||||
# get the latest message
|
||||
message = flow.messages[-1]
|
||||
|
||||
# simply print the content of the message
|
||||
ctx.log.info(message.content)
|
||||
# was the message sent from the client or server?
|
||||
if message.from_client:
|
||||
ctx.log.info("Client sent a message: {}".format(message.content))
|
||||
else:
|
||||
ctx.log.info("Server sent a message: {}".format(message.content))
|
||||
|
||||
# manipulate the message content
|
||||
message.content = re.sub(r'^Hello', 'HAPPY', message.content)
|
||||
|
||||
if 'FOOBAR' in message.content:
|
||||
# kill the message and not send it to the other endpoint
|
||||
message.kill()
|
||||
|
Loading…
Reference in New Issue
Block a user