o
    Óó·iv@  ã                   @  sú  d Z ddlmZ ddlZddlmZmZ ddlmZ ddlm	Z	m
Z
mZmZ ddlm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mZmZmZmZmZmZmZm Z!m"Z" ddl#m$Z$ ddl%m&Z& ddl'm(Z( ddl)m*Z*m+Z+m,Z,m-Z-m.Z. ddl/m0Z1 ddl2m3Z3 ddl4m5Z5 ddl6m7Z7 ddl8m9Z9m:Z:m;Z;m<Z< ddl=m>Z> ddl?m@Z@mAZA ddlBmCZC ddlDmEZEm Z  G dd„ dejFƒZGeG dd„ deHƒƒZIG dd„ dejFƒZJedd eJd!�ZKe	eeef e.gdf ZLe3ƒ ZMG d"d#„ d#ejFeK ƒZNG d$d%„ d%ejFeK ƒZOed d&�G d'd(„ d(ƒƒZPedXd/d0„ƒZQee+ƒeG d1d2„ d2e
eK ƒƒƒZReReJ ZSeQjTdYd4d5„ƒZUeQjTdZd7d8„ƒZVeQjTd[d:d;„ƒZWeQjTd\d=d>„ƒZXeQjTd]d@dA„ƒZYeQjTd^dCdD„ƒZZeQjTd_dFdG„ƒZ[eQjTd`dIdJ„ƒZ\dadNdO„Z]G dPdQ„ dQeCƒZ^dbdVdW„Z_dS )czD
Private implementation module for public L{twisted.web.websocket}.
é    )ÚannotationsN)Ú	dataclassÚfield)Úsingledispatch)ÚCallableÚGenericÚTypeVarÚUnion)Úimplementer)ÚURL)Ú
ConnectionÚConnectionTypeÚWSConnection)ÚConnectionState)
ÚAcceptConnectionÚBytesMessageÚCloseConnectionÚEventÚPingÚPongÚRejectConnectionÚ
RejectDataÚRequestÚTextMessage)ÚH11Handshake)ÚRemoteProtocolError)ÚDeferred)Ú	IConsumerÚ	IProtocolÚIPushProducerÚIReactorTCPÚ
ITransport)ÚFactory)ÚLogger)ÚFailure)ÚBAD_REQUEST)ÚURIÚBrowserLikePolicyForHTTPSÚResponseÚ_StandardEndpointFactory)ÚHeaders)ÚIAgentEndpointFactoryÚIPolicyForHTTPS)ÚResource)ÚNOT_DONE_YETr   c                   @  sP   e Zd ZdZddd„Zdd
d„Zdddd„Zd d!dd„Zd"dd„Zd#dd„Z	dS )$ÚWebSocketTransportz9
    The transport that can send websocket messages.
    ÚtextÚstrÚreturnÚNonec                 C  ó   dS )z&
        Send a text message.
        N© )Úselfr0   r5   r5   úaC:\Users\psant\Downloads\PAF backend\school\venv\Lib\site-packages\twisted/web/_websocket_impl.pyÚsendTextMessageA   ó    z"WebSocketTransport.sendTextMessageÚdataÚbytesc                 C  r4   )z'
        Send a bytes message.
        Nr5   ©r6   r:   r5   r5   r7   ÚsendBytesMessageF   r9   z#WebSocketTransport.sendBytesMessageéè  ÚcodeÚintc                 C  r4   )z0
        Drop the websocket connection.
        Nr5   )r6   r?   r5   r5   r7   ÚloseConnectionK   r9   z!WebSocketTransport.loseConnectionó    Úpayloadc                 C  r4   )a  
        Send a websocket Ping request to measure latency.

        @note: Per U{Mozilla's documentation
            <https://developer.mozilla.org/en-US/docs/Web/API/WebSockets_API/Writing_WebSocket_servers#pings_and_pongs_the_heartbeat_of_websockets>},
            multiple 'ping' requests may be coalesced into a single 'pong', and
            unsolicited 'pong' requests must be ignored, so we do not return a
            L{deferred <twisted.internet.defer.Deferred>} here; pongs are
            delivered separately.
        Nr5   ©r6   rC   r5   r5   r7   ÚpingP   r9   zWebSocketTransport.pingÚproducerr   c                 C  r4   )zF
        Attach the given L{IPushProducer} to this transport.
        Nr5   ©r6   rF   r5   r5   r7   ÚattachProducer\   r9   z!WebSocketTransport.attachProducerc                 C  r4   )zT
        Detach a previously attached L{IPushProducer} from this transport.
        Nr5   ©r6   r5   r5   r7   ÚdetachProducera   r9   z!WebSocketTransport.detachProducerN©r0   r1   r2   r3   ©r:   r;   r2   r3   )r>   )r?   r@   r2   r3   ©rB   ©rC   r;   r2   r3   ©rF   r   r2   r3   ©r2   r3   )
Ú__name__Ú
__module__Ú__qualname__Ú__doc__r8   r=   rA   rE   rH   rJ   r5   r5   r5   r7   r/   <   s    


r/   c                   @  s   e Zd ZU dZded< dS )ÚConnectionRejectedz‡
    A websocket connection was rejected by an HTTP response.

    @ivar response: The HTTP response that describes the rejection.
    r(   ÚresponseN)rQ   rR   rS   rT   Ú__annotations__r5   r5   r5   r7   rU   g   s   
 rU   c                   @  sL   e Zd ZdZddd„Zddd	„Zddd„Zddd„Zddd„Zddd„Z	dS ) ÚWebSocketProtocolac  
    An object that conforms to L{WebSocketProtocol} can receive all the events
    from a websocket connection.

    @note: While this is I{sort of} like a L{byte-stream protocol
        <twisted.internet.interfaces.IProtocol>}, the interface is distinct in
        a few ways; in particular, we have discrete C{negotiationStarted} and
        C{negotiationFinished} methods, representing those events in the
        websocket handshaking process, and no C{connectionMade}; similarly,
        since websockets can natively support both text and bytes messages,
        rather than fragmentable segments of a byte stream, we have
        C{textMessageReceived} and C{bytesMessageReceived} but no
        C{dataReceived}.  Finally, this is a L{typing.Protocol} and not a
        L{zope.interface.Interface}, since it does not predate the L{typing}
        module.
    Ú	transportr/   r2   r3   c                 C  r4   )z’
        An underlying transport (e.g.: a TCP connection) has been established;
        negotiation of the websocket transport has begun.
        Nr5   ©r6   rY   r5   r5   r7   ÚnegotiationStarted„   r9   z$WebSocketProtocol.negotiationStartedc                 C  r4   )zn
        Negotiation is complete: a bidirectional websocket channel is now fully
        established.
        Nr5   rI   r5   r5   r7   ÚnegotiationFinishedŠ   r9   z%WebSocketProtocol.negotiationFinishedrC   r;   c                 C  r4   )a¨  
        A Pong message was received.

        @note: Per U{the standard
            <https://www.rfc-editor.org/rfc/rfc6455#section-5.5.2>}::

                A Pong frame sent in response to a Ping frame must have identical
                "Application data" as found in the message body of the Ping frame
                being replied to.

                If an endpoint receives a Ping frame and has not yet sent Pong
                frame(s) in response to previous Ping frame(s), the endpoint MAY
                elect to send a Pong frame for only the most recently processed
                Ping frame.

            Given that some Pong frames may be dropped, this event should only
            be used in concert with the transport's L{.ping
            <WebSocketTransport.ping>} method for its intended purpose, to
            measure latency and connection durability, not to transport
            application data.
        Nr5   rD   r5   r5   r7   ÚpongReceived�   r9   zWebSocketProtocol.pongReceivedÚmessager1   c                 C  r4   )z<
        A text message was received from the peer.
        Nr5   )r6   r^   r5   r5   r7   ÚtextMessageReceived§   r9   z%WebSocketProtocol.textMessageReceivedr:   c                 C  r4   )z=
        A bytes message was received from the peer.
        Nr5   r<   r5   r5   r7   ÚbytesMessageReceived¬   r9   z&WebSocketProtocol.bytesMessageReceivedÚreasonr$   c                 C  r4   )z4
        The websocket connection was lost.
        Nr5   ©r6   ra   r5   r5   r7   ÚconnectionLost±   r9   z WebSocketProtocol.connectionLostN)rY   r/   r2   r3   rP   rN   )r^   r1   r2   r3   rL   ©ra   r$   r2   r3   )
rQ   rR   rS   rT   r[   r\   r]   r_   r`   rc   r5   r5   r5   r7   rX   r   s    




rX   Ú_WSPT)Ú	covariantÚboundc                   @  ó   e Zd ZdZd	dd„ZdS )
ÚWebSocketServerFactoryz²
    A L{WebSocketServerFactory} is a factory for a particular kind of
    L{WebSocketProtocol} that implements server-side websocket listeners via
    L{WebSocketResource}.
    Úrequestr   r2   re   c                 C  r4   )a/  
        To conform to L{WebSocketServerFactory}, you must implement a
        C{buildProtocol} method which takes a L{Request
        <twisted.web.server.Request>} and returns a L{WebSocketProtocol}.

        @return: a L{WebSocketProtocol} that will handle the inbound
            connection.
        Nr5   )r6   rj   r5   r5   r7   ÚbuildProtocolÃ   r9   z$WebSocketServerFactory.buildProtocolN)rj   r   r2   re   ©rQ   rR   rS   rT   rk   r5   r5   r5   r7   ri   ¼   ó    ri   c                   @  rh   )
