
    \dF                        d Z ddlZ	 ddlmZ n# e$ r Y nw xY 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 dd
lmZ  G d d          Z eej                   G d d                      Z eej        ej                   G d d                      Zd Zd Z G d d          Z 	 	 ddZ!eeddfdZ"d Z# G d d          Z$ddZ%dS )z0
Utilities and helpers for simulating a network
    N)Error)directlyProvidesimplementer)error
interfaces)TCP4ClientEndpointTCP4ServerEndpoint)ConnectionRefusedError)FactoryProtocol)MemoryReactorClock)Failurec                   &    e Zd Zd ZdefdZd ZdS )TLSNegotiationc                 >    || _         || _        d| _        || _        d S )NF)objconnectStatesentreadyToSend)selfr   r   s      2lib/python3.11/site-packages/twisted/test/iosim.py__init__zTLSNegotiation.__init__   s&    (	'    returnc                     d| j         dS )NzTLSNegotiation())r   r   s    r   __repr__zTLSNegotiation.__repr__"   s    .....r   c                     | j                             |j                   s)t                      |_        |                                 d S d S N)r   iosimVerifyNativeOpenSSLErrordisconnectReasonloseConnection)r   othertpts      r   pretendToVerifyzTLSNegotiation.pretendToVerify%   sN     x##EI.. 	!#5#7#7C      	! 	!r   N)__name__
__module____qualname__r   strr   r'    r   r   r   r      sM        ( ( (/# / / / /! ! ! ! !r   r   c                       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   r.   c                       e Zd ZdZ e ej                    fd          ZdZdZ	dZ
 ej        d          ZdZdZdZd!dZdefdZd	 Zd
 Zd Zd Zd Zd Zd Zd Zd Zd Zd Zd Zd Z d Z!d Z"d"dZ#d Z$d Z%d Z&d Z'd Z(d Z)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                 :    t          t          |                     S r    )intnext)counters    r   <lambda>zFakeTransport.<lambda>?   s    T']]ASAS r   r   zConnection doneNc                     || _         || _        g | _        |                                 | _        |t                      }|| _        |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   r8   r9   r=   r>   s        r   r   zFakeTransport.__init__H   s`    " ! &&((%--K&%--K&r   r   c                 j    d                     | j        rdpd| j        | j        j        j                  S )NzFakeTransport<{},{},{}>SC)formatr9   r<   r8   	__class__r(   r   s    r   r   zFakeTransport.__repr__d   s9    (//M!c(SKM#,
 
 	
r   c                     | j         rd S | j        | j                            |           d S | j                            |           d S r    )disconnectingtlstlsbufappendr:   )r   datas     r   writezFakeTransport.writek   sR     	F8Kt$$$$$Kt$$$$$r   c                 \    | j         r"| j        s| j                                          d S d S d S r    producerstreamingProducerresumeProducingr   s    r   _checkProducerzFakeTransport._checkProduceru   sF     = 	,!7 	,M))+++++	, 	, 	, 	,r   c                 R    || _         || _        |s|                                 dS dS )z.
        From abstract.FileDescriptor
        NrL   )r   rM   	streamings      r   registerProducerzFakeTransport.registerProducer{   s=     !!* 	'$$&&&&&	' 	'r   c                     d | _         d S r    )rM   r   s    r   unregisterProducerz FakeTransport.unregisterProducer   s    r   c                 V    |                                   |                                  d S r    )rU   r$   r   s    r   stopConsumingzFakeTransport.stopConsuming   s,    !!!r   c                 V    |                      d                    |                     d S )Nr   )rJ   join)r   iovecs     r   writeSequencezFakeTransport.writeSequence   s$    

388E??#####r   c                     d| _         d S NTrE   r   s    r   r$   zFakeTransport.loseConnection   s    !r   c                     d| _         dS )zp
        For the time being, this is the same as loseConnection; no buffered
        data will be lost.
        TNr^   r   s    r   abortConnectionzFakeTransport.abortConnection   s    
 "r   c                     | j         t                      }n| j        }| j                            t          |                     d S r    )rF   r"   r#   r8   connectionLostr   )r   errs     r   reportDisconnectzFakeTransport.reportDisconnect   sC    8 %&&CC'C$$WS\\22222r   c                     dS )zM
        Identify this transport/event source to the logging system.
        iosimr,   r   s    r   	logPrefixzFakeTransport.logPrefix   s	     wr   c                     | j         S r    )r>   r   s    r   getPeerzFakeTransport.getPeer       r   c                     | j         S r    )r=   r   s    r   getHostzFakeTransport.getHost   rj   r   c                     d S r    r,   r   s    r   rO   zFakeTransport.resumeProducing       r   c                     d S r    r,   r   s    r   pauseProducingzFakeTransport.pauseProducing   rn   r   c                 .    |                                   d S r    )r$   r   s    r   stopProducingzFakeTransport.stopProducing   s    r   Tc                 R    | j         |z  }t          ||          | _        g | _        d S r    )r9   r   rF   rG   )r   contextFactorybeNormalr   s       r   startTLSzFakeTransport.startTLS   s,     }x/!.,??r   c                     | j         }|rg | _         d                    |          S | j        !| 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}
        r   NT)r:   rY   rF   r   r   )r   r@   s     r   getOutBufferzFakeTransport.getOutBuffer   sY     K 	DK88A;;X!x#  $xt4r   c                 n   t          |t                    r| j        J | j        j        rb| j                            ||            d | _        | j        d c}| _        |                     |           t          | t          j	                   d S d| j        _
        d S | j                            |           d S r]   )
