@@ -116,6 +116,7 @@ def __init__(self, *args, **kwargs):
116
116
"rewrite_response" ,
117
117
tuple (),
118
118
)
119
+ self ._requested_subprotocols = None
119
120
super ().__init__ (* args , ** kwargs )
120
121
121
122
# Support/use jupyter_server config arguments allow_origin and allow_origin_pat
@@ -520,27 +521,21 @@ async def start_websocket_connection():
520
521
self .log .info (f"Trying to establish websocket connection to { client_uri } " )
521
522
self ._record_activity ()
522
523
request = httpclient .HTTPRequest (url = client_uri , headers = headers )
523
- subprotocols = (
524
- [self .selected_subprotocol ] if self .selected_subprotocol else None
525
- )
526
524
self .ws = await pingable_ws_connect (
527
525
request = request ,
528
526
on_message_callback = message_cb ,
529
527
on_ping_callback = ping_cb ,
530
- subprotocols = subprotocols ,
528
+ subprotocols = self . _requested_subprotocols ,
531
529
resolver = resolver ,
532
530
)
533
531
self ._record_activity ()
534
532
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 :
539
534
self .log .warn (
540
535
f"Websocket subprotocol between proxy/server ({ self .ws .selected_subprotocol } ) "
541
536
f"became different than for client/proxy ({ self .selected_subprotocol } ) "
542
537
"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 } ."
544
539
)
545
540
546
541
# Wait for the WebSocket to be connected before resolving.
@@ -578,20 +573,27 @@ def select_subprotocol(self, subprotocols):
578
573
"""
579
574
Select a single Sec-WebSocket-Protocol during handshake.
580
575
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
-
587
576
Overrides `tornado.websocket.WebSocketHandler.select_subprotocol` that
588
577
includes an informative docstring:
589
578
https://github.com/tornadoweb/tornado/blob/v6.4.0/tornado/websocket.py#L337-L360.
590
579
"""
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
+
591
587
if subprotocols :
592
588
self .log .debug (
593
589
f"Client sent subprotocols: { subprotocols } , selecting the first"
594
590
)
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
+ #
595
597
return subprotocols [0 ]
596
598
return None
597
599
0 commit comments