o
    Óó·i
J  ã                   @  sP  d Z ddlmZ ddlZzddlmZ W n	 ey   Y nw ddlm	Z	m
Z
 ddlmZ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mZ ddlmZ G dd„ dƒZe
ejƒG dd„ dƒƒZe
ejejej ƒG dd„ dƒƒZ!dd„ Z"dd„ Z#G dd„ dƒZ$			d$dd„Z%e"e#dddfdd„Z&dd„ Z'G d d!„ d!ƒZ(d%d"d#„Z)dS )&z0
Utilities and helpers for simulating a network
é    )ÚannotationsN)ÚError)ÚdirectlyProvidesÚimplementer)ÚerrorÚ
interfaces)ÚTCP4ClientEndpointÚTCP4ServerEndpoint)ÚConnectionRefusedError)ÚFactoryÚProtocol)ÚMemoryReactorÚMemoryReactorClock)ÚFailurec                   @  s&   e Zd Zdd„ Zd
dd„Zdd„ Zd	S )ÚTLSNegotiationc                 C  s   || _ || _d| _|| _d S )NF)ÚobjÚconnectStateÚsentÚreadyToSend)Úselfr   r   © r   úXC:\Users\psant\Downloads\PAF backend\school\venv\Lib\site-packages\twisted/test/iosim.pyÚ__init__   s   
zTLSNegotiation.__init__ÚreturnÚstrc                 C  s   d| j ›d�S )NzTLSNegotiation(ú))r   ©r   r   r   r   Ú__repr__"   s   zTLSNegotiation.__repr__c                 C  s&   | j  |j ¡stƒ |_| ¡  d S d S ©N)r   ZiosimVerifyÚNativeOpenSSLErrorÚdisconnectReasonÚloseConnection)r   ÚotherZtptr   r   r   ÚpretendToVerify%   s   þzTLSNegotiation.pretendToVerifyN©r   r   )Ú__name__Ú
__module__Ú__qualname__r   r   r#   r   r   r   r   r      s    
r   c                   @  s   e Zd ZdZdS )ÚFakeAddressz]
    The default address type for the host and peer of L{FakeTransport}
    connections.
    N)r%   r&   r'   Ú__doc__r   r   r   r   r(   .   s    r(   c                   @  s  e Zd ZdZee ¡ fdd„ƒZdZdZ	dZ
e d¡ZdZdZ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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*„ Z!d>d,d-„Z"d.d/„ Z#d0d1„ Z$d2d3„ Z%d4d5„ Z&d6d7„ Z'd8d9„ Z(d:d;„ Z)dS )?ÚFakeTransportzØ
    A wrapper around a file-like object to make it behave as a Transport.

    This doesn't actually stream the file to the attached protocol,
    and is thus useful mainly as a utility for debugging protocols.
    c                 C  s   t t| ƒƒS r   )ÚintÚnext)Úcounterr   r   r   Ú<lambda>?   s    zFakeTransport.<lambda>r   zConnection doneNc                 C  sH   || _ || _g | _|  ¡ | _|du rtƒ }|| _|du rtƒ }|| _dS )aÔ  
        @param protocol: This transport will deliver bytes to this protocol.
        @type protocol: L{IProtocol} provider

        @param isServer: C{True} if this is the accepting side of the
            connection, C{False} if it is the connecting side.
        @type isServer: L{bool}

        @param hostAddress: The value to return from C{getHost}.  L{None}
            results in a new L{FakeAddress} being created to use as the value.
        @type hostAddress: L{IAddress} provider or L{None}

        @param peerAddress: The value to return from C{getPeer}.  L{None}
            results in a new L{FakeAddress} being created to use as the value.
        @type peerAddress: L{IAddress} provider or L{None}
        N)ÚprotocolÚisServerÚstreamÚ_nextserialÚserialr(   ÚhostAddressÚpeerAddress)r   r/   r0   r4   r5   r   r   r   r   H   s   

