mirror of
https://github.com/Grasscutters/mitmproxy.git
synced 2024-11-29 02:57:19 +00:00
Add WebSocketMessage.injected flag (#5105)
* Add WebSocketMessage.injected flag * add flow format migration Co-authored-by: Maximilian Hils <git@maximilianhils.com>
This commit is contained in:
parent
cba67aa94c
commit
8e1adbc5df
@ -24,6 +24,7 @@
|
|||||||
* Fix random connection stalls (#5040, @EndUser509)
|
* Fix random connection stalls (#5040, @EndUser509)
|
||||||
* Add `n` new flow keybind to mitmweb (#5061, @ianklatzco)
|
* Add `n` new flow keybind to mitmweb (#5061, @ianklatzco)
|
||||||
* Fix compatibility with BoringSSL (@pmoulton)
|
* Fix compatibility with BoringSSL (@pmoulton)
|
||||||
|
* Added `WebSocketMessage.injected` flag (@Prinzhorn)
|
||||||
* Add example addon for saving streamed data to individual files (@EndUser509)
|
* Add example addon for saving streamed data to individual files (@EndUser509)
|
||||||
* Change connection event hooks to be blocking.
|
* Change connection event hooks to be blocking.
|
||||||
Processing will only resume once the event hook has finished. (@Prinzhorn)
|
Processing will only resume once the event hook has finished. (@Prinzhorn)
|
||||||
|
@ -319,6 +319,17 @@ def convert_13_14(data):
|
|||||||
return data
|
return data
|
||||||
|
|
||||||
|
|
||||||
|
def convert_14_15(data):
|
||||||
|
data["version"] = 15
|
||||||
|
if data.get("websocket", None):
|
||||||
|
# Add "injected" attribute.
|
||||||
|
data["websocket"]["messages"] = [
|
||||||
|
msg + [False]
|
||||||
|
for msg in data["websocket"]["messages"]
|
||||||
|
]
|
||||||
|
return data
|
||||||
|
|
||||||
|
|
||||||
def _convert_dict_keys(o: Any) -> Any:
|
def _convert_dict_keys(o: Any) -> Any:
|
||||||
if isinstance(o, dict):
|
if isinstance(o, dict):
|
||||||
return {strutils.always_str(k): _convert_dict_keys(v) for k, v in o.items()}
|
return {strutils.always_str(k): _convert_dict_keys(v) for k, v in o.items()}
|
||||||
@ -380,6 +391,7 @@ converters = {
|
|||||||
11: convert_11_12,
|
11: convert_11_12,
|
||||||
12: convert_12_13,
|
12: convert_12_13,
|
||||||
13: convert_13_14,
|
13: convert_13_14,
|
||||||
|
14: convert_14_15,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -124,8 +124,10 @@ class WebsocketLayer(layer.Layer):
|
|||||||
|
|
||||||
if isinstance(event, events.ConnectionEvent):
|
if isinstance(event, events.ConnectionEvent):
|
||||||
from_client = event.connection == self.context.client
|
from_client = event.connection == self.context.client
|
||||||
|
injected = False
|
||||||
elif isinstance(event, WebSocketMessageInjected):
|
elif isinstance(event, WebSocketMessageInjected):
|
||||||
from_client = event.message.from_client
|
from_client = event.message.from_client
|
||||||
|
injected = True
|
||||||
else:
|
else:
|
||||||
raise AssertionError(f"Unexpected event: {event}")
|
raise AssertionError(f"Unexpected event: {event}")
|
||||||
|
|
||||||
@ -165,7 +167,7 @@ class WebsocketLayer(layer.Layer):
|
|||||||
fragmentizer = Fragmentizer(src_ws.frame_buf, is_text)
|
fragmentizer = Fragmentizer(src_ws.frame_buf, is_text)
|
||||||
src_ws.frame_buf = [b""]
|
src_ws.frame_buf = [b""]
|
||||||
|
|
||||||
message = websocket.WebSocketMessage(typ, from_client, content)
|
message = websocket.WebSocketMessage(typ, from_client, content, injected=injected)
|
||||||
self.flow.websocket.messages.append(message)
|
self.flow.websocket.messages.append(message)
|
||||||
yield WebsocketMessageHook(self.flow)
|
yield WebsocketMessageHook(self.flow)
|
||||||
|
|
||||||
|
@ -7,7 +7,7 @@ MITMPROXY = "mitmproxy " + VERSION
|
|||||||
|
|
||||||
# Serialization format version. This is displayed nowhere, it just needs to be incremented by one
|
# Serialization format version. This is displayed nowhere, it just needs to be incremented by one
|
||||||
# for each change in the file format.
|
# for each change in the file format.
|
||||||
FLOW_FORMAT_VERSION = 14
|
FLOW_FORMAT_VERSION = 15
|
||||||
|
|
||||||
|
|
||||||
def get_dev_version() -> str:
|
def get_dev_version() -> str:
|
||||||
|
@ -14,7 +14,7 @@ from mitmproxy import stateobject
|
|||||||
from mitmproxy.coretypes import serializable
|
from mitmproxy.coretypes import serializable
|
||||||
from wsproto.frame_protocol import Opcode
|
from wsproto.frame_protocol import Opcode
|
||||||
|
|
||||||
WebSocketMessageState = Tuple[int, bool, bytes, float, bool]
|
WebSocketMessageState = Tuple[int, bool, bytes, float, bool, bool]
|
||||||
|
|
||||||
|
|
||||||
class WebSocketMessage(serializable.Serializable):
|
class WebSocketMessage(serializable.Serializable):
|
||||||
@ -47,6 +47,8 @@ class WebSocketMessage(serializable.Serializable):
|
|||||||
"""Timestamp of when this message was received or created."""
|
"""Timestamp of when this message was received or created."""
|
||||||
dropped: bool
|
dropped: bool
|
||||||
"""True if the message has not been forwarded by mitmproxy, False otherwise."""
|
"""True if the message has not been forwarded by mitmproxy, False otherwise."""
|
||||||
|
injected: bool
|
||||||
|
"""True if the message was injected and did not originate from a client/server, False otherwise"""
|
||||||
|
|
||||||
def __init__(
|
def __init__(
|
||||||
self,
|
self,
|
||||||
@ -54,23 +56,25 @@ class WebSocketMessage(serializable.Serializable):
|
|||||||
from_client: bool,
|
from_client: bool,
|
||||||
content: bytes,
|
content: bytes,
|
||||||
timestamp: Optional[float] = None,
|
timestamp: Optional[float] = None,
|
||||||
killed: bool = False,
|
dropped: bool = False,
|
||||||
|
injected: bool = False,
|
||||||
) -> None:
|
) -> None:
|
||||||
self.from_client = from_client
|
self.from_client = from_client
|
||||||
self.type = Opcode(type)
|
self.type = Opcode(type)
|
||||||
self.content = content
|
self.content = content
|
||||||
self.timestamp: float = timestamp or time.time()
|
self.timestamp: float = timestamp or time.time()
|
||||||
self.dropped = killed
|
self.dropped = dropped
|
||||||
|
self.injected = injected
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def from_state(cls, state: WebSocketMessageState):
|
def from_state(cls, state: WebSocketMessageState):
|
||||||
return cls(*state)
|
return cls(*state)
|
||||||
|
|
||||||
def get_state(self) -> WebSocketMessageState:
|
def get_state(self) -> WebSocketMessageState:
|
||||||
return int(self.type), self.from_client, self.content, self.timestamp, self.dropped
|
return int(self.type), self.from_client, self.content, self.timestamp, self.dropped, self.injected
|
||||||
|
|
||||||
def set_state(self, state: WebSocketMessageState) -> None:
|
def set_state(self, state: WebSocketMessageState) -> None:
|
||||||
typ, self.from_client, self.content, self.timestamp, self.dropped = state
|
typ, self.from_client, self.content, self.timestamp, self.dropped, self.injected = state
|
||||||
self.type = Opcode(typ)
|
self.type = Opcode(typ)
|
||||||
|
|
||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
|
@ -438,6 +438,7 @@ def test_inject_message(ws_testdata):
|
|||||||
)
|
)
|
||||||
assert flow.websocket.messages[-1].content == b"hello"
|
assert flow.websocket.messages[-1].content == b"hello"
|
||||||
assert flow.websocket.messages[-1].from_client is False
|
assert flow.websocket.messages[-1].from_client is False
|
||||||
|
assert flow.websocket.messages[-1].injected is True
|
||||||
assert (
|
assert (
|
||||||
playbook
|
playbook
|
||||||
>> reply()
|
>> reply()
|
||||||
|
Loading…
Reference in New Issue
Block a user