o
    Óó·i5  ã                   @  sæ  d Z ddlmZ ddlmZmZ ddl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 dd	lm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!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, e	ddd�Z-dZ.G dd„ de&ƒZ/G dd„ de&ƒZ0ze1dƒ W n e2y§   dZ.Y n1w ddl3m4Z4m5Z5m6Z6m7Z7m8Z8m9Z9m:Z: eG dd „ d e7ƒƒZ;G d!d"„ d"e9e; ƒZ<G d#d$„ d$e6e; ƒZ=eG d%d&„ d&ee- ƒƒZ>ee.d'ƒG d(d)„ d)eƒƒZ?d*S )+z%
Tests for L{twisted.web.websocket}.
é    )Úannotations)Ú	dataclassÚfield)ÚAnyÚGenericÚTypeVar)ÚskipIf)Úimplementer)ÚDeferred)ÚConnectionDone)ÚIPushProducer)ÚAccumulatingProtocolÚMemoryReactorClock)ÚFailure)ÚConnectionCompleterÚIOPump)ÚSynchronousTestCase)ÚBAD_REQUEST)ÚAgentÚreadBody)ÚIRequest)ÚResource)ÚNOT_DONE_YETÚRequestÚSite)ÚDataÚWSPÚWebSocketProtocol)ÚboundFc                   @  ó   e Zd Zddd„ZdS )	ÚWeirdResourceÚrequestr   ÚreturnÚbytesc                 C  s   |  d¡ dS )a¯  
        Per U{the wsproto documentation
        <https://python-hyper.org/projects/wsproto/en/latest/api.html#wsproto.events.RejectConnection.has_body>}:

            - The only scenario in which the caller receives a RejectConnection
              with C{has_body == False} is if the peer violates sends an
              informational status code (1xx) other than 101

        This is a weird edge case so we provoke it.
        éf   ó    N)ZsetResponseCode©Úselfr!   © r(   úeC:\Users\psant\Downloads\PAF backend\school\venv\Lib\site-packages\twisted/web/test/test_websocket.pyÚ
render_GET#   s   
zWeirdResource.render_GETN)r!   r   r"   r#   )Ú__name__Ú
__module__Ú__qualname__r*   r(   r(   r(   r)   r    "   ó    r    c                   @  s   e Zd ZdZd	dd„ZdS )
ÚDelayedResponsez¾
    A resource that will not respond to a C{GET} request right away.  You will
    need to use the C{request.write(b'RESPONSE BODY')} and C{request.finish()}
    to trigger a response.
    r!   r   r"   Úintc                 C  s
   || _ tS ©N)r!   r   r&   r(   r(   r)   r*   9   s   zDelayedResponse.render_GETN)r!   r   r"   r0   )r+   r,   r-   Ú__doc__r*   r(   r(   r(   r)   r/   2   s    r/   ZwsprotoT)ÚConnectionRejectedÚWebSocketClientEndpointÚWebSocketClientFactoryr   ÚWebSocketResourceÚWebSocketServerFactoryÚWebSocketTransportc                   @  s€   e Zd ZU dZeed�Zded< dZded< 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*dd „Zd+d"d#„ZdS ),ÚMyWSPz
        Used to implement both client-side and server-side WebSocket
        application that will help with testing.
        ©Údefault_factoryzlist[bytes]ÚpongsNzFailure | NoneÚwasLostÚ	transportr8   r"   ÚNonec                 C  ó
   || _ d S r1   )r>   )r'   r>   r(   r(   r)   ÚnegotiationStartedW   ó   
