
    ^h@                         S r SSKrSSKrSSKJrJr  SSKJr  SSKJ	r	J
r
  SSKJr  SSKJr  SSKJr  S	r " S
 S5      rg)zBase websocket classes.    N)Optionalno_type_check)urlparse)ioloopweb)IOStream)JupyterHandler)JupyterServerAuthWarningi0u  c                      ^  \ rS rSr% SrSrSrSrSr\	\
   \S'   \S 5       r\S 5       r\SS\	\   S	\4S
 jj5       rS r\S 5       r\U 4S j5       r\U 4S j5       r\S 5       rS rSrU =r$ )WebSocketMixin   z"Mixin for common websocket optionsNg        streamc                 B    U R                   R                  S[        5      $ )zYThe interval for websocket keep-alive pings.

Set ws_ping_interval = 0 to disable pings.
ws_ping_interval)settingsgetWS_PING_INTERVALselfs    W/home/james-whalen/.local/lib/python3.13/site-packages/jupyter_server/base/websocket.pyping_intervalWebSocketMixin.ping_interval   s     }}  !35EFF    c                 p    U R                   R                  S[        SU R                  -  [        5      5      $ )zIf no ping is received in this many milliseconds,
close the websocket connection (VPNs, etc. can fail to cleanly close ws connections).
Default is max of 3 pings or 30 seconds.
ws_ping_timeout   )r   r   maxr   r   r   s    r   ping_timeoutWebSocketMixin.ping_timeout"   s3     }}  s1t'9'9#9;KL
 	
r   originreturnc                 N   U R                   S:X  d&  [        U S5      (       a  U R                  5       (       a  gU R                  R                  R                  S5      nUc  U R                  5       nUb  Uc  gUR                  5       n[        U5      R                  nX2:X  a  gU R                   (       a  U R                   U:H  nO>U R                  (       a+  [        [        R                  " U R                  U5      5      nOSnU(       d  U R                  R                  SUU5        U$ )zCheck Origin == Host or Access-Control-Allow-Origin.

Tornado >= 4 calls this method automatically, raising 403 if it returns False.
*skip_check_originTHostFz>Blocking Cross Origin WebSocket Attempt.  Origin: %s, Host: %s)allow_originhasattrr$   requestheadersr   
get_originlowerr   netlocallow_origin_patboolrematchlogwarning)r   r    hostorigin_hostallows        r   check_originWebSocketMixin.check_origin,   s     #D-..43I3I3K3K||##''/>__&F >T\v&--  %%/E""$"7"7@AE EHHP
 r   c                     g)zmeaningless for websocketsN )r   argskwargss      r   clear_cookieWebSocketMixin.clear_cookieW   s    r   c                    U R                   R                  SS5      (       d  U R                  R                  (       d  [        R
                  " S5      e[        X R                  R                  R                  5       5      n[        USS5      (       dA  U R                  nUc1  U R                  R                  S5        [        R
                  " S5      eggg)zmVerify authentication if required.

Only used when the websocket class does not inherit from JupyterHandler.
allow_unauthenticated_accessFi  __allow_unauthenticatedNz*Couldn't authenticate WebSocket connection)r   r   r(   methodr   	HTTPErrorgetattrr+   current_userr1   r2   )r   rA   users      r   _maybe_authWebSocketMixin._maybe_authZ   s     }}  !?GG<<&&mmC((T<<#6#6#<#<#>?F6#<eDD ((<HH$$%QR--,,  	 E	 Hr   c                 :  > [        U [        5      (       dr  U R                  R                  SS5      (       + nSU R                  ;   a!  U(       a  [        R
                  " S[        SS9  U R                  5         [        TU ]$  " U0 UD6$ [        TU ]$  " U0 UDSS0D6$ )zHandle a get request.r?   Fidentity_providerz~WebSocketMixin sub-class does not inherit from JupyterHandler preventing proper authentication using custom identity provider.   )
stacklevel_redirect_to_login)

isinstancer	   r   r   warningswarnr
   rF   superprepare)r   r:   r;   should_authenticate	__class__s       r   rQ   WebSocketMixin.preparel   s     $//&*mm&7&78VX]&^"^"dmm38KX, 	 7?D3F33wII5IIr   c                   > U R                   R                  SU R                  R                  5        U R                  S:  a  [
        R                  R                  5       nUR                  5       U l	        U R                  U l
        [
        R                  " U R                  U R                  5      U l        U R                  R                  5         [        TU ]@  " U0 UD6$ )zOpen the websocket.zOpening websocket %sr   )r1   debugr(   pathr   r   IOLoopcurrenttime	last_ping	last_pongPeriodicCallback	send_pingping_callbackstartrP   open)r   r:   r;   looprS   s       r   ra   WebSocketMixin.open|   s     	-t||/@/@A !==((*D!YY[DN!^^DN!'!8!8"""D $$&w|T,V,,r   c                 .   U R                   c(  U R                  b  U R                  R                  5         gU R                   R                  (       a  U R	                  5         g[
        R                  R                  5       R                  5       nSXR                  -
  -  nSXR                  -
  -  nUSU R                  -  :  a<  X R                  :  a-  U R                  R                  SU5        U R	                  5         gU R                  S5        Xl
        g)z'send a ping to keep the websocket aliveNg     @@rJ   z#WebSocket ping timeout after %i ms.r   )ws_connectionr_   stopclient_terminatedcloser   rX   rY   rZ   r\   r[   r   r   r1   r2   ping)r   nowsince_last_pongsince_last_pings       r   r^   WebSocketMixin.send_ping   s     %$*<*<*H##%//JJL mm##%**,~~!56~~!56Q!3!333J[J[8[HHBOTJJL		#r   c                 f    [         R                  R                  5       R                  5       U l        g)zHandle a pong message.N)r   rX   rY   rZ   r\   )r   datas     r   on_pongWebSocketMixin.on_pong   s    ..0557r   )r[   r\   r_   )N)__name__
__module____qualname____firstlineno____doc__r_   r[   r\   r   r   r   __annotations__propertyr   r   r   strr.   r6   r<   rF   rQ   ra   r^   rp   __static_attributes____classcell__)rS   s   @r   r   r      s    ,MII!%FHX%G G 
 
 (8C= (D ( (T) - -" J J - -   .8 8r   r   )rv   r/   rN   typingr   r   urllib.parser   tornador   r   tornado.iostreamr   jupyter_server.base.handlersr	   jupyter_server.utilsr
   r   r   r9   r   r   <module>r      s4     	  * !  % 7 9  U8 U8r   