ÚWebSocketClientFactoryz¸
    A L{WebSocketClientFactory} is a factory for a particular kind of
    L{WebSocketProtocol} that implements client-side websocket listeners via
    L{WebSocketClientEndpoint}.
    Úurlr1   r2   re   c                 C  r4   )a#  
        To conform to L{WebSocketServerFactory}, you must implement a
        C{buildProtocol} method which takes a string representing an URL and
        returns a L{WebSocketProtocol}.

        @return: a L{WebSocketProtocol} that will handle the outgoing
            connection.
        Nr5   )r6   ro   r5   r5   r7   rk   Õ   r9   z$WebSocketClientFactory.buildProtocolN)ro   r1   r2   re   rl   r5   r5   r5   r7   rn   Î   rm   rn   )Úfrozenc                   @  sH   e Zd ZU dZded< 	 ded< 	 eeƒ ddfddd„ƒZddd„ZdS )ÚWebSocketClientEndpointz¬
    A L{WebSocketClientEndpoint} describes an URL to connect to and a way of
    connecting to that URL, that can connect a L{WebSocketClientFactory} to
    that URL.
    r+   ÚendpointFactoryr1   ro   NÚreactorr    Ú	tlsPolicyr,   ÚconnectTimeoutú
int | NoneÚbindAddressúbytes | Noner2   c                 C  s   t ||||ƒ}t||ƒS )a)  
        Construct a L{WebSocketClientEndpoint} from a reactor and a URL.

        @param reactor: The reactor to use for the TCP connection.

        @param url: a string describing an URL where a websocket server lives.

        @param tlsPolicy: The TLS policy to use for HTTPS connections.

        @param connectTimeout: The number of seconds for the TCP-level
            connection timeout.

        @param bindAddress: The bind address to use for the TCP client
            connections.

        @return: the newly constructed endpoint.
        N)r)   rq   )Úclsrs   ro   rt   ru   rw   rr   r5   r5   r7   Únewò   s   ÿ