zMyWSP.negotiationStartedc                 C  s   d S r1   r(   ©r'   r(   r(   r)   ÚnegotiationFinishedZ   s   zMyWSP.negotiationFinishedÚreasonr   c                 C  r@   r1   )r=   )r'   rE   r(   r(   r)   ÚconnectionLost]   rB   zMyWSP.connectionLostÚdatar#   c                 C  ó(   |dkr| j  d¡ d S | j |¡ d S )Nó   requestó    responseÿ)r>   ÚsendBytesMessageÚ	bDeferredÚcallback©r'   rG   r(   r(   r)   ÚbytesMessageReceived`   ó   zMyWSP.bytesMessageReceivedÚstrc                 C  rH   )Nr!   Úresponse)r>   ÚsendTextMessageÚdeferredrM   rN   r(   r(   r)   ÚtextMessageReceivedf   rP   zMyWSP.textMessageReceivedÚpayloadc                 C  s   | j  |¡ d S r1   )r<   Úappend)r'   rV   r(   r(   r)   ÚpongReceivedl   s   zMyWSP.pongReceivedúDeferred[str]c                 C  ó   t ƒ | _| j d¡ | jS )zR
            Send a text message to the server and expect a response.
            r!   N)r
   rT   r>   rS   rC   r(   r(   r)   ÚsendRequesto   ó   zMyWSP.sendRequestúDeferred[bytes]c                 C  rZ   )zS
            Send a bytes message to the server and expect a response.
            rI   N)r
   rL   r>   rK   rC   r(   r(   r)   ÚbytesRequestw   r\   zMyWSP.bytesRequest)r>   r8   r"   r?   ©r"   r?   )rE   r   r"   r?   )rG   r#   r"   r?   )rG   rQ   r"   r?   )rV   r#   r"   r?   )r"   rY   )r"   r]   )r+   r,   r-   r2   r   Úlistr<   Ú__annotations__r=   rA   rD   rF   rO   rU   rX   r[   r^   r(   r(   r(   r)   r9   M   s   
 






r9   c                   @  s    e Zd ZU ded< d
dd„Zd	S )Ú	MyFactoryzWebSocketFixture[Any]Úfixturer!   r   r"   r9   c                 C  s   t ƒ }| jj |¡ |S r1   )r9   rc   ÚserversrW   )r'   r!   Únewr(   r(   r)   ÚbuildProtocol‚   s   zMyFactory.buildProtocolN)r!   r   r"   r9   )r+   r,   r-   ra   rf   r(   r(   r(   r)   rb      s   
 rb   c                   @  r   )	ÚMyClientFactoryÚurirQ   r"   r9   c                 C  s   t ƒ S r1   )r9   )r'   rh   r(   r(   r)   rf   ˆ   s   zMyClientFactory.buildProtocolN)rh   rQ   r"   r9   )r+   r,   r-   rf   r(   r(   r(   r)   rg   ‡   r.   rg   c                   @  s–   e Zd ZU eƒ Zded< eed�Zded< eed�Z	ded< dZ
d	ed
< eed�Zded< eed�Zded< ed dd„ƒZd!d"dd„Zd#d$dd„ZdS )%ÚWebSocketFixtureúWebSocketClientFactory[WSP]ÚclientFactoryr:   r   Úreactorr   ÚresourceéP   r0   Ú
portNumberz	list[WSP]rd   r/   ÚslowResourcer"   úWebSocketFixture[WSP]c                 C  sz   | |ƒ}t ƒ }||_|j dt|ƒ¡ |j dtddƒ¡ |j dtƒ ¡ |j d|j¡ |j 	|j
t|j|jd�¡ |S )Ns   connects   resources	   some-datazapplication/octet-streams
   processings   slow)rl   )rb   rc   rm   ZputChildr6   r   r    rp   rl   Z	listenTCPro   r   )Úclsrk   r'   ZserverFactoryr(   r(   r)   re   •   s   
ÿÿzWebSocketFixture.newúhttp://localhost:80/connectrh   rQ   r   c                 Ã  s"   �t  | j|¡}| | j¡I d H S r1   )r4   re   rl   Úconnectrk   )r'   rh   Úclientr(   r(   r)   rt   ¥   s   €zWebSocketFixture.connectTÚgreetÚboolr   c                 C  s*   t | jƒ}|j|d�}|dusJ dƒ‚|S )aP  
        There should be a single websocket connection in progress; complete it.

        @param greet: Should we immediately issue a greeting, i.e. deliver any
            pending buffered TCP data, upon connection?  If C{False}, the
            caller must call C{flush} on the result to deliver any pending
            data.
        ©rv   NzConnection not in progress.)r   rl   ZsucceedOnce)r'   rv   Z	completerZ	succeededr(   r(   r)   Úcomplete©   s   
	zWebSocketFixture.completeN)rk   rj   r"   rq   )rs   )rh   rQ   r"   r   )T)rv   rw   r"   r   )r+   r,   r-   r   rk   ra   r   rl   r   rm   ro   r`   rd   r/   rp   Úclassmethodre   rt   ry   r(   r(   r(   r)   ri   Œ   s   
 ri   z'wsproto library required for websocketsc                   @  sf   e 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dd„Z	ddd„Z
