diff --git a/openpilot/system/webrtc/tests/test_stream_session.py b/openpilot/system/webrtc/tests/test_stream_session.py index d64cf6aed..03d540c3c 100644 --- a/openpilot/system/webrtc/tests/test_stream_session.py +++ b/openpilot/system/webrtc/tests/test_stream_session.py @@ -7,7 +7,7 @@ from openpilot.common.test import OpenpilotTestCase from openpilot.cereal import messaging, log from teleoprtc.tracks import VIDEO_CLOCK_RATE -from openpilot.system.webrtc.webrtcd import CerealOutgoingMessageProxy, CerealIncomingMessageProxy +from openpilot.system.webrtc.webrtcd import CerealOutgoingMessageProxy, CerealIncomingMessageProxy, ServerState, handle_get_stream from openpilot.system.webrtc.device.video import LiveStreamVideoStreamTrack @@ -80,3 +80,8 @@ class TestStreamSession(OpenpilotTestCase): start_pts = packet.pts assert abs(i + packet.pts - (start_pts + (((time.monotonic_ns() - start_ns) * VIDEO_CLOCK_RATE) // 1_000_000_000))) < 450 #5ms assert bytes(packet) == b"" + + def test_stream_rejects_non_json_content_type(self): + response = self.loop.run_until_complete(handle_get_stream(ServerState(), b"{}", "text/plain")) + + assert response == (415, b'{"error": "unsupported media type"}', "application/json; charset=utf-8") diff --git a/openpilot/system/webrtc/webrtcd.py b/openpilot/system/webrtc/webrtcd.py index 8e022eda1..3c0c3037f 100755 --- a/openpilot/system/webrtc/webrtcd.py +++ b/openpilot/system/webrtc/webrtcd.py @@ -395,7 +395,10 @@ def _text_response(text: str, status: int = 200) -> tuple[int, bytes, str]: return (status, text.encode(), "text/plain; charset=utf-8") -async def handle_get_stream(state: ServerState, raw_body: bytes) -> tuple[int, bytes, str]: +async def handle_get_stream(state: ServerState, raw_body: bytes, content_type: str) -> tuple[int, bytes, str]: + if content_type != "application/json": + return _json_response({"error": "unsupported media type"}, status=415) + stream_dict = state.streams body = StreamRequestBody(**json.loads(raw_body)) @@ -508,7 +511,7 @@ class WebrtcdHandler(BaseHTTPRequestHandler): services = parse_qs(parsed.query).get("services", [""])[0] result = self._run(handle_get_schema(self.server.state, services)) elif parsed.path == "/stream": - result = self._run(handle_get_stream(self.server.state, self._read_body())) + result = self._run(handle_get_stream(self.server.state, self._read_body(), self.headers.get_content_type())) else: # /notify try: payload = json.loads(self._read_body()) @@ -611,7 +614,7 @@ def webrtcd_thread(host: str, port: int): def main(): parser = argparse.ArgumentParser(description="WebRTC daemon") - parser.add_argument("--host", type=str, default="0.0.0.0", help="Host to listen on") + parser.add_argument("--host", type=str, default="127.0.0.1", help="Host to listen on") parser.add_argument("--port", type=int, default=5001, help="Port to listen on") args = parser.parse_args()