zFakeTransport.__init__r   r   c                 C  s    d  | jrdpd| j| jjj¡S )NzFakeTransport<{},{},{}>ÚSÚC)Úformatr0   r3   r/   Ú	__class__r%   r   r   r   r   r   d   s
   ýzFakeTransport.__repr__c                 C  s4   | j rd S | jd ur| j |¡ d S | j |¡ d S r   )ÚdisconnectingÚtlsÚtlsbufÚappendr1   )r   Údatar   r   r   Úwritek   s
   
zFakeTransport.writec                 C  s"   | j r| js| j  ¡  d S d S d S r   ©ÚproducerÚstreamingProducerÚresumeProducingr   r   r   r   Ú_checkProduceru   s   ÿzFakeTransport._checkProducerc                 C  s    || _ || _|s| ¡  dS dS )z.
        From abstract.FileDescriptor
        Nr@   )r   rA   Z	streamingr   r   r   ÚregisterProducer{   s
   ÿzFakeTransport.registerProducerc                 C  s
   d | _ d S r   )rA   r   r   r   r   ÚunregisterProducer„   ó   
z FakeTransport.unregisterProducerc                 C  s   |   ¡  |  ¡  d S r   )rF   r!   r   r   r   r   ÚstopConsuming‡   s   zFakeTransport.stopConsumingc                 C  s   |   d |¡¡ d S )Nó    )r?   Újoin)r   Ziovecr   r   r   ÚwriteSequence‹   s   zFakeTransport.writeSequencec                 C  s
   d| _ d S ©NT©r:   r   r   r   r   r!   Ž   rG   zFakeTransport.loseConnectionc                 C  s
   d| _ dS )zp
        For the time being, this is the same as loseConnection; no buffered
        data will be lost.
        TNrM   r   r   r   r   ÚabortConnection‘   s   
zFakeTransport.abortConnectionc                 C  s,   | j d ur	tƒ }n| j}| j t|ƒ¡ d S r   )r;   r   r    r/   ZconnectionLostr   )r   Úerrr   r   r   ÚreportDisconnect˜   s   
zFakeTransport.reportDisconnectc                 C  s   dS )zM
        Identify this transport/event source to the logging system.
        ZiosimNr   r   r   r   r   Ú	logPrefix¡   s   zFakeTransport.logPrefixc                 C  ó   | j S r   )r5   r   r   r   r   ÚgetPeer§   ó   zFakeTransport.getPeerc                 C  rR   r   )r4   r   r   r   r   ÚgetHostª   rT   zFakeTransport.getHostc                 C  ó   d S r   r   r   r   r   r   rC   ­   ó   zFakeTransport.resumeProducingc                 C  rV   r   r   r   r   r   r   ÚpauseProducing±   rW   zFakeTransport.pauseProducingc                 C  s   |   ¡  d S r   )r!   r   r   r   r   ÚstopProducingµ   s   zFakeTransport.stopProducingTc                 C  s    | j |A }t||ƒ| _g | _d S r   )r0   r   r;   r<   )r   ZcontextFactoryZbeNormalr   r   r   r   ÚstartTLS¸   s   

zFakeTransport.startTLSc                 C  sB   | j }|rg | _ d |¡S | jdur| jjrd| j_| jS dS dS )zÁ
        Get the pending writes from this transport, clearing them from the
        pending buffer.

        @return: the bytes written with C{transport.write}
        @rtype: L{bytes}
        rI   NT)r1   rJ   r;   r   r   )r   r6   r   r   r   ÚgetOutBufferÀ   s   

zFakeTransport.getOutBufferc                 C  sx   t |tƒr4| jd usJ ‚| jjr.| j || ¡ d | _| jd }| _|  |¡ t| tj	ƒ d S d| j_
d S | j |¡ d S rL   )Ú
isinstancer   r;   r   r#   r<   rK   r   r   ZISSLTransportr   r/   ZdataReceived)r   ÚbufÚbr   r   r   ÚbufferReceivedÖ   s   