zWebSocketClientEndpoint.newÚprotocolFactoryúWebSocketClientFactory[_WSP]re   c                 ƒ  sX   �ˆj  t ˆj d¡¡¡}d‡fdd	„‰ | t ‡ ‡‡fd
d„¡¡I dH }|j	I dH S )ae  
        Make an outgoing connection to this L{WebSocketClientEndpoint}'s HTTPS
        connection.

        @param protocolFactory: The constructor for the protocol.

        @return: A coroutine (that yields L{Deferred}s) that completes with the
            connected L{WebSocketProtocol} once the websocket connection is
            established.
        zutf-8ÚwscúWSConnection | ConnectionÚtr!   r2   r3   c                   s<   t  ˆ j¡}t|jddd d�ƒ}| |  t|j|ƒ¡¡ d S )NÚ )ÚschemeÚhostÚport)	r   ZfromTextro   r1   ÚreplaceÚwriteÚsendÚ	WSRequestr‚   )r}   r   ÚhÚtargetrI   r5   r7   ÚclientBootstrap   s   z8WebSocketClientEndpoint.connect.<locals>.clientBootstrapc                     s   t ttjƒˆ ˆ ˆj¡ƒS ©N)Ú_WebSocketWireProtocolr   r   ZCLIENTrk   ro   r5   ©rŠ   r{   r6   r5   r7   Ú<lambda>'  s
    
ýz1WebSocketClientEndpoint.connect.<locals>.<lambda>N©r}   r~   r   r!   r2   r3   )
rr   ZendpointForURIr&   Z	fromBytesro   ÚencodeÚconnectÚProtocolFactoryZforProtocolÚ_done)r6   r{   ZendpointÚ	connectedr5   r�   r7   r‘     s   €ÿÿ
ÿ	zWebSocketClientEndpoint.connect)rs   r    ro   r1   rt   r,   ru   rv   rw   rx   r2   rq   )r{   r|   r2   re   )	rQ   rR   rS   rT   rW   Úclassmethodr'   rz   r‘   r5   r5   r5   r7   rq   à   s   
 úrq   Úeventr   ÚprotoÚAnyWSWPr2   r3   c                 C  r4   )z,
    Handle a websocket protocol event.
    Nr5   ©r–   r—   r5   r5   r7   Ú_handleEvent1  r9   rš   c                   @  sÒ   e Zd ZU ded< ded< ded< edd�Zd	ed
