o
    9»Bi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   ó    )ÚsetResponseCode©Úselfr!   © r)   ú_/var/www/html/Trade-python/venv/lib/python3.10/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"   r1   )r,   r-   r.   Ú__doc__r+   r)   r)   r)   r*   r0   2   s    r0   Ú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Ú	transportr:   r"   ÚNonec                 C  ó
   || _ d S r2   )r@   )r(   r@   r)   r)   r*   ÚnegotiationStartedW   ó   
zMyWSP.negotiationStartedc                 C  s   d S r2   r)   ©r(   r)   r)   r*   ÚnegotiationFinishedZ   s   zMyWSP.negotiationFinishedÚreasonr   c                 C  rB   r2   )r?   )r(   rG   r)   r)   r*   ÚconnectionLost]   rD   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(   rI   r)   r)   r*   ÚbytesMessageReceived`   ó   zMyWSP.bytesMessageReceivedÚstrc                 C  rJ   )Nr!   Úresponse)r@   ÚsendTextMessageÚdeferredrO   rP   r)   r)   r*   ÚtextMessageReceivedf   rR   zMyWSP.textMessageReceivedÚpayloadc                 C  s   | j  |¡ d S r2   )r>   Úappend)r(   rX   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!   )r
   rV   r@   rU   rE   r)   r)   r*   ÚsendRequesto   ó   zMyWSP.sendRequestúDeferred[bytes]c                 C  r\   )zS
            Send a bytes message to the server and expect a response.
            rK   )r
   rN   r@   rM   rE   r)   r)   r*   ÚbytesRequestw   r^   zMyWSP.bytesRequest)r@   r:   r"   rA   ©r"   rA   )rG   r   r"   rA   )rI   r#   r"   rA   )rI   rS   r"   rA   )rX   r#   r"   rA   )r"   r[   )r"   r_   )r,   r-   r.   r3   r   Úlistr>   Ú__annotations__r?   rC   rF   rH   rQ   rW   rZ   r]   r`   r)   r)   r)   r*   r;   M   s   
 






r;   c                   @  s    e Zd ZU ded< d
dd„Zd	S )Ú	MyFactoryzWebSocketFixture[Any]Úfixturer!   r   r"   r;   c                 C  s   t ƒ }| jj |¡ |S r2   )r;   re   ÚserversrY   )r(   r!   Únewr)   r)   r*   ÚbuildProtocol‚   s   zMyFactory.buildProtocolN)r!   r   r"   r;   )r,   r-   r.   rc   rh   r)   r)   r)   r*   rd      s   
 rd   c                   @  r   )	ÚMyClientFactoryÚurirS   r"   r;   c                 C  s   t ƒ S r2   )r;   )r(   rj   r)   r)   r*   rh   ˆ   s   zMyClientFactory.buildProtocolN)rj   rS   r"   r;   )r,   r-   r.   rh   r)   r)   r)   r*   ri   ‡   r/   ri   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   r1   Ú
portNumberz	list[WSP]rf   r0   Ú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)rn   )rd   re   ro   ÚputChildr8   r   r    rr   rn   Ú	listenTCPrq   r   )Úclsrm   r(   ÚserverFactoryr)   r)   r*   rg   •   s   
ÿÿzWebSocketFixture.newúhttp://localhost:80/connectrj   rS   r   c                 Ã  s"   t  | j|¡}| | j¡I d H S r2   )r6   rg   rn   Úconnectrm   )r(   rj   Úclientr)   r)   r*   ry   ¥   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.
        ©r{   NzConnection not in progress.)r   rn   ÚsucceedOnce)r(   r{   Ú	completerÚ	succeededr)   r)   r*   Úcomplete©   s   
	zWebSocketFixture.completeN)rm   rl   r"   rs   )rx   )rj   rS   r"   r   )T)r{   r|   r"   r   )r,   r-   r.   r   rm   rc   r   rn   r   ro   rq   rb   rf   r0   rr   Úclassmethodrg   ry   r   r)   r)   r)   r*   rk   Œ   s   
 rk   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"   rA   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.
        é   rT   N)rk   rg   ri   r
   ÚfromCoroutinery   ÚassertNoResultÚassertEqualÚlenrn   Ú