isinstancer   rF   r   r'   rG   r[   r   r   ISSLTransportr   r8   dataReceived)r   bufbs      r   bufferReceivedzFakeTransport.bufferReceived   s    c>** 	,8''' x} 
,((d333 "&d4;""1%%% z'?@@@@@ (,$$$M&&s+++++r   c                     d S r    r,   r   s    r   getTcpKeepAlivezFakeTransport.getTcpKeepAlive   rn   r   c                     d S r    r,   r   s    r   getTcpNoDelayzFakeTransport.getTcpNoDelay   rn   r   c                     d S r    r,   r   s    r   loseWriteConnectionz!FakeTransport.loseWriteConnection   rn   r   c                     d S r    r,   r   enableds     r   setTcpKeepAlivezFakeTransport.setTcpKeepAlive   rn   r   c                     d S r    r,   r   s     r   setTcpNoDelayzFakeTransport.setTcpNoDelay   rn   r   )NN)T)+r(   r)   r*   r/   staticmethod	itertoolscountr;   closedrE   disconnectedr   ConnectionDoner#   rM   rN   rF   r   r+   r   rJ   rP   rS   rU   rW   r[   r$   r`   rd   rg   ri   rl   rO   rp   rr   rv   rx   r   r   r   r   r   r   r,   r   r   r1   r1   6   s         ,oio.?.?SSSTTKFML+u+,=>>H
C' ' ' '8
# 
 
 
 
% % %, , ,' ' '    $ $ $" " "" " "3 3 3                       ,, , ,&            r   r1   c                 $    t          | 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r9   r1   )clientProtocols    r   makeFakeClientr      s     %8888r   c                 $    t          | d          S )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}
    Tr   r   )serverProtocols    r   makeFakeServerr     s     $7777r   c                   (    e Zd ZdZd ZddZ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?
    c                 L    || _         || _        || _        || _        || _        d S r    )clientserverclientIOserverIOdebug)r   r   r   r   r   r   s         r   r   zIOPump.__init__  s)      


r   Fc                 t    d}t          d          D ]}|                     |          rd} n
J d            |S )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   resultxs       r   flushzIOPump.flush&  sQ     t 	! 	!Ayy  j   r   c                    | j         s|rt          d           | j                                        }| j                                        }| j                                         | j                                         | j         s|rQt          d           |rt          dt          |          z              |rt          dt          |          z              |r| j                            |           |r| j                            |           |s|rdS | j        j        rW| j        j	        sK| j         s|rt          d           d| j        _	        d| j        _        | j        
                                 dS | j        j        rW| j        j	        sK| j         s|rt          d           d| j        _	        d| j        _        | j        
                                 dS dS )	zX
        Move data back and forth.

        Returns whether any data was moved.
        z
