
    Xh@                         d Z ddlZddlZddlmZmZ ddlmZ ddlm	Z	m
Z
 ddlmZ ddlmZ ddlmZ d	Z G d
 d      Zy)zBase websocket classes.    N)Optionalno_type_check)urlparse)ioloopweb)IOStream)JupyterHandler)JupyterServerAuthWarningi0u  c                        e Zd ZU dZdZdZdZdZee	   e
d<   ed        Zed        Zeddee   defd	       Zd
 Zed        Ze fd       Ze fd       Zed        Zd Z xZS )WebSocketMixinz"Mixin for common websocket optionsNg        streamc                 B    | j                   j                  dt              S )ziThe interval for websocket keep-alive pings.

        Set ws_ping_interval = 0 to disable pings.
        ws_ping_interval)settingsgetWS_PING_INTERVALselfs    Q/var/www/html/myenv/lib/python3.12/site-packages/jupyter_server/base/websocket.pyping_intervalzWebSocketMixin.ping_interval   s     }}  !35EFF    c                 p    | j                   j                  dt        d| j                  z  t                    S )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_timeoutzWebSocketMixin.ping_timeout"   s3     }}  s1t'9'9#9;KL
 	
r   originreturnc                    | j                   dk(  st        | d      r| j                         ry| j                  j                  j                  d      }|| j                         }||y|j                         }t        |      j                  }||k(  ry| j                   r| j                   |k(  }n8| j                  r*t        t        j                  | j                  |            }nd}|s| j                  j                  d||       |S )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_originzWebSocketMixin.check_origin,   s     #D-.43I3I3K||##''/>__&F >T\v&-- $ %%/E""$"7"7@AE EHHP
 r   c                      y)zmeaningless for websocketsN )r   argskwargss      r   clear_cookiezWebSocketMixin.clear_cookieW   s    r   c                    | j                   j                  dd      s| j                  j                  st	        j
                  d      t        | | j                  j                  j                               }t        |dd      s?| j                  }|0| j                  j                  d       t	        j
                  d      yyy)z}Verify 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_userr.   r/   )r   r<   users      r   _maybe_authzWebSocketMixin._maybe_authZ   s     }}  !?G<<&&mmC((T4<<#6#6#<#<#>?F6#<eD ((<HH$$%QR--,,  	 E	 Hr   c                    t        | t              sh| j                  j                  dd       }d| j                  v r|rt	        j
                  dt        d       | j                          t        | $  |i |S t        | $  |i |ddiS )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
   rA   superprepare)r   r6   r7   should_authenticate	__class__s       r   rK   zWebSocketMixin.preparel   s     $/&*mm&7&78VX]&^"^"dmm38KX, 	 7?D3F33wII5IIr   c                    | j                   j                  d| j                  j                         | j                  dkD  rt
        j                  j                         }|j                         | _	        | j                  | _
        t        j                  | j                  | j                        | _        | j                  j                          t        | @  |i |S )zOpen the websocket.zOpening websocket %sr   )r.   debugr%   pathr   r   IOLoopcurrenttime	last_ping	last_pongPeriodicCallback	send_pingping_callbackstartrJ   open)r   r6   r7   looprM   s       r   rZ   zWebSocketMixin.open|   s     	-t||/@/@A !==((*D!YY[DN!^^DN!'!8!8"""D $$&w|T,V,,r   c                 $   | j                   '| j                  | j                  j                          y| j                   j                  r| j	                          yt
        j                  j                         j                         }d|| j                  z
  z  }d|| j                  z
  z  }|d| j                  z  k  r<|| j                  kD  r-| j                  j                  d|       | j	                          y| j                  d       || _
        y)z'send a ping to keep the websocket aliveNg     @@rD   z#WebSocket ping timeout after %i ms.r   )ws_connectionrX   stopclient_terminatedcloser   rQ   rR   rS   rU   rT   r   r   r.   r/   ping)r   nowsince_last_pongsince_last_pings       r   rW   zWebSocketMixin.send_ping   s     %$*<*<*H##%//JJL mm##%**,t~~!56t~~!56Q!3!333$J[J[8[HHBOTJJL		#r   c                 f    t         j                  j                         j                         | _        y)zHandle a pong message.N)r   rQ   rR   rS   rU   )r   datas     r   on_pongzWebSocketMixin.on_pong   s    ..0557r   )N)__name__
__module____qualname____doc__rX   rT   rU   r   r   r   __annotations__propertyr   r   r   strr+   r3   r8   rA   rK   rZ   rW   rg   __classcell__)rM   s   @r   r   r      s    ,MII!%FHX%G G 
 
 (8C= (D ( (T) - -" J J - -   .8r   r   )rk   r,   rH   typingr   r   urllib.parser   tornador   r   tornado.iostreamr   jupyter_server.base.handlersr	   jupyter_server.utilsr
   r   r   r5   r   r   <module>rv      s4     	  * !  % 7 9  U8 U8r   