< edd�Zded< dZded< d8dd„Zd9dd„Z	d:dd„Z
d;dd„Zd<d d!„Zd:d"d#„Zd=d>d&d'„Zd?d@d,d-„ZdAd0d1„Zd9d2d3„Zd9d4d5„Zd9d6d7„ZdS )BrŒ   r~   Ú_wsconnÚ
_BootstrapÚ
_bootstrapre   Ú_wspF)Úinitr!   rY   zDeferred[_WSP]r“   NzResponse | NoneÚ_rejectResponser2   r3   c                 C  s   || _ tƒ | _|  ¡  d S r‹   )rY   r   r“   ÚconnectionMaderZ   r5   r5   r7   ÚmakeConnectionG  s   z%_WebSocketWireProtocol.makeConnectionc                 C  s    | j  | ¡ |  | j| j¡ d S r‹   )rž   r[   r�   r›   rY   rI   r5   r5   r7   r¡   L  s   z%_WebSocketWireProtocol.connectionMader:   r;   c                 C  s*   | j  |¡ | j  ¡ D ]}t|| ƒ qd S r‹   )r›   Zreceive_dataÚeventsrš   )r6   r:   r–   r5   r5   r7   ÚdataReceivedQ  s   ÿz#_WebSocketWireProtocol.dataReceivedra   r$   c                 C  s0   | j  |¡ | jd ur| j |¡ d | _d S d S r‹   )rž   rc   r    Z_bodyDataFinishedrb   r5   r5   r7   rc   V  s
   

