o
    îó·i{.  ã                   @   s~   d dl Z d dlZd dlZd dlmZ d dlmZmZmZ d dl	m
Z
 ddlmZ e  e¡ZG dd„ deƒZG d	d
„ d
eƒZdS )é    N)Úunquote)ÚConnectionDenyÚWebSocketServerFactoryÚWebSocketServerProtocol)Údeferé   )Úparse_x_forwarded_forc                   @   s¦   e Zd ZdZdZdZdd„ Zdd„ Zdd	„ Zd
d„ Z	dd„ Z
dd„ Zdd„ Zdd„ Zd'dd„Zdd„ Zd(dd„Zd'dd„Zdd„ Zdd „ Zd!d"„ Zd#d$„ Zd%d&„ ZdS ))ÚWebSocketProtocolzj
    Protocol which supports WebSockets and forwards incoming messages to
    the websocket channels.
    Ú	websocketFc                 C   s  | j j| _| j | ¡ || _d | _| jj| _t ¡ | _t ¡ | _	zÐg | _
|j ¡ D ]'\}}| d¡}d|v r7q)| ¡ dkrCt|ƒ| _q)| j
 | ¡ | d¡f¡ q)| j ¡ }| j ¡ }t|dƒrxt|dƒrxt|jƒ|jg| _t|jƒ|jg| _nd | _d | _| jjr˜tt| j
ƒ| jj| jj| jj| jƒ\| _| _g }| j
D ]\}}|dkr´dd	„ t|  d¡ƒ !d
¡D ƒ}q�|j" d¡| _"t# $| jj%| dt| j"  d¡ƒ| j"| j| j
| j&| j| j|dœ	¡| _'| j'd urï| j' (| j)¡ | j' *| j+¡ W n t,yÿ   t- .t/ 0¡ ¡ ‚ w t# 1¡ | _2| j2S )NÚasciió   _s   daphne-root-pathÚlatin1ÚhostÚports   sec-websocket-protocolc                 S   s   g | ]}|  ¡ ‘qS © )Ústrip)Ú.0Úxr   r   úXC:\Users\psant\Downloads\PAF backend\school\venv\Lib\site-packages\daphne/ws_protocol.pyÚ
<listcomp>G   s    ÿz/WebSocketProtocol.onConnect.<locals>.<listcomp>ú,r
   )	ÚtypeÚpathÚraw_pathÚ	root_pathÚheadersZquery_stringÚclientÚserverÚsubprotocols)3ÚfactoryÚserver_classr   Zprotocol_connectedÚrequestZprotocol_to_acceptr   ÚtimeÚsocket_openedÚ	last_pingZclean_headersr   ÚitemsÚencodeÚlowerr   ÚappendÚ	transportZgetPeerZgetHostÚhasattrÚstrr   r   Úclient_addrZserver_addrZproxy_forwarded_address_headerr   ÚdictZproxy_forwarded_port_headerZproxy_forwarded_proto_headerZclient_schemeÚdecodeÚsplitr   r   ZmaybeDeferredZcreate_applicationZ_raw_query_stringZapplication_deferredZaddCallbackÚapplicationCreateWorkedZ
addErrbackÚapplicationCreateFailedÚ	ExceptionÚloggerÚerrorÚ	tracebackÚ
format_excZDeferredÚhandshake_deferred)Úselfr!   ÚnameÚvalueZpeerr   r   Úheaderr   r   r   Ú	onConnect   s~   






ûÿ€÷ý
€ü
zWebSocketProtocol.onConnectc                 C   sH   || _ | j  ddi¡ | j dd| jj| jrdt| jƒ nddœ¡ dS )zk
        Called when the background thread has successfully made the application
        instance.
        r   zwebsocket.connectr
   Z
connectingú%s:%sN©r   r   )Úapplication_queueÚ
put_nowaitr   Ú
log_actionr!   r   r,   Útuple)r8   r?   r   r   r   r0   h   s   ýýz)WebSocketProtocol.applicationCreateWorkedc                 C   s   t  |¡ |S )z9
        Called when application creation fails.
        N)r3   r4   )r8   Zfailurer   r   r   r1   |   s   
z)WebSocketProtocol.applicationCreateFailedc                 C   s@   t  d| j¡ | j dd| jj| jrdt| jƒ nd dœ¡ d S )Nz!WebSocket %s open and establishedr
   Ú	connectedr=   r>   )r3   Údebugr,   r   rA   r!   r   rB   ©r8   r   r   r   ÚonOpen…   s   ýýzWebSocketProtocol.onOpenc                 C   sf   | j rt d| j¡ d S t d| j¡ t ¡ | _|r%| j d|dœ¡ d S | j d| d¡dœ¡ d S )NzMuting incoming frame on %szWebSocket incoming frame on %szwebsocket.receive)r   ÚbytesÚutf8)r   Útext)	Úmutedr3   rD   r,   r"   r$   r?   r@   r.   )r8   ÚpayloadZisBinaryr   r   r   Ú	onMessage“   s   
ÿÿzWebSocketProtocol.onMessagec                 C   sn   | j  | ¡ t d| j¡ | jst| dƒr| j d|dœ¡ | j  	dd| j
j| jr0dt| jƒ ndd	œ¡ dS )
z8
        Called when Twisted closes the socket.
        zWebSocket closed for %sr?   zwebsocket.disconnect)r   Úcoder
   Údisconnectedr=   Nr>   )r   Úprotocol_disconnectedr3   rD   r,   rJ   r*   r?   r@   rA   r!   r   rB   )r8   ZwasCleanrM   Úreasonr   r   r   ÚonClose£   s   ÿýýzWebSocketProtocol.onClosec                 C   sø   d|vrt dƒ‚|d dkr|  | dd ¡¡ d S |d dkr7| j| jkr+|  ¡  d S | j| dd ¡d� d S |d dkrx| j| jkrGt d	ƒ‚| d