zFakeTransport.bufferReceivedc                 C  rV   r   r   r   r   r   r   ÚgetTcpKeepAliveé   rW   zFakeTransport.getTcpKeepAlivec                 C  rV   r   r   r   r   r   r   ÚgetTcpNoDelayí   rW   zFakeTransport.getTcpNoDelayc                 C  rV   r   r   r   r   r   r   ÚloseWriteConnectionñ   rW   z!FakeTransport.loseWriteConnectionc                 C  rV   r   r   ©r   Úenabledr   r   r   ÚsetTcpKeepAliveõ   rW   zFakeTransport.setTcpKeepAlivec                 C  rV   r   r   rc   r   r   r   ÚsetTcpNoDelayù   rW   zFakeTransport.setTcpNoDelay)NNr$   )T)*r%   r&   r'   r)   ÚstaticmethodÚ	itertoolsÚcountr2   Úclosedr:   Údisconnectedr   ZConnectionDoner    rA   rB   r;   r   r   r?   rD   rE   rF   rH   rK   r!   rN   rP   rQ   rS   rU   rC   rX   rY   rZ   r[   r_   r`   ra   rb   re   rf   r   r   r   r   r*   6   sF    



		
r*   c                 C  ó   t | dd�S )zø
    Create and return a new in-memory transport hooked up to the given protocol.

    @param clientProtocol: The client protocol to use.
    @type clientProtocol: L{IProtocol} provider

    @return: The transport.
    @rtype: L{FakeTransport}
    F©r0   N©r*   )ÚclientProtocolr   r   r   ÚmakeFakeClientþ   ó   
rp   c                 C  rl   )zø
    Create and return a new in-memory transport hooked up to the given protocol.

    @param serverProtocol: The server protocol to use.
    @type serverProtocol: L{IProtocol} provider

    @return: The transport.
    @rtype: L{FakeTransport}
    Trm   Nrn   )ÚserverProtocolr   r   r   ÚmakeFakeServer  rq   rs   c                   @  s.   e Zd ZdZddd„Zddd„Zdd	d
„ZdS )ÚIOPumpz�
    Utility to pump data between clients and servers for protocol testing.

    Perhaps this is a utility worthy of being in protocol.py?
    Nc                 C  s6   || _ || _|| _|| _|| _|d u rtƒ }|| _d S r   )ÚclientÚserverÚclientIOÚserverIOÚdebugr   Úclock)r   ru   rv   rw   rx   ry   rz   r   r   r   r     s   
zIOPump.__init__FTc                 C  s0   d}t dƒD ]}|  ||¡rd}q |S J dƒ‚)zk
        Pump until there is no more input or output.

        Returns whether any data was moved.
        Fiè  Tr   zToo longN)ÚrangeÚpump)r   ry   ÚadvanceClockÚresultÚ_r   r   r   Úflush)  s   ÿzIOPump.flushc                 C  s4  |r| j  d¡ | js|rtdƒ | j ¡ }| j ¡ }| j ¡  | j ¡  | js*|rBtdƒ |r8tdt|ƒ ƒ |rBtdt|ƒ ƒ |rJ| j 	|¡ |rR| j 	|¡ |sV|rXdS | jj
rx| jjsx| jse|ritdƒ d| j_d| j_
| j ¡  dS | jj
r˜| jjs˜| js…|r‰tdƒ d| j_d| j_
| j ¡  dS d	S )z·
        Move data back and forth, while also triggering any currently pending
        scheduled calls (i.e. C{callLater(0, f)}).

        Returns whether any data was moved.
        r   z
-- GLUG --Ú.zC: zS: Tz* Cz* SFN)rz   Zadvancery   Úprintrx   r[   rw   rD   Úreprr_   r:   rk   rP   )r   ry   r}   ZsDataZcDatar   r   r   r|   9  sF   









zIOPump.pumpr   ©FT)r%   r&   r'   r)   r   r€   r|   r   r   r   r   rt     s
    