þz%_WebSocketWireProtocol.connectionLostr0   r1   c                 C  ó,   | j }|d us	J ‚| | j t|ƒ¡¡ d S r‹   )rY   r…   r›   r†   r   )r6   r0   r   r5   r5   r7   r8   ]  ó   z&_WebSocketWireProtocol.sendTextMessagec                 C  r¥   r‹   )rY   r…   r›   r†   r   )r6   r:   r   r5   r5   r7   r=   b  r¦   z'_WebSocketWireProtocol.sendBytesMessagerB   rC   c                 C  r¥   r‹   )rY   r…   r›   r†   r   )r6   rC   r   r5   r5   r7   rE   g  r¦   z_WebSocketWireProtocol.pingr>   r€   r?   r@   c                 C  s6   | j }|d us	J ‚| | j t||ƒ¡¡ | ¡  d S r‹   )rY   r…   r›   r†   r   rA   )r6   r?   ra   r   r5   r5   r7   rA   l  s   z%_WebSocketWireProtocol.loseConnectionrF   r   c                 C  s   t | jƒ |d¡ d S )NT)r   rY   ZregisterProducerrG   r5   r5   r7   rH   r  s   z%_WebSocketWireProtocol.attachProducerc                 C  s   t | jƒ ¡  d S r‹   )r   rY   ZunregisterProducerrI   r5   r5   r7   rJ   u  s   z%_WebSocketWireProtocol.detachProducerc                 C  s$   | j }| ` | | j¡ | j ¡  d S r‹   )r“   Úcallbackrž   r\   ©r6   Údoner5   r5   r7   Ú_completeConnectionx  s   z*_WebSocketWireProtocol._completeConnectionc                 C  s,   | j d usJ ‚| j}| `| t| j ƒ¡ d S r‹   )r    r“   ZerrbackrU   r¨   r5   r5   r7   Ú_rejectConnection~  s   z(_WebSocketWireProtocol._rejectConnection)rY   r!   r2   r3   rP   rL   rd   rK   rM   rN   )r>   r€   )r?   r@   ra   r1   r2   r3   rO   )rQ   rR   rS   rW   r   rY   r“   r    r¢   r¡   r¤   rc   r8   r=   rE   rA   rH   rJ   rª   r«   r5   r5   r5   r7   rŒ   8  s&   
 








