Skip to content

Commit d7e158e

Browse files
authored
Merge pull request #462 from consideRatio/pr/fix-regression-in-4.1.1
Keep proxying all requested subprotocols
2 parents 81c483b + f9d6fcd commit d7e158e

File tree

2 files changed

+22
-21
lines changed

2 files changed

+22
-21
lines changed

jupyter_server_proxy/handlers.py

Lines changed: 17 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,7 @@ def __init__(self, *args, **kwargs):
116116
"rewrite_response",
117117
tuple(),
118118
)
119+
self._requested_subprotocols = None
119120
super().__init__(*args, **kwargs)
120121

121122
# Support/use jupyter_server config arguments allow_origin and allow_origin_pat
@@ -520,27 +521,21 @@ async def start_websocket_connection():
520521
self.log.info(f"Trying to establish websocket connection to {client_uri}")
521522
self._record_activity()
522523
request = httpclient.HTTPRequest(url=client_uri, headers=headers)
523-
subprotocols = (
524-
[self.selected_subprotocol] if self.selected_subprotocol else None
525-
)
526524
self.ws = await pingable_ws_connect(
527525
request=request,
528526
on_message_callback=message_cb,
529527
on_ping_callback=ping_cb,
530-
subprotocols=subprotocols,
528+
subprotocols=self._requested_subprotocols,
531529
resolver=resolver,
532530
)
533531
self._record_activity()
534532
self.log.info(f"Websocket connection established to {client_uri}")
535-
if (
536-
subprotocols
537-
and self.ws.selected_subprotocol != self.selected_subprotocol
538-
):
533+
if self.ws.selected_subprotocol != self.selected_subprotocol:
539534
self.log.warn(
540535
f"Websocket subprotocol between proxy/server ({self.ws.selected_subprotocol}) "
541536
f"became different than for client/proxy ({self.selected_subprotocol}) "
542537
"due to https://github.com/jupyterhub/jupyter-server-proxy/issues/459. "
543-
f"Requested subprotocols were {subprotocols}."
538+
f"Requested subprotocols were {self._requested_subprotocols}."
544539
)
545540

546541
# Wait for the WebSocket to be connected before resolving.
@@ -578,20 +573,27 @@ def select_subprotocol(self, subprotocols):
578573
"""
579574
Select a single Sec-WebSocket-Protocol during handshake.
580575
581-
Note that this subprotocol selection should really be delegated to the
582-
server we proxy to, but we don't! For this to happen, we would need to
583-
delay accepting the handshake with the client until we have successfully
584-
handshaked with the server. This issue is tracked via
585-
https://github.com/jupyterhub/jupyter-server-proxy/issues/459.
586-
587576
Overrides `tornado.websocket.WebSocketHandler.select_subprotocol` that
588577
includes an informative docstring:
589578
https://github.com/tornadoweb/tornado/blob/v6.4.0/tornado/websocket.py#L337-L360.
590579
"""
580+
# Stash all requested subprotocols to be re-used as requested
581+
# subprotocols in the proxy/server handshake to be performed later. At
582+
# least bokeh has used additional subprotocols to pass credentials,
583+
# making this a required workaround for now.
584+
#
585+
self._requested_subprotocols = subprotocols if subprotocols else None
586+
591587
if subprotocols:
592588
self.log.debug(
593589
f"Client sent subprotocols: {subprotocols}, selecting the first"
594590
)
591+
# FIXME: Subprotocol selection should be delegated to the server we
592+
# proxy to, but we don't! For this to happen, we would need
593+
# to delay accepting the handshake with the client until we
594+
# have successfully handshaked with the server. This issue is
595+
# tracked in https://github.com/jupyterhub/jupyter-server-proxy/issues/459.
596+
#
595597
return subprotocols[0]
596598
return None
597599

tests/test_proxies.py

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -360,6 +360,7 @@ async def test_server_proxy_websocket_headers(a_server_port_and_token: Tuple[int
360360
[
361361
(None, None, None, None),
362362
(["first"], ["first"], "first", "first"),
363+
(["first", "second"], ["first", "second"], "first", "first"),
363364
# IMPORTANT: The tests below verify current bugged behavior, and the
364365
# commented out tests is what we want to succeed!
365366
#
@@ -369,14 +370,12 @@ async def test_server_proxy_websocket_headers(a_server_port_and_token: Tuple[int
369370
# before the proxy/server handshake, and that makes it
370371
# impossible. We currently instead just pick the first
371372
# requested protocol no matter what what subprotocol the
372-
# server picks.
373+
# server picks and warn if there is a mismatch retroactively.
373374
#
374-
# Bug 1 - server wasn't passed all subprotocols:
375-
(["first", "second"], ["first"], "first", "first"),
376-
# (["first", "second"], ["first", "second"], "first", "first"),
375+
# Tracked in https://github.com/jupyterhub/jupyter-server-proxy/issues/459.
377376
#
378-
# Bug 2 - server_responded doesn't match proxy_responded:
379-
(["first", "favored"], ["first"], "first", "first"),
377+
# Bug - server_responded doesn't match proxy_responded:
378+
(["first", "favored"], ["first", "favored"], "favored", "first"),
380379
# (["first", "favored"], ["first", "favored"], "favored", "favored"),
381380
(
382381
["please_select_no_protocol"],

0 commit comments

Comments
 (0)