rt   FTc                 C  s8   |   |¡ |  |¡ t|| ||||d�}|r| ¡  |S )aÓ  
    Create a new L{IOPump} connecting two protocols.

    @param serverProtocol: The protocol to use on the accepting side of the
        connection.
    @type serverProtocol: L{IProtocol} provider

    @param serverTransport: The transport to associate with C{serverProtocol}.
    @type serverTransport: L{FakeTransport}

    @param clientProtocol: The protocol to use on the initiating side of the
        connection.
    @type clientProtocol: L{IProtocol} provider

    @param clientTransport: The transport to associate with C{clientProtocol}.
    @type clientTransport: L{FakeTransport}

    @param debug: A flag indicating whether to log information about what the
        L{IOPump} is doing.
    @type debug: L{bool}

    @param greet: Should the L{IOPump} be L{flushed <IOPump.flush>} once before
        returning to put the protocols into their post-handshake or
        post-server-greeting state?
    @type greet: L{bool}

    @param clock: An optional L{Clock}. Pumping the resulting L{IOPump} will
        also increase clock time by a small increment.

    @return: An L{IOPump} which connects C{serverProtocol} and
        C{clientProtocol} and delivers bytes between them when it is pumped.
    @rtype: L{IOPump}
    ©rz   N)ZmakeConnectionrt   r€   )rr   ÚserverTransportro   ÚclientTransportry   Úgreetrz   r|   r   r   r   Úconnectf  s   
*
úr‰   c                 C  s8   |ƒ }| ƒ }||ƒ}	||ƒ}
||t ||
||	|||d�fS )a‰  
    Connect a given server and client class to each other.

    @param ServerClass: a callable that produces the server-side protocol.
    @type ServerClass: 0-argument callable returning L{IProtocol} provider.

    @param ClientClass: like C{ServerClass} but for the other side of the
        connection.
    @type ClientClass: 0-argument callable returning L{IProtocol} provider.

    @param clientTransportFactory: a callable that produces the transport which
        will be attached to the protocol returned from C{ClientClass}.
    @type clientTransportFactory: callable taking (L{IProtocol}) and returning
        L{FakeTransport}

    @param serverTransportFactory: a callable that produces the transport which
        will be attached to the protocol returned from C{ServerClass}.
    @type serverTransportFactory: callable taking (L{IProtocol}) and returning
        L{FakeTransport}

    @param debug: Should this dump an escaped version of all traffic on this
        connection to stdout for inspection?
    @type debug: L{bool}

    @param greet: Should the L{IOPump} be L{flushed <IOPump.flush>} once before
        returning to put the protocols into their post-handshake or
        post-server-greeting state?
    @type greet: L{bool}

    @param clock: An optional L{Clock}. Pumping the resulting L{IOPump} will
        also increase clock time by a small increment.

    @return: the client protocol, the server protocol, and an L{IOPump} which,
        when its C{pump} and C{flush} methods are called, will move data
        between the created client and server protocol instances.
    @rtype: 3-L{tuple} of L{IProtocol}, L{IProtocol}, L{IOPump}
    r…   N)r‰   )ZServerClassZClientClassZclientTransportFactoryZserverTransportFactoryry   rˆ   rz   ÚcÚsZcioÚsior   r   r   ÚconnectedServerAndClient   s
   .r�   c                 C  s.   | \}}}}}|\}}}	}
||kr||fS dS )a'  
    Should the client and server described by the arguments be connected to
    each other, i.e. do their port numbers match?

    @param clientInfo: the args for connectTCP
    @type clientInfo: L{tuple}

    @param serverInfo: the args for listenTCP
    @type serverInfo: L{tuple}

    @return: If they do match, return factories for the client and server that
        should connect; otherwise return L{None}, indicating they shouldn't be
        connected.
    @rtype: L{None} or 2-L{tuple} of (L{ClientFactory},
        L{IProtocolFactory})
    Nr   )Ú
