
    Vh
J                       d Z ddlmZ ddl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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      Z e
ej8                         G d d             Z e
ej<                  ej>                  ej@                         G d d             Z!d Z"d Z# G d d      Z$	 	 	 ddZ%e"e#dddfdZ&d Z' G d d      Z(ddZ)y# e$ r Y w xY w) z0
Utilities and helpers for simulating a network
    )annotationsN)Error)directlyProvidesimplementer)error
interfaces)TCP4ClientEndpointTCP4ServerEndpoint)ConnectionRefusedError)FactoryProtocol)MemoryReactorMemoryReactorClock)Failurec                       e Zd Zd ZddZd Zy)TLSNegotiationc                <    || _         || _        d| _        || _        y )NF)objconnectStatesentreadyToSend)selfr   r   s      B/home/dcms/DCMS/lib/python3.12/site-packages/twisted/test/iosim.py__init__zTLSNegotiation.__init__   s     (	'    c                "    d| j                   dS )NzTLSNegotiation())r   r   s    r   __repr__zTLSNegotiation.__repr__"   s     A..r   c                    | j                   j                  |j                         s t               |_        |j	                          y y N)r   iosimVerifyNativeOpenSSLErrordisconnectReasonloseConnection)r   othertpts      r   pretendToVerifyzTLSNegotiation.pretendToVerify%   s6     xx##EII.#5#7C   /r   Nreturnstr)__name__
__module____qualname__r   r   r(    r   r   r   r      s    (/!r   r   c                      e Zd ZdZy)FakeAddressz]
    The default address type for the host and peer of L{FakeTransport}
    connections.
    N)r,   r-   r.   __doc__r/   r   r   r1   r1   .   s    r   r1   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 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)y)"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']AS r   r   zConnection doneNc                    || _         || _        g | _        | j                         | _        |