ddd„ZdS )ÚWebSocketTestsr"   r?   c                 C  sŽ   t  tƒ ¡}t | ¡ ¡}|  |¡ |  t|j	j
ƒd¡ |  t|j	jƒd¡ | ¡ }|  |¡}| ¡ }|  |¡ | ¡  |  |  |¡d¡ dS )zÏ
        Connecting to a websocket server (installed with L{WebSocketResource})
        from a websocket client (connected with L{WebSocketClientEndpoint})
        results in a websocket connection.
        é   rR   N)ri   re   rg   r
   ÚfromCoroutinert   ÚassertNoResultÚassertEqualÚlenrl   Z
tcpServersZ
tcpClientsry   ÚsuccessResultOfr[   Úflush)r'   rc   Ú	connectedÚpumpÚwsClientÚ	requestedr(   r(   r)   Útest_websocketº   s   


zWebSocketTests.test_websocketc                 C  s\   t  tƒ ¡}t | ¡ ¡}| ¡ }|  |¡}| ¡ }|  	|¡ | 
¡  |  |  |¡d¡ dS )zŠ
        Connecting to a websocket server and sending it a bytes message results
        in C{bytesMessageReceived} being called.
        rJ   N)ri   re   rg   r
   r}   rt   ry   r�   r^   r~   r‚   r   )r'   rc   rƒ   r„   r…   Z
bRequestedr(   r(   r)   Útest_bytesMessageÌ   s   

z WebSocketTests.test_bytesMessagec                   sê   t  tƒ ¡}t | ¡ ¡ | ¡ }g ‰ ttƒG ‡ fdd„dƒƒ}|ƒ }|j	d j
 |¡ |  ˆ g ¡ |jj ¡  |  ˆ dg¡ |jj ¡  |  ˆ ddg¡ |jj ¡  |  ˆ g d¢¡ |  |jj|¡ |j	d j
 ¡  |  |jjd¡ dS )zo
        Websocket transports can notify a producer of backpressure events via
        attachProducer.
        c                      s6   e Zd Zd
‡ fdd„Zd
‡ fdd„Zd
‡ fdd„Zd	S )z6WebSocketTests.test_backpressure.<locals>.TestProducerr"   r?   c                   ó   ˆ   d¡ d S )NÚpaused©rW   rC   ©Úeventsr(   r)   ÚpauseProducingæ   ó   zEWebSocketTests.test_backpressure.<locals>.TestProducer.pauseProducingc                   r‰   )NÚresumedr‹   rC   rŒ   r(   r)   ÚresumeProducingé   r�   zFWebSocketTests.test_backpressure.<locals>.TestProducer.resumeProducingc                   r‰   )NÚstoppedr‹   rC   rŒ   r(   r)   ÚstopProducingì   r�   zDWebSocketTests.test_backpressure.<locals>.TestProducer.stopProducingNr_   )r+   r,   r-   rŽ   r‘   r“   r(   rŒ   r(   r)   ÚTestProducerä   s    r”   r   rŠ   r�   )rŠ   r�   r’   N)ri   re   rg   r
   r}   rt   ry   r	   r   rd   r>   ZattachProducerr   ZserverIOZproducerrŽ   r‘   r“   ÚassertIsZdetachProducer)r'   rc   r„   r”   ZtestProducerr(   rŒ   r)   Útest_backpressureÚ   s$   
z WebSocketTests.test_backpressurec                 C  sb   t  tƒ ¡}t | ¡ ¡}| ¡ }|  |¡}|j 	d¡ |  
|jg ¡ | ¡  |  
|jdg¡ dS )a6  
        Internally, Twisted's websocket resource responds to all ping requests
        with a pong as required by the spec, so peers can issue a C{ping} and
        receive a C{pong} message with the same payload; our websocket
        transport also implements a C{ping} method to send that message.
        s   123N)ri   re   rg   r
   r}   rt   ry   r�   r>   Zpingr   r<   r‚   ©r'   rc   rƒ   r„   r…   r(   r(   r)   Útest_pingPongü   s   
