Skip to content

Commit 14fda0c

Browse files
authored
Fixes #356 WebSockets not working with TLS interception (#365)
1 parent e7aa8a2 commit 14fda0c

File tree

5 files changed

+24
-9
lines changed

5 files changed

+24
-9
lines changed

helper/chrome_with_proxy.sh

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,6 @@ fi
2020
--no-first-run \
2121
--no-default-browser-check \
2222
--user-data-dir="$(mktemp -d -t 'chrome-remote_data_dir')" \
23-
--proxy-server=${PROXY_PY_ADDR} \
24-
--ignore-urlfetcher-cert-requests \
25-
--ignore-certificate-errors
23+
--proxy-server=${PROXY_PY_ADDR} #\
24+
# --ignore-urlfetcher-cert-requests \
25+
# --ignore-certificate-errors

proxy/http/handler.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -288,13 +288,13 @@ def handle_writables(self, writables: List[Union[int, HasFileno]]) -> bool:
288288

289289
try:
290290
self.client.flush()
291-
except OSError:
292-
logger.error('OSError when flushing buffer to client')
293-
return True
294291
except BrokenPipeError:
295292
logger.error(
296293
'BrokenPipeError when flushing buffer for client')
297294
return True
295+
except OSError:
296+
logger.error('OSError when flushing buffer to client')
297+
return True
298298
return False
299299

300300
def handle_readables(self, readables: List[Union[int, HasFileno]]) -> bool:
@@ -359,7 +359,7 @@ def handle_readables(self, readables: List[Union[int, HasFileno]]) -> bool:
359359
except HttpProtocolException as e:
360360
logger.debug(
361361
'HttpProtocolException type raised')
362-
response = e.response(self.request)
362+
response: Optional[memoryview] = e.response(self.request)
363363
if response:
364364
self.client.queue(response)
365365
return True

proxy/http/parser.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -258,3 +258,8 @@ def is_http_1_1_keep_alive(self) -> bool:
258258
return self.version == HTTP_1_1 and \
259259
(not self.has_header(b'Connection') or
260260
self.header(b'Connection').lower() == b'keep-alive')
261+
262+
def is_connection_upgrade(self) -> bool:
263+
return self.version == HTTP_1_1 and \
264+
self.has_header(b'Connection') and \
265+
self.has_header(b'Upgrade')

proxy/http/proxy/server.py

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -207,6 +207,15 @@ def on_client_data(self, raw: memoryview) -> Optional[memoryview]:
207207
if self.request.state == httpParserStates.COMPLETE and (
208208
self.request.method != httpMethods.CONNECT or
209209
self.flags.tls_interception_enabled()):
210+
211+
if self.pipeline_request is not None and \
212+
self.pipeline_request.is_connection_upgrade():
213+
# Previous pipelined request was a WebSocket
214+
# upgrade request. Incoming client data now
215+
# must be treated as WebSocket protocol packets.
216+
self.server.queue(raw)
217+
return None
218+
210219
if self.pipeline_request is None:
211220
self.pipeline_request = HttpParser(
212221
httpParserTypes.REQUEST_PARSER)
@@ -226,7 +235,8 @@ def on_client_data(self, raw: memoryview) -> Optional[memoryview]:
226235
self.server.queue(
227236
memoryview(
228237
self.pipeline_request.build()))
229-
self.pipeline_request = None
238+
if not self.pipeline_request.is_connection_upgrade():
239+
self.pipeline_request = None
230240
else:
231241
self.server.queue(raw)
232242
return None

proxy/http/websocket.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -231,7 +231,7 @@ def run_once(self) -> bool:
231231
self.selector.register(self.sock.fileno(), ev)
232232
events = self.selector.select(timeout=1)
233233
self.selector.unregister(self.sock)
234-
for key, mask in events:
234+
for _, mask in events:
235235
if mask & selectors.EVENT_READ and self.on_message:
236236
raw = self.recv()
237237
if raw is None or raw.tobytes() == b'':

0 commit comments

Comments
 (0)