o
    9Bi
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   R/var/www/html/Trade-python/venv/lib/python3.10/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   iosimVerifyNativeOpenSSLErrordisconnectReasonloseConnection)r   other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   r1   r2   r6   r7   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)formatr2   r5   r1   	__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appendr3   )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
        NrB   )r   rC   	streamingr   r   r   registerProducer{   s
   zFakeTransport.registerProducerc                 C  s
   d | _ d S r   )rC   r   r   r   r   unregisterProducer      
z FakeTransport.unregisterProducerc                 C  s   |    |   d S r   )rI   r"   r   r   r   r   stopConsuming   s   zFakeTransport.stopConsumingc                 C  s   |  d| d S )N    )rA   join)r   iovecr   r   r   writeSequence   s   zFakeTransport.writeSequencec                 C  s
   d| _ d S NTr<   r   r   r   r   r"      rJ   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.
        TNrQ   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!   r1   connectionLostr   )r   errr   r   r   reportDisconnect   s   
zFakeTransport.reportDisconnectc                 C  s   dS )zM
        Identify this transport/event source to the logging system.
        iosimr   r   r   r   r   	logPrefix   s   zFakeTransport.logPrefixc                 C     | j S r   )r7   r   r   r   r   getPeer      zFakeTransport.getPeerc                 C  rX   r   )r6   r   r   r   r   getHost   rZ   zFakeTransport.getHostc                 C     d S r   r   r   r   r   r   rE         zFakeTransport.resumeProducingc                 C  r\   r   r   r   r   r   r   pauseProducing   r]   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   )r2   r   r=   r>   )r   contextFactory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}
        rL   NT)r3   rM   r=   r   r   )r   r8   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 rP   )
isinstancer   r=   r   r%   r>   rO   r   r   ISSLTransportr   r1   dataReceived)r   bufbr   r   r   bufferReceived   s   

zFakeTransport.bufferReceivedc                 C  r\   r   r   r   r   r   r   getTcpKeepAlive   r]   zFakeTransport.getTcpKeepAlivec                 C  r\   r   r   r   r   r   r   getTcpNoDelay   r]   zFakeTransport.getTcpNoDelayc                 C  r\   r   r   r   r   r   r   loseWriteConnection   r]   z!FakeTransport.loseWriteConnectionc                 C  r\   r   r   r   enabledr   r   r   setTcpKeepAlive   r]   zFakeTransport.setTcpKeepAlivec                 C  r\   r   r   rm   r   r   r   setTcpNoDelay   r]   zFakeTransport.setTcpNoDelay)NNr&   )T)*r'   r(   r)   r+   staticmethod	itertoolscountr4   closedr<   disconnectedr   ConnectionDoner!   rC   rD   r=   r   r   rA   rF   rH   rI   rK   rO   r"   rR   rU   rW   rY   r[   rE   r^   r_   rb   rc   ri   rj   rk   rl   ro   rp   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r2   r,   )clientProtocolr   r   r   makeFakeClient      
r{   c                 C  rw   )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}
    Trx   ry   )serverProtocolr   r   r   makeFakeServer  r|   r~   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   r   r   r   r   r   r   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 long)rangepump)r   r   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|rt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* SF)r   advancer   printr   rc   r   rF   reprri   r<   ru   rU   )r   r   r   sDatacDatar   r   r   r   9  sF   









zIOPump.pumpr   FT)r'   r(   r)   r+   r   r   r   r   r   r   r   r     s
    


r   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}
    r   )makeConnectionr   r   )r}   serverTransportrz   clientTransportr   greetr   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   )r   )ServerClassClientClassclientTransportFactoryserverTransportFactoryr   r   r   cs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
serverInfo
clientHost
clientPortclientFactoryclientTimeoutclientBindAddress
serverPortserverFactoryserverBacklog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__FTr   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
tcpClients
tcpServersr   remove
connectorspopbuildProtocolr~   r{   r   )r   r   r   r   	clientIdxr   r   	factoriesr   r   rz   r}   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   clientConnectionFailedr   )r   r   r   r   r   failOnce%  s   zConnectionCompleter.failOnceN)r   r   r   r   r   )r   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  )r   r   r	   listenr   forProtocolr   r   )r   reactorclientEndpointserverEndpointr   r   r   connectableEndpoint1  s
   
r   )FTN)F)*r+   
__future__r   rr   OpenSSL.SSLr   r    ImportErrorzope.interfacer   r   twisted.internetr   r   twisted.internet.endpointsr   r	   twisted.internet.errorr
   twisted.internet.protocolr   r   twisted.internet.testingr   r   twisted.python.failurer   r   IAddressr*   
ITransportITLSTransport	IConsumerr,   r{   r~   r   r   r   r   r   r   r   r   r   r   <module>   sJ    HS
=
5=