t               }|| _        |
t               }|| _        y)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serialr1   hostAddresspeerAddress)r   r;   r<   r@   rA   s        r   r   zFakeTransport.__init__H   sS    " ! &&(%-K&%-K&r   c                    dj                  | j                  xr dxs d| j                  | j                  j                  j
                        S )NzFakeTransport<{},{},{}>SC)formatr<   r?   r;   	__class__r,   r   s    r   r   zFakeTransport.__repr__d   s@    (//MM!c(SKKMM##,,
 	
r   c                    | j                   ry | j                  | j                  j                  |       y | j                  j                  |       y r!   )disconnectingtlstlsbufappendr=   )r   datas     r   writezFakeTransport.writek   s<    88KKt$KKt$r   c                l    | j                   r(| j                  s| j                   j                          y y y r!   producerstreamingProducerresumeProducingr   s    r   _checkProducerzFakeTransport._checkProduceru   s*     ==!7!7MM))+ "8=r   c                F    || _         || _        |s|j                          yy)z.
        From abstract.FileDescriptor
        NrO   )r   rP   	streamings      r   registerProducerzFakeTransport.registerProducer{   s'     !!*$$& r   c                    d | _         y r!   )rP   r   s    r   unregisterProducerz FakeTransport.unregisterProducer   s	    r   c                D    | j                          | j                          y r!   )rX   r%   r   s    r   stopConsumingzFakeTransport.stopConsuming   s    !r   c                D    | j                  dj                  |             y )Nr   )rM   join)r   iovecs     r   writeSequencezFakeTransport.writeSequence   s    

388E?#r   c                    d| _         y NTrH   r   s    r   r%   zFakeTransport.loseConnection   s
    !r   c                    d| _         y)zp
        For the time being, this is the same as loseConnection; no buffered
        data will be lost.
        TNra   r   s    r   abortConnectionzFakeTransport.abortConnection   s    
 "r   c                    | j                   t               }n| j                  }| j                  j	                  t        |             y r!   )rI   r#   r$   r;   connectionLostr   )r   errs     r   reportDisconnectzFakeTransport.reportDisconnect   s7    88 %&C''C$$WS\2r   c                     y)zM
        Identify this transport/event source to the logging system.
        iosimr/   r   s    r   	logPrefixzFakeTransport.logPrefix   s     r   c                    | j                   S r!   )rA   r   s    r   getPeerzFakeTransport.getPeer       r   c                    | j                   S r!   )r@   r   s    r   getHostzFakeTransport.getHost   rm   r   c                     y r!   r/   r   s    r   rR   zFakeTransport.resumeProducing       r   c                     y r!   r/   r   s    r   pauseProducingzFakeTransport.pauseProducing   rq   r   c                $    | j                          y r!   )r%   r   s    r   stopProducingzFakeTransport.stopProducing   s    r   c                R    | j                   |z  }t        ||      | _        g | _        y r!   )r<   r   rI   rJ   )r   contextFactorybeNormalr   s       r   startTLSzFakeTransport.startTLS   s'     }}x/!.,?r   c                    | j                   }|rg | _         dj                  |      S | j                  4| j                  j                  rd| j                  _        | j                  S yy)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=   r\   rI   r   r   )r   rC   s     r   getOutBufferzFakeTransport.getOutBuffer   sV     KKDK88A;XX!xx## $xxr   c                   t        |t              r| j                  J | j                  j                  rc| j                  j	                  ||        d | _        | j
                  d c}| _        | j                  |       t        | t        j                         y d| j                  _
        y | j                  j                  |       y r`   )
isinstancer   rI   r   r(   rJ   r^   r   r   ISSLTransportr   r;   dataReceived)r   bufbs      r   bufferReceivedzFakeTransport.bufferReceived   s    c>*88''' xx}}((d3 "&d4;""1% z'?'?@ (,$MM&&s+r   c                     y r!   r/   r   s    r   getTcpKeepAlivezFakeTransport.getTcpKeepAlive   rq   r   c                     y r!   r/   r   s    r   getTcpNoDelayzFakeTransport.getTcpNoDelay   rq   r   c                     y r!   r/   r   s    r   loseWriteConnectionz!FakeTransport.loseWriteConnection   rq   r   c                     y r!   r/   r   enableds     r   setTcpKeepAlivezFakeTransport.setTcpKeepAlive   rq   r   c                     y r!   r/   r   s     r   setTcpNoDelayzFakeTransport.setTcpNoDelay   rq   r   )NNr)   )T)*r,   r-   r.   r2   staticmethod	itertoolscountr>   closedrH   disconnectedr   ConnectionDoner$   rP   rQ   rI   r   r   rM   rS   rV   rX   rZ   r^   r%   rc   rg   rj   rl   ro   rR   rs   ru   ry   r{   r   r   r   r   r   r   r/   r   r   r4   r4   6   s     oioo.?STKFML+u++,=>H
C'8
%,'$""3  ,,&r   r4   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r<   r4   )clientProtocols    r   makeFakeClientr      s     %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7r   c                  (    e Zd ZdZddZddZddZy)IOPumpz
    Utility to pump data between clients and servers for protocol testing.

    Perhaps this is a utility worthy of being in protocol.py?
    Nc                p    || _         || _        || _        || _        || _        |
t               }|| _        y r!   )clientserverclientIOserverIOdebugr   clock)r   r   r   r   r   r   r   s          r   r   zIOPump.__init__  s9      
=&(E
r   c                b    d}t        d      D ]  }| j                  ||      rd} |S  J d       )zk
        Pump until there is no more input or output.

        Returns whether any data was moved.
        Fi  TzToo long)rangepump)r   r   advanceClockresult_s        r   flushzIOPump.flush)  sE     t 	!Ayy- 	! !j 1r   c                \   |r| j                   j                  d       | j                  s|rt        d       | j                  j                         }| j                  j                         }| j                  j                          | j                  j                          | j                  s|r=t        d       |rt        dt        |      z          |rt        dt        |      z          |r| j                  j                  |       |r| j                  j                  |       |s|ry| j                  j                  rl| j                  j                  sV| j                  s|rt        d       d| j                  _        d| j                  _
        | j                  j                          y| j                  j                  rl| j                  j                  sV| j                  s|rt        d       d| j                  _        d| j                  _
        | j                  j                          yy	)
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   r{   r   rS   reprr   rH   r   rg   )r   r   r   sDatacDatas        r   r   zIOPump.pump9  s    JJq!::,**,**,$$&$$&::#Jed5k)*ed5k)*MM((/MM((/E==&&t}}/I/IzzUe)-DMM&*.DMM'MM**,==&&t}}/I/IzzUe)-DMM&*.DMM'MM**,r   r!   FT)r,   r-   r.   r2   r   r   r   r/   r   r   r   r     s     *r   r   FTc                    | j                  |       |j                  |       t        || ||||      }|r|j                          |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   serverTransportr   clientTransportr   greetr   r   s           r   connectr   f  sP    T !!/2!!/2D 

Kr   c                h     |       } |        } ||      }	 ||      }
||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}

    @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sios              r   connectedServerAndClientr     sE    \ 	AA
 
#C
 
#CaCCUCCCr   c                4    | \  }}}}}|\  }}}	}
||k(  r||fS y)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     s?    . 	BL?ZZm++r   c                  D    e Zd ZdZddZdddZ e e             fd	dZy)
ConnectionCompleterz
    A L{ConnectionCompleter} can cause synthetic TCP connections established by
    L{MemoryReactor.connectTCP} and L{MemoryReactor.listenTCP} to succeed or
    fail.
    c                    || _         y)z
        Create a L{ConnectionCompleter} from a L{MemoryReactor}.

        @param memoryReactor: The reactor to attach to.
        N)_reactor)r   memoryReactors     r   r   zConnectionCompleter.__init__  s     &r   c           
        | j                   }t        |j                        D ]  \  }}|j                  D ]  }t	        ||      }|s|j                  j                  |       |j                  j                  |       |\  }}	|j                  d      }
|	j                  d      }t        |      }t        |
      }t        |||
|||      }|c c S   y)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   r   r   r   r   r   s                  r   succeedOncezConnectionCompleter.succeedOnce  s     %.}/G/G%H 	"!Iz+66 "
3J
K	!,,33J?!,,00;3<0M=%2%@%@%FN%2%@%@%FN&4^&DO&4^&DO%,&'&'#&F "M%"	"( r   c                    | j                   j                  j                  d      d   j                  | j                   j                  j                  d      |       y)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   reasons     r   failOncezConnectionCompleter.failOnce%  sF     	  $$Q'*AAMM$$((+V	
r   N)r   r   r*   Noner   )r   boolr   r   r*   zIOPump | None)r   r   r*   r   )	r,   r-   r.   r2   r   r   r   r   r   r/   r   r   r   r     s%    & D *11G1I)J 	
r   r   c                    t               }t        |dd      }t        |d      }|j                  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   1  sP     !"G'DAN'6N'--h78.w777r   )FTN)F)*r2   
__future__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   r   twisted.python.failurer   r   IAddressr1   
ITransportITLSTransport	IConsumerr4   r   r   r   r   r   r   r   r   r/   r   r   <module>r      s  
 # 	7 9 . M 9 7 F *! !& Z  !  " Z""J$<$<j>R>RSD D TDN
9
8K Kf 

7z *)


2Dj>:
 :
z8G  		s   C C C 