tcpServersÚ
tcpClientsr   ÚsuccessResultOfr]   Úflush)r(   re   Ú	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.
        rL   N)rk   rg   ri   r
   r…   ry   r   r‹   r`   r†   rŒ   r‡   )r(   re   r   rŽ   r   Ú
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"   rA   c                   ó   ˆ   d¡ d S )NÚpaused©rY   rE   ©Úeventsr)   r*   ÚpauseProducingæ   ó   zEWebSocketTests.test_backpressure.<locals>.TestProducer.pauseProducingc                   r”   )NÚresumedr–   rE   r—   r)   r*   ÚresumeProducingé   rš   zFWebSocketTests.test_backpressure.<locals>.TestProducer.resumeProducingc                   r”   )NÚstoppedr–   rE   r—   r)   r*   ÚstopProducingì   rš   zDWebSocketTests.test_backpressure.<locals>.TestProducer.stopProducingNra   )r,   r-   r.   r™   rœ   rž   r)   r—   r)   r*   ÚTestProducerä   s    rŸ   r   r•   r›   )r•   r›   r   N)rk   rg   ri   r
   r…   ry   r   r	   r   rf   r@   ÚattachProducerr‡   ÚserverIOÚproducerr™   rœ   rž   ÚassertIsÚdetachProducer)r(   re   rŽ   rŸ   Ú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)rk   rg   ri   r
   r…   ry   r   r‹   r@   Úpingr‡   r>   rŒ   ©r(   re   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)rk   rg   ri   r
   r…   ry   r   r‹   r£   rf   r?   r@   ÚloseConnectionrŒ   Ú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)rk   rg   ri   r   rn   r!   r†   r   r‹   r‡   Úcoder   r   )r(   re   ÚagentrT   Ú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/emptyFr}   N©rk   rg   ri   r
   r…   ry   r   r†   rŒ   ÚfailureResultOfr5   ©r(   re   r   rŽ   r)   r)   r*   Útest_connectionRefused0  s   
z%WebSocketTests.test_connectionRefusedc                 C  r²   )r³   zhttp://localhost/processingFr}   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/slowTr}   r%   s   hellos   worlds
   helloworldNzshould be closed now)rk   rg   ri   r
   r…   ry   r   r†   rr   r!   ÚwriterŒ   rµ   r5   ÚvaluerT   ÚdeliverBodyr   r‡   rI   Úfinishr£   ÚclosedReasonÚtyper   )r(   re   r   rŽ   ÚrejectedÚrespÚpÚreqr)   r)   r*   Útest_connectionRefusedSlowL  s,   


z)WebSocketTests.test_connectionRefusedSlowNra   )r,   r-   r.   r‘   r“   r¦   r©   r¬   r±   r·   r¸   rÃ   r)   r)   r)   r*   rƒ   ¸   s    



"



rƒ   N)@r3   Ú
__future__r   Údataclassesr   r   Útypingr   r   r   Úunittestr   Úzope.interfacer	   Útwisted.internet.deferr
   Útwisted.internet.errorr   Útwisted.internet.interfacesr   Útwisted.internet.testingr   r   Útwisted.python.failurer   Útwisted.test.iosimr   r   Útwisted.trial.unittestr   Útwisted.web._responsesr   Útwisted.web.clientr   r   Útwisted.web.iwebr   Útwisted.web.resourcer   Útwisted.web.serverr   r   r   Útwisted.web.staticr   r   Ú
shouldSkipr    r0   Ú
__import__ÚImportErrorÚtwisted.web.websocketr5   r6   r7   r   r8   r9   r:   r;   rd   ri   rk   rƒ   r)   r)   r)   r*   Ú<module>   sJ   ÿ$
1+