d ¡rZ| dd ¡rZt d|f ƒ‚| d
d ¡rh|  |d
 d¡ | dd ¡rz|  |d d¡ d S d S d S )Nr   zMessage has no type definedzwebsocket.acceptÚsubprotocolzwebsocket.closerM   ©rM   zwebsocket.sendz4Socket has not been accepted, so cannot send over itrG   rI   zMGot invalid WebSocket reply message on %s - contains both bytes and text keysTF)Ú
ValueErrorÚserverAcceptÚgetÚstateÚSTATE_CONNECTINGÚserverRejectÚserverCloseÚ
serverSend)r8   Úmessager   r   r   Úhandle_replyº   s.   ÿÿõ
zWebSocketProtocol.handle_replyc                 C   s2   t | dƒr| j tddd�¡ dS | jdd� dS )zF
        Called by the server when our application tracebacks
        r7   iô  zInternal server error©rM   rP   ió  rS   N)r*   r7   Úerrbackr   ZsendCloseFrame)r8   Ú	exceptionr   r   r   Úhandle_exceptionÑ   s
   

ÿz"WebSocketProtocol.handle_exceptionNc                 C   s"   | j  |¡ | ` t d| j¡ dS )zO
        Called when we get a message saying to accept the connection.
        z$WebSocket %s accepted by applicationN)r7   Úcallbackr3   rD   r,   )r8   rR   r   r   r   rU   Þ   s   zWebSocketProtocol.serverAcceptc                 C   sd   | j  tddd�¡ | ` | j | ¡ t d| j¡ | j dd| j	j
| jr+dt| jƒ ndd	œ¡ dS )
zO
        Called when we get a message saying to reject the connection.
        i“  zAccess deniedr^   z$WebSocket %s rejected by applicationr
   Zrejectedr=   Nr>   )r7   r_   r   r   rO   r3   rD   r,   rA   r!   r   rB   rE   r   r   r   rY   æ   s   
ÿýýzWebSocketProtocol.serverRejectc                 C   sL   | j | jkr
|  ¡  t d| j¡ |r|  ||¡ dS |  | d¡|¡ dS )z@
        Server-side channel message to send a message.
        z&Sent WebSocket packet to client for %srH   N)rW   rX   rU   r3   rD   r,   ZsendMessager&   )r8   ÚcontentÚbinaryr   r   r   r[   û   s   zWebSocketProtocol.serverSendc                 C   s    |du rdn|}| j |d� dS )zA
        Server-side channel message to close the socket
        Niè  rS   )Z	sendClose)r8   rM   r   r   r   rZ     s   zWebSocketProtocol.serverClosec                 C   s   t   ¡ | j S )z>
        Returns the time since the socket was opened
        N)r"   r#   rE   r   r   r   Úduration  s   zWebSocketProtocol.durationc                 C   s�   |   ¡ | jjkr| jjdkr|  ¡  | j| jkr(|   ¡ | jjkr&|  ¡  dS dS | j| jkrDt	 	¡ | j
 | jjkrF|  ¡  t	 	¡ | _
dS dS dS )zK
        Called periodically to see if we should timeout something
        r   N)re   r   Zwebsocket_timeoutrZ   rW   rX   Zwebsocket_connect_timeoutrY   Z
STATE_OPENr"   r$   Zping_intervalZ_sendAutoPingrE   r   r   r   Úcheck_timeouts  s   ÿ
þÿýz WebSocketProtocol.check_timeoutsc                 C   s   t t| ƒƒS ©N)ÚhashÚidrE   r   r   r   Ú__hash__*  s   zWebSocketProtocol.__hash__c                 C   s   t | ƒt |ƒkS rg   )ri   )r8   Úotherr   r   r   Ú__eq__-  s   zWebSocketProtocol.__eq__c                 C   s   d| j ›d| j›d�S )Nz<WebSocketProtocol client=z path=ú>)r,   r   rE   r   r   r   Ú__repr__0  s   zWebSocketProtocol.__repr__rg   )F)Ú__name__Ú
__module__Ú__qualname__Ú__doc__Zapplication_typerJ   r<   r0   r1   rF   rL   rQ   r]   ra   rU   rY   r[   rZ   re   rf   rj   rl   rn   r   r   r   r   r	      s*    K	


	r	   c                       s,   e Zd ZdZeZdd„ Z‡ fdd„Z‡  ZS )ÚWebSocketFactoryzˆ
    Factory subclass that remembers what the "main"
    factory is, so WebSocket protocols can access it
    to get reply ID info.
    c                 O   s"   || _ tj| g|¢R i |¤Ž d S rg   )r    r   Ú__init__)r8   r    ÚargsÚkwargsr   r   r   rt   =  s   zWebSocketFactory.__init__c                    s<   zt ƒ  |¡}| |_|W S  ty   t dt ¡  ¡ ‚ w )zh
        Builds protocol instances. We use this to inject the factory object into the protocol.
        zCannot build protocol: %sN)ÚsuperÚbuildProtocolr   r2   r3   r4   r5   r6   )r8   ÚaddrÚprotocol©Ú	__class__r   r   rx   A  s   þzWebSocketFactory.buildProtocol)	ro   rp   rq   rr   r	   rz   rt   rx   Ú__classcell__r   r   r{   r   rs   4  s
    rs   )Úloggingr"   r5   Úurllib.parser   Zautobahn.twisted.websocketr   r   r   Ztwisted.internetr   Úutilsr   Ú	getLoggerro   r3   r	   rs   r   r   r   r   Ú<module>   s    
  $