clientInfoÚ
serverInfoZ
clientHostZ
clientPortÚclientFactoryZclientTimeoutZclientBindAddressZ
serverPortÚserverFactoryZserverBacklogZserverInterfacer   r   r   Ú_factoriesShouldConnectÕ  s   úr’   c                   @  s:   e Zd ZdZddd„Zdddd„Zeeƒ ƒfddd„ZdS )ÚConnectionCompleterz¬
    A L{ConnectionCompleter} can cause synthetic TCP connections established by
    L{MemoryReactor.connectTCP} and L{MemoryReactor.listenTCP} to succeed or
    fail.
    ÚmemoryReactorr   r   ÚNonec                 C  s
   || _ dS )zƒ
        Create a L{ConnectionCompleter} from a L{MemoryReactor}.

        @param memoryReactor: The reactor to attach to.
        N)Ú_reactor)r   r”   r   r   r   r   û  s   
zConnectionCompleter.__init__FTry   Úboolrˆ   úIOPump | Nonec              
   C  sœ   | j }t|jƒD ]C\}}|jD ];}t||ƒ}|rJ|j |¡ |j |¡ |\}}	| d¡}
|	 d¡}t	|ƒ}t
|
ƒ}t|||
|||d�}|    S qqdS )aQ  
        Complete a single TCP connection established on this
        L{ConnectionCompleter}'s L{MemoryReactor}.

        @param debug: A flag; whether to dump output from the established
            connection to stdout.

        @return: a pump for the connection, or L{None} if no connection could
            be established.
        N)rˆ   )r–   Ú	enumerateÚ
tcpClientsZ
tcpServersr’   ÚremoveÚ
connectorsÚpopZbuildProtocolrs   rp   r‰   )r   ry   rˆ   r”   Z	clientIdxrŽ   r�   Z	factoriesr�   r‘   ro   rr   r†   r‡   r~   r   r   r   ÚsucceedOnce  s0   



úðþzConnectionCompleter.succeedOnceÚreasonr   c                 C  s(   | j j d¡d  | j j d¡|¡ dS )z¿
        Fail a single TCP connection established on this
        L{ConnectionCompleter}'s L{MemoryReactor}.

        @param reason: the reason to provide that the connection failed.
        r   é   N)r–   rš   r�   ZclientConnectionFailedrœ   )r   rŸ   r   r   r   ÚfailOnce%  s   ÿzConnectionCompleter.failOnceN)r”   r   r   r•   r„   )ry   r—   rˆ   r—   r   r˜   )rŸ   r   r   r•   )	r%   r&   r'   r)   r   rž   r   r
   r¡   r   r   r   r   r“   ô  s
    
"r“   c                 C  s8   t ƒ }t|ddƒ}t|dƒ}| t t¡¡ |t|ƒfS )a…  
    Create an endpoint that can be fired on demand.

    @param debug: A flag; whether to dump output from the established
        connection to stdout.
    @type debug: L{bool}

    @return: A client endpoint, and an object that will cause one of the
        L{Deferred}s returned by that client endpoint.
    @rtype: 2-L{tuple} of (L{IStreamClientEndpoint}, L{ConnectionCompleter})
    z0.0.0.0iá  N)r   r   r	   Úlistenr   ZforProtocolr   r“   )ry   ZreactorZclientEndpointZserverEndpointr   r   r   ÚconnectableEndpoint1  s
   
r£   )FTN)F)*r)   Ú
__future__r   rh   ZOpenSSL.SSLr   r   ÚImportErrorZzope.interfacer   r   Ztwisted.internetr   r   Ztwisted.internet.endpointsr   r	   Ztwisted.internet.errorr
   Ztwisted.internet.protocolr   r   Ztwisted.internet.testingr   r   Ztwisted.python.failurer   r   ZIAddressr(   Z
ITransportZITLSTransportZ	IConsumerr*   rp   rs   rt   r‰   r�   r’   r“   r£   r   r   r   r   Ú<module>   sJ   ÿ HS
ù=
ù5=