-- GLUG --.zC: zS: Tz* Cz* SF)r   printr   rx   r   rP   reprr   rE   r   rd   )r   r   sDatacDatas       r   r   zIOPump.pump6  s    : 	  	 ,**,,**,,$$&&&$$&&&: 	+ 	+#JJJ +ed5kk)*** +ed5kk)*** 	0M((/// 	0M((/// 	E 	4=& 	t}/I 	z U e)-DM&*.DM'M**,,,4=& 	t}/I 	z U e)-DM&*.DM'M**,,,4ur   NF)r(   r)   r*   r/   r   r   r   r,   r   r   r   r     sU               ' ' ' ' ' 'r   r   FTc                     |                      |           |                     |           t          || |||          }|r|                                 |S )aN  
    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}

    @return: An L{IOPump} which connects C{serverProtocol} and
        C{clientProtocol} and delivers bytes between them when it is pumped.
    @rtype: L{IOPump}
    )makeConnectionr   r   )r   serverTransportr   clientTransportr   greetr   s          r   connectr   `  sc    L !!/222!!/222% D  

Kr   c           
           |            } |             } ||          } ||          }	||t          ||	||||          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}

    @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   )
ServerClassClientClassclientTransportFactoryserverTransportFactoryr   r   csciosios
             r   connectedServerAndClientr     sZ    T 	AA
 
 
#
#C
 
 
#
#CaCC6666r   c                 8    | \  }}}}}|\  }}}	}
||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serverInterfaces              r   _factoriesShouldConnectr     sD    . 	BL?ZZm++tr   c                   L    e Zd ZdZd ZddZ e e                      f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.
    c                     || _         dS )z
        Create a L{ConnectionCompleter} from a L{MemoryReactor}.

        @param memoryReactor: The reactor to attach to.
        @type memoryReactor: L{MemoryReactor}
        N)_reactor)r   memoryReactors     r   r   zConnectionCompleter.__init__  s     &r   Fc           	         | j         }t          |j                  D ]\  }}|j        D ]}t	          ||          }|r|j                            |           |j                            |           |\  }}|                    d          }	|                    d          }
t          |
          }t          |	          }t          |
||	||          c c S dS )a  
        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.
        @type debug: L{bool}

        @return: a pump for the connection, or L{None} if no connection could
            be established.
        @rtype: L{IOPump} or L{None}
        N)r   	enumerate
tcpClients
tcpServersr   remove
connectorspopbuildProtocolr   r   r   )r   r   r   	clientIdxr   r   	factoriesr   r   r   r   r   r   s                r   succeedOncezConnectionCompleter.succeedOnce  s    %.}/G%H%H 	 	!Iz+6  
3J
KK	 !,33J???!,00;;;3<0M=%2%@%@%F%FN%2%@%@%F%FN&4^&D&DO&4^&D&DO"&'&'      	 	r   c                     | 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.
        @type reason: L{Failure}
        r      N)r   r   r   clientConnectionFailedr   )r   reasons     r   failOncezConnectionCompleter.failOnce  sV     	 $$Q''*AAM$((++V	
 	
 	
 	
 	
r   Nr   )	r(   r)   r*   r/   r   r   r   r
   r   r,   r   r   r   r     so         & & &   B &g&<&<&>&>?? 

 

 

 

 

 

r   r   c                     t                      }t          |dd          }t          |d          }|                    t	          j        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serverEndpoints       r   connectableEndpointr     sb     !""G'DAAN'66N'-h77888.w7777r   )FTr   )&r/   r   OpenSSL.SSLr   r"   ImportErrorzope.interfacer   r   twisted.internetr   r   twisted.internet.endpointsr   r	   twisted.internet.errorr
   twisted.internet.protocolr   r   twisted.internet.testingr   twisted.python.failurer   r   IAddressr.   
ITransportITLSTransportr1   r   r   r   r   r   r   r   r   r,   r   r   <module>r      s  
 
    	7777777 	 	 	D	 9 8 8 8 8 8 8 8 . . . . . . . . M M M M M M M M 9 9 9 9 9 9 7 7 7 7 7 7 7 7 7 7 7 7 7 7 * * * * * *! ! ! ! ! ! ! !& Z !!       "! Z"J$<==D D D D D D D >=DN
9 
9 
9
8 
8 
8E E E E E E E EZ 
. . . .h *)

.7 .7 .7 .7b  >;
 ;
 ;
 ;
 ;
 ;
 ;
 ;
|8 8 8 8 8 8s    