zWebSocketTests.test_pingPongc                 C  s¨   t  tƒ ¡}t | ¡ ¡}| ¡ }|  |¡}|  |j	d j
d¡ |  |j
d¡ |j ¡  |  |j	d j
d¡ |  |j
d¡ | ¡  |  |j	d j
d¡ |  |j
d¡ dS )zu
        When the underlying TCP connection is lost,
        L{WebSocketProtocol.connectionLost} is invoked.
        r   N)ri   re   rg   r
   r}   rt   ry   r�   r•   rd   r=   r>   ZloseConnectionr‚   ZassertIsNotr—   r(   r(   r)   Útest_serverConnectionLost  s   

z(WebSocketTests.test_serverConnectionLostc                 C  sj   t  tƒ ¡}t|jƒ}| dd¡}|  |¡ | ¡  |  |¡}|  	|j
t¡ t|ƒ}|  	|  |¡d¡ dS )z«
        Attempting to issue an C{HTTP GET} against a websocket server
        (installed with L{WebSocketResource}) results in a C{BAD_REQUEST}
        response.
        s   GETs   http://localhost/connects$   websocket protocol negotiation errorN)ri   re   rg   r   rl   r!   r~   ry   r�   r   Úcoder   r   )r'   rc   ZagentrR   ÚrÚbodyr(   r(   r)   Útest_bad  s   



ÿzWebSocketTests.test_badc                 C  óJ   t  tƒ ¡}t | d¡¡}|jdd�}|  |¡ | ¡  |  	|t
¡ dS )úÁ
        Attempting to connect to a regular HTTP resource that does not support
        websockets will result in the Deferred returned from
        L{WebSocketClientEndpoint} failing.
        zhttp://localhost/emptyFrx   N©ri   re   rg   r
   r}   rt   ry   r~   r‚   ÚfailureResultOfr3   ©r'   rc   rƒ   r„   r(   r(   r)   Útest_connectionRefused0  s   
z%WebSocketTests.test_connectionRefusedc                 C  rž   )rŸ   zhttp://localhost/processingFrx   Nr    r¢   r(   r(   r)   Útest_connectionRefusedWeird=  s   ÿ
z*WebSocketTests.test_connectionRefusedWeirdc                 C  s  t  tƒ ¡}t | d¡¡}|jdd�}|  |¡ |jj	 
d¡ | ¡  |  |t¡}|jj}| tƒ  }¡ |  |jd¡ |jj	}| 
d¡ | ¡  |  |jd¡ | 
d¡ | ¡  |  |jd¡ | ¡  |  |jd¡ | ¡  |jdusyJ d	ƒ‚|  |jjt¡ dS )
z§
        When the client connection is refused by an asynchronous HTTP response,
        the websocket client will not be notified until the response arrives.
        zhttp://localhost/slowTrx   r%   s   hellos   worlds
   helloworldNzshould be closed now)ri   re   rg   r
   r}   rt   ry   r~   rp   r!   Úwriter‚   r¡   r3   ÚvaluerR   ZdeliverBodyr   r   rG   Úfinishr•   ZclosedReasonÚtyper   )r'   rc   rƒ   r„   ZrejectedÚrespÚpÚreqr(   r(   r)   Útest_connectionRefusedSlowL  s,   


z)WebSocketTests.test_connectionRefusedSlowNr_   )r+   r,   r-   r‡   rˆ   r–   r˜   r™   r�   r£   r¤   r¬   r(   r(   r(   r)   r{   ¸   s    



"



r{   N)@r2   Ú
__future__r   Údataclassesr   r   Útypingr   r   r   Zunittestr   Zzope.interfacer	   Ztwisted.internet.deferr
   Ztwisted.internet.errorr   Ztwisted.internet.interfacesr   Ztwisted.internet.testingr   r   Ztwisted.python.failurer   Ztwisted.test.iosimr   r   Ztwisted.trial.unittestr   Ztwisted.web._responsesr   Ztwisted.web.clientr   r   Ztwisted.web.iwebr   Ztwisted.web.resourcer   Ztwisted.web.serverr   r   r   Ztwisted.web.staticr   r   Z
shouldSkipr    r/   Ú
__import__ÚImportErrorZtwisted.web.websocketr3   r4   r5   r   r6   r7   r8   r9   rb   rg   ri   r{   r(   r(   r(   r)   Ú<module>   sJ   ÿ$
1+