rŒ   r   c                 C  s   |  ¡  d S r‹   )rª   r™   r5   r5   r7   Ú_handle_acceptConnectionˆ  s   r¬   r   c                 C  sD   t ƒ }| jD ]
\}}| ||¡ qtd| jd||jƒ|_| ¡  d S )Nz1.1r€   )r*   ÚheadersZaddRawHeaderr(   Ústatus_coderY   r    r«   )r–   r—   ÚhdrÚkÚvr5   r5   r7   Ú_handle_rejectConnection�  s
   r²   r   c                 C  s8   |j d us	J dƒ‚|j  | j¡ | jr|j ¡  d S d S )Nz7response should never be None when receiving RejectData)r    Z_bodyDataReceivedr:   Zbody_finishedrY   rA   r™   r5   r5   r7   Ú_handle_rejectData–  s   ÿþÿr³   r   c                 C  ó   |j  | j¡ d S r‹   )rž   r_   r:   r™   r5   r5   r7   Ú_handle_textMessage   ó   rµ   r   c                 C  r´   r‹   )rž   r`   r:   r™   r5   r5   r7   Ú_handle_bytesMessage¥  r¶   r·   r   c                 C  s   |j  |j |  ¡ ¡¡ d S r‹   )rY   r…   r›   r†   rV   r™   r5   r5   r7   Ú_handle_pingª  s   r¸   r   c                 C  r´   r‹   )rž   r]   rC   r™   r5   r5   r7   Ú_handle_pong¯  r¶   r¹   r   c                 C  sB   |j d usJ ‚|jjtjkr|j  |j |  ¡ ¡¡ |j  ¡  d S r‹   )	rY   r›   Ústater   ZCLOSEDr…   r†   rV   rA   r™   r5   r5   r7   Ú_handle_closeConnection´  s   r»   rj   r   r;   c                 C  s   |   t¡ |  dd¡ dS )Nzcontent-typez
text/plains$   websocket protocol negotiation error)ZsetResponseCoder%   Z	setHeader)rj   r5   r5   r7   Ú_negotiationError¼  s   
r¼   c                      s,   e Zd ZdZd‡ fdd„Zddd„Z‡  ZS )ÚWebSocketResourcezœ
    A L{WebSocketResource} is a L{Resource} that presents a websocket listener.
    You can install it into any twisted web server resource hierarchy.
    Úfactoryú)WebSocketServerFactory[WebSocketProtocol]r2   r3   c                   s   t ƒ  ¡  || _dS )a#  
        Create a L{WebSocketResource} that will respond to incoming connections
        with the given L{WebSocketServerFactory}.

        @param factory: The factory that will be used to respond to inbound
            websocket connections on appropriately formatted GET requests.
        N)ÚsuperÚ__init__r¾   )r6   r¾   ©Ú	__class__r5   r7   rÁ   È  s   

zWebSocketResource.__init__rj   r   úbytes | intc              
   C  sö   t tjƒ}|j ¡ }dd„ |D ƒ}z	| ||j¡ W n ty8 } ztj	d||d� t
|ƒW  Y d}~S d}~ww | j |¡}|dusGJ dƒ‚| tƒ ¡}|j}|jj}	|	dus\J dƒ‚|dusdJ dƒ‚t|t|ƒ}
|j |
¡ |	 |¡ | ¡  tS )	zv
        This implementation of the C{GET} HTTP method will respond to inbound
        websocket connections.
        c                 S  s"   g | ]\}}|D ]}||f‘qqS r5   r5   )Ú.0ÚhkeyZhvalsÚvalr5   r5   r7   Ú
<listcomp>Ú  s   " z0WebSocketResource.render_GET.<locals>.<listcomp>z{request} failed with {rpe})rj   ÚrpeNz"connection not accepted by twistedzchannel transport not connectedz"connection not accepted by wsproto)r   r   ZSERVERZrequestHeadersZgetAllRawHeadersZinitiate_upgrade_connectionÚpathr   Ú_logÚerrorr¼   r¾   rk   r†   r   Ú
connectionZchannelrY   rŒ   ÚserverBootstrapZ_protocolUpgradeForWebsocketsr…   r\   r.   )r6   rj   Z	handshakeÚrawZsimpleHeadersrÉ   ZwsprotZtoSendZwsconr   Z	wireProtor5   r5   r7   Ú
render_GETÓ  s,   

€þ
zWebSocketResource.render_GET)r¾   r¿   r2   r3   )rj   r   r2   rÄ   )rQ   rR   rS   rT   rÁ   rÐ   Ú__classcell__r5   r5   rÂ   r7   r½   Â  s    r½   r}   r~   r   r!   c                 C  r4   )zC
    The server requires no bootstrapping, so this is a no-op.
    Nr5   )r}   r   r5   r5   r7   rÎ   î  r9   rÎ   )r–   r   r—   r˜   r2   r3   )r–   r   r—   r˜   r2   r3   )r–   r   r—   r˜   r2   r3   )r–   r   r—   r˜   r2   r3   )r–   r   r—   r˜   r2   r3   )r–   r   r—   r˜   r2   r3   )r–   r   r—   r˜   r2   r3   )r–   r   r—   r˜   r2   r3   )r–   r   r—   r˜   r2   r3   )rj   r   r2   r;   r�   )`rT   Ú
__future__r   ÚtypingÚdataclassesr   r   Ú	functoolsr   r   r   r   r	   Zzope.interfacer
   Z	hyperlinkr   Zwsprotor   r   r   Zwsproto.connectionr   Zwsproto.eventsr   r   r   r   r   r   r   r   r   r‡   r   Zwsproto.handshaker   Zwsproto.utilitiesr   Ztwisted.internet.deferr   Ztwisted.internet.interfacesr   r   r   r    r!   Ztwisted.internet.protocolr"   r’   Ztwisted.loggerr#   Ztwisted.python.failurer$   Ztwisted.web._responsesr%   Ztwisted.web.clientr&   r'   r(   r)   Ztwisted.web.http_headersr*   Ztwisted.web.iwebr+   r,   Ztwisted.web.resourcer-   Ztwisted.web.serverr.   ÚProtocolr/   Ú	ExceptionrU   rX   re   rœ   rË   ri   rn   rq   rš   rŒ   r˜   Úregisterr¬   r²   r³   rµ   r·   r¸   r¹   r»   r¼   r½   rÎ   r5   r5   r5   r7   Ú<module>   sx   0+
EPK	
,