Ϫf\2dZddlZddlZddlZddlZddlmZmZmZddl m Z ddl m Z m Z mZddlmZmZddlmZddlmZmZmZmZmZdd lmZmZdd lmZmZm Z m!Z!dd l"m#Z#m$Z$m%Z%m&Z&m'Z'm(Z(m)Z)m*Z*dd l+m,Z,m-Z-m.Z.m/Z/ dd l0m1Z1m2Z2ddl4m5Z5ddl6m7Z7ddl8m9Z9ddl:m;Z;ddlZ>ddl?m@Z@mAZAddlBmCZCmDZDmEZEddlFmGZGddlHmIZIddlJmKZKddlLmMZMddlNmOZOmPZP ddlQmRZSddlTmUZUmVZVmWZWmXZXmYZYmZZZddl[m\Z]e]Z\gdZ^Gdd e/Z_Gd!d"e,Z`e ejGd#d$ZbGd%d&ejejejZfGd'd(eGefd)ZgGd*d+e.ZhGd,d-eZie ejGd.d/Zke ejGd0d1ZlGd2d3elZmGd4d5elZne ejGd6d7Zoe ejGd8d9Zpe e$Gd:d;Zqe ejGd<d=Zre ejGd>d?Zse ejGd@dAZte ejGdBdCZue ejGdDdEZve ejGdFdGZwdkdHZxdldIZy dmdJZze e=e*GdKdLZ{e e=e*GdMdNZ|e e=e*GdOdPZ}exeyezdQZ~edR\ZZdSZdTZemeseudUZeoetevdUZdVZdWZdXZdYZdZZd[Zd\Zd]Zd^Zd_Zd`ZeeedUZdaZdbZe ejGdcddZe ejGdedfZdgZ dndhZe e=e)GdidjZy#e3$rdZ2dZ1YqwxYw#e3$rdZ\YwxYw)oa7 Implementations of L{IStreamServerEndpoint} and L{IStreamClientEndpoint} that wrap the L{IReactorTCP}, L{IReactorSSL}, and L{IReactorUNIX} interfaces. This also implements an extensible mini-language for describing endpoints, parsed by the L{clientFromString} and L{serverFromString} functions. @since: 10.1 N)OptionalSequenceType) normalize)directlyProvides implementerprovider) NamedConstantNames)Version)defererrorfdesc interfacesthreads) isIPAddress isIPv6Address)HostnameAddress IPv4Address IPv6Address_ProcessAddress)IAddressIHostnameResolverIHostResolutionIReactorPluggableNameResolverIReactorSocketIResolutionReceiver,IStreamClientEndpointStringParserWithReactor!IStreamServerEndpointStringParser) ClientFactoryFactoryProcessProtocolProtocol) PipeAddress StandardIO)HostResolution)Deferred) LoopingCall)Logger)IPlugin getPlugins) deprecatelog)_matchingString iterbytes nativeString)proxyForInterface)Failure)FilePath) ListenFDs) _idnaBytes _idnaText)Error) CertificateCertificateOptionsKeyPairPrivateCertificateoptionsForClientTLStrustRootFromCertificatesTLSMemoryBIOFactory)clientFromStringserverFromStringTCP4ServerEndpointTCP6ServerEndpointTCP4ClientEndpointTCP6ClientEndpointUNIXServerEndpointUNIXClientEndpointSSL4ServerEndpointSSL4ClientEndpointAdoptedStreamServerEndpointStandardIOEndpointProcessEndpointHostnameEndpointStandardErrorBehaviorconnectProtocol wrapClientTLScFeZdZdZdZdZdZdZdZdZ dZ d Z d Z y ) _WrappingProtocolz_ Wrap another protocol in order to notify my user when a connection has been made. c||_||_tjtjtj fD]*}|j |jst||,y)z @param connectedDeferred: The L{Deferred} that will callback with the C{wrappedProtocol} when it is connected. @param wrappedProtocol: An L{IProtocol} provider that will be connected. N)_connectedDeferred_wrappedProtocolrIHalfCloseableProtocolIFileDescriptorReceiverIHandshakeListener providedByr)selfconnectedDeferredwrappedProtocolifaces )>?rac8|jj|S)zM Proxy C{dataReceived} calls to our C{self._wrappedProtocol} )rV dataReceived)r[datas r_rnz_WrappingProtocol.dataReceiveds$$11$77rac8|jj|S)zW Proxy C{fileDescriptorReceived} calls to our C{self._wrappedProtocol} )rVfileDescriptorReceived)r[ descriptors r_rqz(_WrappingProtocol.fileDescriptorReceiveds$$;;JGGrac8|jj|S)zO Proxy C{connectionLost} calls to our C{self._wrappedProtocol} )rVconnectionLostr[reasons r_rtz _WrappingProtocol.connectionLosts$$33F;;rac8|jjy)zl Proxy L{IHalfCloseableProtocol.readConnectionLost} to our C{self._wrappedProtocol} N)rVreadConnectionLostrgs r_rxz$_WrappingProtocol.readConnectionLost 002rac8|jjy)zm Proxy L{IHalfCloseableProtocol.writeConnectionLost} to our C{self._wrappedProtocol} N)rVwriteConnectionLostrgs r_r{z%_WrappingProtocol.writeConnectionLosts 113rac8|jjy)za Proxy L{interfaces.IHandshakeListener} to our C{self._wrappedProtocol}. N)rVhandshakeCompletedrgs r_r}z$_WrappingProtocol.handshakeCompletedryraN) rf __module__ __qualname____doc__r`rdrlrnrqrtrxr{r}rar_rSrSjs6 .&8@8 H < 343rarSc>eZdZdZeZdZdZdZdZ dZ dZ dZ y ) _WrappingFactorya Wrap a factory in order to wrap the protocols it builds. @ivar _wrappedFactory: A provider of I{IProtocolFactory} whose buildProtocol method will be called and whose resulting protocol will be wrapped. @ivar _onConnection: A L{Deferred} that fires when the protocol is connected @ivar _connector: A L{connector } that is managing the current or previous connection attempt. c\||_tj|j|_y)z @param wrappedFactory: A provider of I{IProtocolFactory} whose buildProtocol method will be called and whose resulting protocol will be wrapped.  cancellerN)_wrappedFactoryr r' _canceller _onConnection)r[wrappedFactorys r_r`z_WrappingFactory.__init__s! ."^^dooFrac||_y)z~ A connection attempt was started. Remember the connector which started said attempt, for use later. N) _connector)r[ connectors r_startedConnectingz"_WrappingFactory.startedConnectings $rac|jtj|jj |jj y)a; The outgoing connection attempt was cancelled. Fail that L{Deferred} with an L{error.ConnectingCancelledError}. @param deferred: The L{Deferred } that was cancelled; should be the same as C{self._onConnection}. @type deferred: L{Deferred } @note: This relies on startedConnecting having been called, so it may seem as though there's a race condition where C{_connector} may not have been set. However, using public APIs, this condition is impossible to catch, because a connection API (C{connectTCP}/C{SSL}/C{UNIX}) is always invoked before a L{_WrappingFactory}'s L{Deferred } is returned to C{connect()}'s caller. @return: L{None} N)errbackrConnectingCancelledErrorrgetDestinationstopConnecting)r[deferreds r_rz_WrappingFactory._cancellers?&   * *4??+I+I+K L  &&(rac8|jjy)zY Start notifications are passed straight through to the wrapped factory. N)rdoStartrgs r_rz_WrappingFactory.doStarts $$&rac8|jjy)zX Stop notifications are passed straight through to the wrapped factory. N)rdoStoprgs r_rz_WrappingFactory.doStops ##%rac |jj|}|tj |j |j |S#t $r|j jYywxYw)a Proxy C{buildProtocol} to our C{self._wrappedFactory} or errback the C{self._onConnection} L{Deferred} if the wrapped factory raises an exception or returns L{None}. @return: An instance of L{_WrappingProtocol} or L{None} N)r buildProtocolr NoProtocolprotocolr BaseExceptionr)r[addrprotos r_rz_WrappingFactory.buildProtocolsr <((66t(rarMceZdZdZdZdZy)_TCPServerEndpointz) A TCP server endpoint interface c<||_||_||_||_y)a+ @param reactor: An L{IReactorTCP} provider. @param port: The port number used for listening @type port: int @param backlog: Size of the listen queue @type backlog: int @param interface: The hostname to bind to @type interface: str N)r_port_backlog _interfacer[rportbacklog interfaces r_r`z_TCPServerEndpoint.__init__s     #ractj|jj|j||j |j S)z] Implement L{IStreamServerEndpoint.listen} to listen on a TCP socket )rr)r rr listenTCPrrrr[rs r_rz_TCPServerEndpoint.listens: }} MM # # JJ MMoo   raNrfr~rrr`rrrar_rrs$$  rarceZdZdZddZy)rCzC Implements TCP server endpoint with an IPv4 configuration c6tj|||||y)aA @param reactor: An L{IReactorTCP} provider. @param port: The port number used for listening @type port: int @param backlog: Size of the listen queue @type backlog: int @param interface: The hostname to bind to, defaults to '' (all) @type interface: str Nrr`rs r_r`zTCP4ServerEndpoint.__init__ ##D'4)LraN2rfr~rrr`rrar_rCrC   MrarCceZdZdZddZy)rDzC Implements TCP server endpoint with an IPv6 configuration c6tj|||||y)aD @param reactor: An L{IReactorTCP} provider. @param port: The port number used for listening @type port: int @param backlog: Size of the listen queue @type backlog: int @param interface: The hostname to bind to, defaults to C{::} (all) @type interface: str Nrrs r_r`zTCP6ServerEndpoint.__init__$rraNrz::rrrar_rDrDrrarDceZdZdZddZdZy)rEz9 TCP client endpoint with an IPv4 configuration. NcJ||_||_||_||_||_y)a @param reactor: An L{IReactorTCP} provider @param host: A hostname, used when connecting @type host: str @param port: The port number, used when connecting @type port: int @param timeout: The number of seconds to wait before assuming the connection has failed. @type timeout: L{float} or L{int} @param bindAddress: A (host, port) tuple of local address to bind to, or None. @type bindAddress: tuple Nr_hostr_timeout _bindAddressr[rhostrtimeout bindAddresss r_r`zTCP4ClientEndpoint.__init__:s($     'rac t|}|jj|j|j||j |j |jS#t$rtjcYSwxYw)zP Implement L{IStreamClientEndpoint.connect} to connect via TCP. rr) rr connectTCPrrrrrrr rr[rwfs r_rzTCP4ClientEndpoint.connectRsr !/2B MM $ $    -- % ## # ::<  sAA!!BBNrfr~rrr`rrrar_rErE4s(0 rarEczeZdZdZeej ZeejZ dZ dZ d dZ dZdZdZy) rFa TCP client endpoint with an IPv6 configuration. @ivar _getaddrinfo: A hook used for testing name resolution. @ivar _deferToThread: A hook used for testing deferToThread. @ivar _GAI_ADDRESS: Index of the address portion in result of getaddrinfo to be used. @ivar _GAI_ADDRESS_HOST: Index of the actual host-address in the 5-tuple L{_GAI_ADDRESS}. rNcJ||_||_||_||_||_y)z @param host: An IPv6 address literal or a hostname with an IPv6 address @see: L{twisted.internet.interfaces.IReactorTCP.connectTCP} Nrrs r_r`zTCP6ClientEndpoint.__init__ys(     'ractjrjj|}|Sjj}|j fd|j j||S)z~ Implement L{IStreamClientEndpoint.connect} to connect via TCP, once the hostname resolution is done. cB|djjS)Nr) _GAI_ADDRESS_GAI_ADDRESS_HOST)resultr[s r_z,TCP6ClientEndpoint.connect..s!vay):):;D.cbDeliversg@I V<%HV__,&66{57T87TUv~~-&66{57T87TU  VracXjjd|jy)Nz'while looking up {name} with {callable})namecallable)_logfailurer)rr,r[s r_ebLogz6_SimpleHostnameResolver.resolveHostName..ebLogs, II  9--  rac$jSN)resolutionComplete)ignoredr+s r_rz9_SimpleHostnameResolver.resolveHostName..s"4"G"G"Ira)r&resolutionBeganrr addErrbackaddBoth) r[r+r,r-r.r/ resolutionrr;rAs ``` r_resolveHostNamez'_SimpleHostnameResolver.resolveHostNamesg4$H- **:6  : 6 V  i  U IJra)rNr3)rfr~rrr)r?r`rstrintrrrrrrJrrar_r(r(sm  8D.;?"' 0/00 0 xX78 0  0 0rar(ceZdZdZeej ZeejZ dZ d dZ de fdZdZedZd Zd Zy) rNaB A name-based endpoint that connects to the fastest amongst the resolved host addresses. @cvar _DEFAULT_ATTEMPT_DELAY: The default time to use between attempts, in seconds, when no C{attemptDelay} is given to L{HostnameEndpoint.__init__}. @ivar _hostText: the textual representation of the hostname passed to the constructor. Used to pass to the reactor's hostname resolver. @type _hostText: L{unicode} @ivar _hostBytes: the encoded bytes-representation of the hostname passed to the constructor. Used to construct the L{HostnameAddress} associated with this endpoint. @type _hostBytes: L{bytes} @ivar _hostStr: the native-string representation of the hostname passed to the constructor, used for exception construction @type _hostStr: native L{str} @ivar _badHostname: a flag - hopefully false! - indicating that an invalid hostname was passed to the constructor. This might be a textual hostname that isn't valid IDNA, or non-ASCII bytes. @type _badHostname: L{bool} g333333?Nc,||_|j||_|j|\|_|_|_ttur |j n |j |_ ||_ ||_ ||_ | |j}||_y)a Create a L{HostnameEndpoint}. @param reactor: The reactor to use for connections and delayed calls. @type reactor: provider of L{IReactorTCP}, L{IReactorTime} and either L{IReactorPluggableNameResolver} or L{IReactorPluggableResolver}. @param host: A hostname to connect to. @type host: L{bytes} or L{unicode} @param port: The port number to connect to. @type port: L{int} @param timeout: For each individual connection attempt, the number of seconds to wait before assuming the connection has failed. @type timeout: L{float} or L{int} @param bindAddress: the local address of the network interface to make the connections from. @type bindAddress: L{bytes} @param attemptDelay: The number of seconds to delay between connection attempts. @type attemptDelay: L{float} @see: L{twisted.internet.interfaces.IReactorTCP.connectTCP} N)r_getNameResolverAndMaybeWarn _nameResolver_hostAsBytesAndText _badHostname _hostBytes _hostTextbytesrK_hostStrrrr_DEFAULT_ATTEMPT_DELAY _attemptDelay)r[rrrrr attemptDelays r_r`zHostnameEndpoint.__init__s>  !>>wG?C?W?W @ < DOT^,1C<T^^   '  66L)rar0c|jr |j}n;t|jrd|jd}nt|j}dj d|dt |jdgS)zh Produce a string representation of the L{HostnameEndpoint}. @return: A L{str} []rz)rRrVrr0rSjoinrKrr!s r___repr__zHostnameEndpoint.__repr__Csi   ==D 4== )t}}oQ'D  0Dww,dCTZZ#NOOrac tj|s`tj|jt dddddd}t j|td t|jS|jS) a Retrieve a C{nameResolver} callable and warn the caller's caller that using a reactor which doesn't provide L{IReactorPluggableNameResolver} is deprecated. @param reactor: The reactor to check. @return: A L{IHostnameResolver} provider. TwistedrzPassing HostnameEndpoint a reactor that does not provide IReactorPluggableNameResolver (%(fqpn)s) was deprecated in %(version)sz5a reactor that provides IReactorPluggableNameResolver)r replacement) stacklevel) rrZr,getDeprecationWarningStringrer warningswarnDeprecationWarningr(_fallbackNameResolution nameResolver)r[r warningStrings r_rOz-HostnameEndpoint._getNameResolverAndMaybeWarnWst-77@%AA!! 2q!,5 O M MM-); J*4+G+GH H###ract|tr9t|s t|rd||j dfS d|t |fStd|}t|s t|rd|jd|fS dt||fS#t $r|j d}YnwxYw#t $rYnwxYw|jdd}d||j dfS)a For various reasons (documented in the C{@ivar}'s in the class docstring) we need both a textual and a binary representation of the hostname given to the constructor. For compatibility and convenience, we accept both textual and binary representations of the hostname, save the form that was passed, and convert into the other form. This is mostly just because L{HostnameAddress} chose somewhat poorly to define its attribute as bytes; hopefully we can find a compatible way to clean this up in the future and just operate in terms of text internally. @param host: A hostname to convert. @type host: L{bytes} or C{str} @return: a 3-tuple of C{(invalid, bytes, text)} where C{invalid} is a boolean indicating the validity of the hostname, C{bytes} is a binary representation of C{host}, and C{text} is a textual representation of C{host}. FasciicharmapNFCbackslashreplaceT) isinstancerUrrdecoder7 UnicodeErrorrencoder6)r asciibytess r_rQz$HostnameEndpoint._hostAsBytesAndTextrs( dE "4 M$$7dDKK$8882 $ $77 UD)D4 M$$7dkk'2D88 *T"2D88$2;;y1D2$ [[*<= Z!2!27!;;;s# B B/B,+B,/ B;:B;cjr+tjtdjSt gt tGfdd}jj|jjjfdjfd}jtfdjfd}S) a Attempts a connection to each resolved address, and returns a connection which is established first. @param protocolFactory: The protocol factory whose protocol will be connected. @type protocolFactory: L{IProtocolFactory} @return: A L{Deferred} that fires with the connected protocol or fails a connection-related error. zinvalid hostname: cHeZdZedZefdZefdZy)2HostnameEndpoint.connect..EndpointReceivercyrCr)resolutionInProgresss r_rFzBHostnameEndpoint.connect..EndpointReceiver.resolutionBegansrac(j|yrCappend)address addressess r_r4zBHostnameEndpoint.connect..EndpointReceiver.addressResolveds  )rac(jyrCrkrrsr_rDzEHostnameEndpoint.connect..EndpointReceiver.resolutionCompletes 9%raN)rfr~rr$rFr4rDrsr_EndpointReceiverr{s=    * * & &rar)r-cptjtjdjdS)NzCouldn't find the hostname '')r rrDNSLookupErrorrV)rEr[s r_rz*HostnameEndpoint.connect..s-EJJ$$'CDMM?RS%TUrac3jK|D]}t|trCtj|j|j j jt|tsgtj|j|j j jywrC) rtrrFrrrrrrrE)r eachAddressr[s r_resolvedAddressesToEndpointsz>HostnameEndpoint.connect..resolvedAddressesToEndpointss )  k;7, #((#(( )) k;7, #((#(( ))  s A)B3-AB3c|jtjtjj yrC)rrrrrSr)rr[s r_rz,HostnameEndpoint.connect.._cancellers1 II..#DOOTZZ@ rac||s"tjd jt|ggt j fdd_d_t fd j_ j jjfd}S)aQ Given a sequence of endpoints obtained via name resolution, start connecting to a new one every C{self._attemptDelay} seconds until one of the connections succeeds, all of them fail, or the attempt is cancelled. @param endpoints: a list of all the endpoints we might try to connect to, as determined by name resolution. @type endpoints: L{list} of L{IStreamServerEndpoint} @return: a Deferred that fires with the result of the C{endpoint.connect} method that completes the fastest, or fails with the first connection error it encountered if none of them succeed. @rtype: L{Deferred} failing with L{error.ConnectingCancelledError} or firing with L{IProtocol} z no results for hostname lookup: rczsjs jryjjyrC) completed endpointsLeftrpop) checkDonefailurespendingwinnersr_rzLHostnameEndpoint.connect..startConnectionAttempts..checkDone s+i11Y5L5Lx||~.raFTctd}|d_y|j jjfd}j fd}j fd}y)NFc*j|SrC)remove)r eachAttemptrs r_noLongerPendingzkHostnameEndpoint.connect..startConnectionAttempts..iterateEndpoint..noLongerPendingsNN;/!Mrac(j|yrCr)rrs r_ succeededzeHostnameEndpoint.connect..startConnectionAttempts..iterateEndpoint..succeeded"sOOF+rac6j|yrCr)rvrrs r_failedzbHostnameEndpoint.connect..startConnectionAttempts..iterateEndpoint..failed&sOOF+Kra)nextrrrrHrrG) endpointrrrrrr iterEndpointsrrrs @r_iterateEndpointzRHostnameEndpoint.connect..startConnectionAttempts..iterateEndpoints t4#.3I+K&..? {+$$"%"((,),'' ( racd_ddD]}|jjrj|SNT)rcancelrunningstop)r remainingrrrs r_cancelRemainingPendingzYHostnameEndpoint.connect..startConnectionAttempts..cancelRemainingPending.sD&* #!('I$$&'"**#((* ra)rrrViterr r'rrr(rclockstartrXrH) endpointsrrrrrrrrrr[s @@@@@@r_startConnectionAttemptsz9HostnameEndpoint.connect..startConnectionAttemptss&**6t}}oF!OMGH^^j9F / #(I &*I #    2%)MMO !  ! !$"4"4 5 ^^  Mra)rRr r ValueErrorrVr'r rrPrJrTrrGrlist)r[rrrrrrrs`` @@@r_rzHostnameEndpoint.connects   ::j+=dmm_)MNO O J % & & & ' & ** dnn +       ( d  I  I Vrac\|j|j||dtjS)a Resolve the hostname string into a tuple containing the host address. This is method is only used when the reactor does not provide L{IReactorPluggableNameResolver}. @param host: A unicode hostname to resolve. @param port: The port to include in the resolution. @return: A L{Deferred} that fires with L{_getaddrinfo}'s return value. r)rrr SOCK_STREAM)r[rrs r_rlz(HostnameEndpoint._fallbackNameResolution;s)""4#4#4dD!VEWEWXXra)r NN)rfr~rrr$rr%rrr&rrWr`rKr`rOrQrrlrrar_rNrNsq6  2 23L!'"7"78N OS**XP#P($6*<* ?))  PW ?KCOO # #L 1 : :  !1?B  !22;; \ "     %0099&//(!    BY $I#g,&W XX- s,E?c eZdZdZdZdZdZy)_StandardIOParserz Stream server endpoint string parser for the Standard I/O type. @ivar prefix: See L{IStreamServerEndpointStringParser.prefix}. stdioct|S)z Internal parser function for L{_parseServer} to convert the string arguments into structured arguments for the L{StandardIOEndpoint} @param reactor: Reactor for the endpoint )rLrs r_ _parseServerz_StandardIOParser._parseServers"'**rac$|j|SrCrr[rrkwargss r_parseStreamServerz#_StandardIOParser.parseStreamServers  ))raNrfr~rrprefixrr rrar_rrs F+*rarc jeZdZdZej ZdZ d dede de e de e de f d Z d Z y) _SystemdParsera Stream server endpoint string parser for the I{systemd} endpoint type. @ivar prefix: See L{IStreamServerEndpointStringParser.prefix}. @ivar _sddaemon: A L{ListenFDs} instance used to translate an index into an actual file descriptor. systemdNrdomainindexr=r0c|du|duk(r td|'|jjt|}n!|J|jj |}t t d|z}t|||S)aW Internal parser function for L{_parseServer} to convert the string arguments for a systemd server endpoint into structured arguments for L{AdoptedStreamServerEndpoint}. @param reactor: An L{IReactorSocket} provider. @param domain: The domain (or address family) of the socket inherited from systemd. This is a string like C{"INET"} or C{"UNIX"}, ie the name of an address family from the L{socket} module, without the C{"AF_"} prefix. @param index: If given, the decimal representation of an integer giving the offset into the list of file descriptors inherited from systemd. Since the order of descriptors received from systemd is hard to predict, this option should only be used if only one descriptor is being inherited. Even in that case, C{name} is probably a better idea. Either C{index} or C{name} must be given. @param name: If given, the name (as defined by C{FileDescriptorName} in the C{[Socket]} section of a systemd service definition) of an inherited file descriptor. Either C{index} or C{name} must be given. @return: An L{AdoptedStreamServerEndpoint} which will adopt the inherited listening port when it is used to listen. Nz/Specify exactly one of descriptor index or nameAF_)r _sddaemoninheritedDescriptorsrLinheritedNamedDescriptorsrrrK)r[rrrr=rrs r_rz_SystemdParser._parseServersD TMtt| ,NO O  ^^88:3u:FF# ##^^==?EF7 *7FMJJrac.|j|g|i|SrCr r s r_r z _SystemdParser.parseStreamServers!!t  :4:6::ra)NN)rfr~rrr4fromEnvironmentrrrrKrrKrr rrar_rrso* ))+I F $" ,K,K,K} ,K sm ,K % ,K\;rarc"eZdZdZdZddZdZy)_TCP6ServerParserz Stream server endpoint string parser for the TCP6ServerEndpoint type. @ivar prefix: See L{IStreamServerEndpointStringParser.prefix}. tcp6cJt|}t|}t||||S)a Internal parser function for L{_parseServer} to convert the string arguments into structured arguments for the L{TCP6ServerEndpoint} @param reactor: An L{IReactorTCP} provider. @param port: The port number used for listening @type port: int @param backlog: Size of the listen queue @type backlog: int @param interface: The hostname to bind to @type interface: str )rLrDrs r_rz_TCP6ServerParser._parseServer)s' 4yg,!'4)DDrac.|j|g|i|SrCr r s r_r z#_TCP6ServerParser.parseStreamServer=s!!t  :4:6::raNrr rrar_rrs  E(;rar)tcpunixrrc#ZKtd|}td|}td|}td|}|}||z}|||z||i}tt|}|D]D} | t|vrt|ft| f|}|| },| |k(r|t |z }@|| z }Ft|fyw)a Tokenize a strports string and yield each token. @param description: a string as described by L{serverFromString} or L{clientFromString}. @type description: L{str} or L{bytes} @return: an iterable of 2-tuples of (C{_OP} or C{_STRING}, string). Tuples starting with C{_OP} will contain a second element of either ':' (i.e. 'next parameter') or '=' (i.e. 'assign parameter value'). For example, the string 'hello:greeting=world' would result in a generator yielding these values:: _STRING, 'hello' _OP, ':' _STRING, 'greet=ing' _OP, '=' _STRING, 'world' rr]=\N)r.rr/_STRING_OPr) descriptionemptycolonequals backslashcurrentopsnextOpsiterdescns r_ _tokenizer1Ls( B ,E C -E S+ .F 4IG &.Cefnfe4GIk*+H   # 7" "q&LG!*C )^ tH~ %G qLG  7 sB)B+cgictd|}fd}d}t|D]$\}}|tur||fz }||k(s||d}&||fS)a Convert a description string into a list of positional and keyword parameters, using logic vaguely like what Python does. @param description: a string as described by L{serverFromString} or L{clientFromString}. @return: a 2-tuple of C{(args, kwargs)}, where 'args' is a list of all ':'-separated C{str}s not containing an '=' and 'kwargs' is a map of all C{str}s which do contain an '='. For example, the result of C{_parse('a:b:d=1:c')} would be C{(['a', 'b', 'c'], {'d': '1'})}. r]ctt|dk(rj|dy|dt|d<y)Nr5r)lenrr0)sofarrrs r_addz_parse..adds5 u:? KKa !).qB|E!H% &rar)r.r1r%)r'r)r6r5typerrrs @@r__parser8vsx2HD" C -E2 E - e 7? eX E e^ JE  J 8Ora)r3rUNIXct|\}}|d}tj|}|!tt t |}||dd|fS|j f||g|ddi|zS)a Parse a strports description into a 2-tuple of arguments and keyword values. @param description: A description in the format explained by L{serverFromString}. @type description: C{str} @param factory: A 'factory' argument; this is left-over from twisted.application.strports, it's not really used. @type factory: L{IProtocolFactory} or L{None} @return: a 3-tuple of (plugin or name, arguments, keyword arguments) rNr5)r8_serverParsersget_matchPluginToPrefixr+rupper)r'rrr endpointTypeparserplugins r_rrsk"HD"7L    -F ~& 8 9< QR"%%    "VG%Ed12h%E"%E EErac|j}|D]-}t|jj||k(s+|cStd|d)z! Match plugin to prefix. zUnknown endpoint type: 'r)lowerr.rr)pluginsr?rAs r_r=r=sY %%'L 6==..0, ?< OM / ~Q? @@ract|d\}}}t|tur|}|j|g|i|S|}|dd|ddz}t ||g|i|S)a_ Construct a stream server endpoint from an endpoint description string. The format for server endpoint descriptions is a simple byte string. It is a prefix naming the type of endpoint, then a colon, then the arguments for that endpoint. For example, you can call it like this to create an endpoint that will listen on TCP port 80:: serverFromString(reactor, "tcp:80") Additional arguments may be specified as keywords, separated with colons. For example, you can specify the interface for a TCP server endpoint to bind to like this:: serverFromString(reactor, "tcp:80:interface=127.0.0.1") SSL server endpoints may be specified with the 'ssl' prefix, and the private key and certificate files may be specified by the C{privateKey} and C{certKey} arguments:: serverFromString( reactor, "ssl:443:privateKey=key.pem:certKey=crt.pem") If a private key file name (C{privateKey}) isn't provided, a "server.pem" file is assumed to exist which contains the private key. If the certificate file name (C{certKey}) isn't provided, the private key file is assumed to contain the certificate as well. You may escape colons in arguments with a backslash, which you will need to use if you want to specify a full pathname argument on Windows:: serverFromString(reactor, "ssl:443:privateKey=C\:/key.pem:certKey=C\:/cert.pem") finally, the 'unix' prefix may be used to specify a filesystem UNIX socket, optionally with a 'mode' argument to specify the mode of the socket file created by C{listen}:: serverFromString(reactor, "unix:/var/run/finger") serverFromString(reactor, "unix:/var/run/finger:mode=660") This function is also extensible; new endpoint types may be registered as L{IStreamServerEndpointStringParser} plugins. See that interface for more information. @param reactor: The server endpoint will be constructed with this reactor. @param description: The strports description to parse. @type description: L{str} @return: A new endpoint which can be used to listen with the parameters given by C{description}. @rtype: L{IStreamServerEndpoint} @raise ValueError: when the 'description' string cannot be parsed. @since: 10.2 Nr5r)rr7rKr _endpointServerFactories)rr' nameOrPluginrrrAr=s r_rBrBs||*+t<L$ L$'v''=$="== 8d12h D #D )' ?D ?B ??racLd\}}||fD]}|j|||z}|S)a Quote an argument to L{serverFromString} and L{clientFromString}. Since arguments are separated with colons and colons are escaped with backslashes, some care is necessary if, for example, you have a pathname, you may be tempted to interpolate into a string like this:: serverFromString(reactor, "ssl:443:privateKey=%s" % (myPathName,)) This may appear to work, but will have portability issues (Windows pathnames, for example). Usually you should just construct the appropriate endpoint type rather than interpolating strings, which in this case would be L{SSL4ServerEndpoint}. There are some use-cases where you may need to generate such a string, though; for example, a tool to manipulate a configuration file which has strports descriptions in it. To be correct in those cases, do this instead:: serverFromString(reactor, "ssl:443:privateKey=%s" % (quoteStringArgument(myPathName),)) @param argument: The part of the endpoint description string you want to pass through. @type argument: C{str} @return: The quoted argument. @rtype: C{str} z\:)replace)argumentr+r)cs r_quoteStringArgumentrLs=:Iu  6##Ay1}56 Oracht|dk(rt|d|d<|d|d<n,t|dk(rd|vrt|d|d<n|d|d< t|d|d< t|d|d< |ddf|d<|S#t$rY*wxYw#t$rY'wxYw#t$rY|SwxYw)a$ Perform any argument value coercion necessary for TCP client parameters. Valid positional arguments to this function are host and port. Valid keyword arguments to this function are all L{IReactorTCP.connectTCP} arguments. @return: The coerced values as a C{dict}. rr5rrrrr)r4rLKeyErrorrr s r__parseClientTCPrP8s 4yA~T!Wvav Ta V  a\F6N!!WF6N VF^,v y 12y !' !6 :} M         M s6B(B: B$ BB B! B!$ B10B1ci}|jD]~}|jjjddj dk(sE |j } tj|}|||j<t|jS#t $rYwxYw#t$rYwxYw)z Load certificate-authority certificate objects in a given directory. @param directoryPath: a L{unicode} or L{bytes} pointing at a directory to load .pem files from, or L{None}. @return: an L{IOpenSSLTrustRoot} provider. .pem) children asTextModebasenamesplitrCrOSErrorr9rdigestSSLErrorr>values) directoryPathcaCertschildrotheCerts r__loadCAsFromDirra_sG'')0!**,2237;AACuL  ##%D 0!))$/G )0GGNN$ %0 %W^^%5 66       s$B-*B<- B98B9< CCc0|ytt|S)z Parse a string referring to a directory full of certificate authorities into a trust root. @param pathName: path name @type pathName: L{unicode} or L{bytes} or L{None} @return: L{None} or L{IOpenSSLTrustRoot} N)rar3)pathNames r__parseTrustRootPathrd{s 8H- ..rac|yt|j}|tj|Stjt j|t jt|jdS)ax Parse a certificate path and key path, either or both of which might be L{None}, into a certificate object. @param certificatePath: the certificate path @type certificatePath: L{bytes} or L{unicode} or L{None} @param keyPath: the private key path @type keyPath: L{bytes} or L{unicode} or L{None} @return: a L{PrivateCertificate} or L{None} Nr5)r3rr<rfromCertificateAndKeyPairr9r;load)certificatePathkeyPath certBytess r__privateCertFromPathsrkss)446I!)))44!;;    * LL'*557 ;  racd|jdd}t|jdd|jdd}t|jdd}|tt |||}n7|#|j j }|j }nd}d}t|||}||d<|S) a Parse common arguments for SSL endpoints, creating an L{CertificateOptions} instance. @param kwargs: A dict of keyword arguments to be parsed, potentially containing keys C{certKey}, C{privateKey}, C{caCertsDir}, and C{hostname}. See L{_parseClientSSL}. @type kwargs: L{dict} @return: The remaining arguments, including a new key C{sslContextFactory}. hostnameNrr caCertsDir trustRootclientCertificate)rprrr)rrkrdr=r7rrr:)r rmrqrp configurationprivateKeyOpenSSLcertificateOpenSSLs r__parseClientSSLOptionsruszz*d+H- 9d#VZZ d%C$FJJ|T$BCI+ h /   ( 1 < < E E !2!;!;  $ !% *(* #0F  Mrac.t|i|}t|S)a Perform any argument value coercion necessary for SSL client parameters. Valid keyword arguments to this function are all L{IReactorSSL.connectSSL} arguments except for C{contextFactory}. Instead, C{certKey} (the path name of the certificate file) C{privateKey} (the path name of the private key associated with the certificate) are accepted and used to construct a context factory. Valid positional arguments to this function are host and port. @keyword caCertsDir: The one parameter which is not part of L{IReactorSSL.connectSSL}'s signature, this is a path name used to construct a list of certificate authority certificates. The directory will be scanned for files ending in C{.pem}, all of which will be considered valid certificate authorities for this connection. @type caCertsDir: L{str} @keyword hostname: The hostname to use for validating the server's certificate. @type hostname: L{unicode} @return: The coerced values as a L{dict}. )rPrurOs r__parseClientSSLrws2d -f -F !& ))ract|dk(r|d|d< tt|jd|d< t|d|d<|S#t$rYwxYw#t$rY|SwxYw)a Perform any argument value coercion necessary for UNIX client parameters. Valid keyword arguments to this function are all L{IReactorUNIX.connectUNIX} keyword arguments except for C{checkPID}. Instead, C{lockfile} is accepted and has the same meaning. Also C{path} is used instead of C{address}. Valid positional arguments to this function are C{path}. @return: The coerced values as a C{dict}. r5rrrrr)r4rrLrrNrOs r__parseClientUNIXrys 4yA~av !#fjj&<"=>z y 12y M       M s"&AA! AA! A.-A.ct|\}}|jd}|j}|tvr/t t t |}|j|g|i|St||i|}t||fi|S)a Construct a client endpoint from a description string. Client description strings are much like server description strings, although they take all of their arguments as keywords, aside from host and port. You can create a TCP client endpoint with the 'host' and 'port' arguments, like so:: clientFromString(reactor, "tcp:host=www.example.com:port=80") or, without specifying host and port keywords:: clientFromString(reactor, "tcp:www.example.com:80") Or you can specify only one or the other, as in the following 2 examples:: clientFromString(reactor, "tcp:host=www.example.com:80") clientFromString(reactor, "tcp:www.example.com:port=80") or an SSL client endpoint with those arguments, plus the arguments used by the server SSL, for a client certificate:: clientFromString(reactor, "ssl:web.example.com:443:" "privateKey=foo.pem:certKey=foo.pem") to specify your certificate trust roots, you can identify a directory with PEM files in it with the C{caCertsDir} argument:: clientFromString(reactor, "ssl:host=web.example.com:port=443:" "caCertsDir=/etc/ssl/certs") Both TCP and SSL client endpoint description strings can include a 'bindAddress' keyword argument, whose value should be a local IPv4 address. This fixes the client socket to that IP address:: clientFromString(reactor, "tcp:www.example.com:80:" "bindAddress=192.0.2.100") NB: Fixed client ports are not currently supported in TCP or SSL client endpoints. The client socket will always use an ephemeral port assigned by the operating system You can create a UNIX client endpoint with the 'path' argument and optional 'lockfile' and 'timeout' arguments:: clientFromString( reactor, b"unix:path=/var/foo/bar:lockfile=1:timeout=9") or, with the path as a positional argument with or without optional arguments as in the following 2 examples:: clientFromString(reactor, "unix:/var/foo/bar") clientFromString(reactor, "unix:/var/foo/bar:lockfile=1:timeout=9") This function is also extensible; new endpoint types may be registered as L{IStreamClientEndpointStringParserWithReactor} plugins. See that interface for more information. @param reactor: The client endpoint will be constructed with this reactor. @param description: The strports description to parse. @type description: L{str} @return: A new endpoint which can be used to connect with the parameters given by C{description}. @rtype: L{IStreamClientEndpoint} @since: 10.2 r) r8rr>_clientParsersr=r+rparseStreamClient_endpointClientFactories)rr'rr anamer=rAs r_rArA sP+&LD& HHQKE ;;=D >!% C Dd (v''A$A&AA D !4 26 2F #D )' .OneShotFactorycSrCr)r[rrs r_rz5connectProtocol..OneShotFactory.buildProtocolosOraN)rfr~rrrsr_OneShotFactoryrns rar)r!r)rrrs ` r_rPrP]s%"   N, --raceZdZdZdZdZy)_WrapperEndpointz2 An endpoint that wraps another endpoint. c ||_||_y)z2 Construct a L{_WrapperEndpoint}. N_wrappedEndpoint_wrapperFactoryr[wrappedEndpointwrapperFactorys r_r`z_WrapperEndpoint.__init__{!0-racv|jj|j|jdS)K Connect the given protocol factory and unwrap its result. c|jSrC)r]rs r_rz*_WrapperEndpoint.connect..s x'?'?ra)rrrrrs r_rz_WrapperEndpoint.connects7$$,,   1 +? @ AraNrrrar_rrus.ArarceZdZdZdZdZy)_WrapperServerEndpointz? A server endpoint that wraps another server endpoint. c ||_||_y)z8 Construct a L{_WrapperServerEndpoint}. Nrrs r_r`z_WrapperServerEndpoint.__init__rracV|jj|j|S)r)rrrrs r_rz_WrapperServerEndpoint.listens&$$++D,@,@,QRRraNrrrar_rrs.SrarcDt tdt|fdS)a Wrap an endpoint which upgrades to TLS as soon as the connection is established. @since: 16.0 @param connectionCreator: The TLS options to use when connecting; see L{twisted.internet.ssl.optionsForClientTLS} for how to construct this. @type connectionCreator: L{twisted.internet.interfaces.IOpenSSLClientConnectionCreator} @param wrappedEndpoint: The endpoint to wrap. @type wrappedEndpoint: An L{IStreamClientEndpoint} provider. @return: an endpoint that provides transport level encryption layered on top of C{wrappedEndpoint} @rtype: L{twisted.internet.interfaces.IStreamClientEndpoint} z6OpenSSL not available. Try `pip install twisted[tls]`.ctd|Srr?)rconnectionCreators r_rzwrapClientTLS..s 3 t_! ra)r@NotImplementedErrorr)rrs` r_rQrQs2&"! D     rac | r#tdt| jt|tr|n|j d}t|ts||n|j d}t |}t |}tt|t|t|||t||St|t||||S)a Internal method to construct an endpoint from string parameters. @param reactor: The reactor passed to L{clientFromString}. @param host: The hostname to connect to. @type host: L{bytes} or L{unicode} @param port: The port to connect to. @type port: L{bytes} or L{unicode} @param timeout: For each individual connection attempt, the number of seconds to wait before assuming the connection has failed. @type timeout: L{bytes} or L{unicode} @param bindAddress: The address to which to bind outgoing connections. @type bindAddress: L{bytes} or L{unicode} @param certificate: a string representing a filesystem path to a PEM-encoded certificate. @type certificate: L{bytes} or L{unicode} @param privateKey: a string representing a filesystem path to a PEM-encoded certificate. @type privateKey: L{bytes} or L{unicode} @param endpoint: an optional string endpoint description of an endpoint to wrap; if this is passed then C{host} is used only for certificate verification. @type endpoint: L{bytes} or L{unicode} @return: a client TLS endpoint @rtype: L{IStreamClientEndpoint} z&unrecognized keyword arguments presentzutf-8ro) TypeErrorrkeysrtrKrurLrQr=rdrkrArNr6) rrrrrrr trustRootsrr s r__parseClientTLSrs\@$v{{}BUVVdC(4dkk'.BD k3 ';+>     ( t9D'lG  )*53KL   (+  gz$'7w T  rac$eZdZdZdZedZy)_TLSClientEndpointParserz Stream client endpoint string parser for L{wrapClientTLS} with L{HostnameEndpoint}. @ivar prefix: See L{IStreamClientEndpointStringParserWithReactor.prefix}. tlsc t|g|i|S)a Redirects to another function L{_parseClientTLS}; tricks zope.interface into believing the interface is correctly implemented, since the signature is (C{reactor}, C{*args}, C{**kwargs}). See L{_parseClientTLS} for the specific signature description for this endpoint parser. @param reactor: The reactor passed to L{clientFromString}. @param args: The positional arguments in the endpoint description. @type args: L{tuple} @param kwargs: The named arguments in the endpoint description. @type kwargs: L{dict} @return: a client TLS endpoint @rtype: L{IStreamClientEndpoint} )r)rrr s r_r|z*_TLSClientEndpointParser.parseStreamClient s(w8888raN)rfr~rrrr$r|rrar_rr s F99rar)rr)666rT)z server.pemNNrrNN)s30NNNNN)rrrrritypingrrr unicodedatarzope.interfacerrr constantlyr r incrementalr rr rrrrtwisted.internet.abstractrrtwisted.internet.addressrrrrtwisted.internet.interfacesrrrrrrrrtwisted.internet.protocolr r!r"r#twisted.internet.stdior$r% ImportErrortwisted.internet._resolverr&twisted.internet.deferr'twisted.internet.taskr(twisted.loggerr)twisted.pluginr*r+twisted.pythonr,r-twisted.python.compatr.r/r0twisted.python.componentsr1twisted.python.failurer2twisted.python.filepathr3twisted.python.systemdr4_idnar6r7 OpenSSL.SSLr8r[twisted.internet.sslr9r:r;r<r=r>twisted.protocols.tlsr@_TLSMemoryBIOFactory__all__rSrIStreamServerEndpointrLIProcessTransport IConsumer IPushProducerrrrrOIStreamClientEndpointrMrrCrDrErFr(rNrIrJrGrHrKrrrrrrr;ranger&r%r1r8rFr}rr=rBrLrPrardrkrurwryr{rArPrrrQrrrrar_rs   ++!BB+EE@   XW> 6+-!.)JJ7*,,(/-R/ *N3N3b\/}\/~ Z - -.  / 8  *"6"6 8P8P 1  =8_=8@ E  Z - -.@(@(/@(F Z - -." " /" JM+M*M+M* Z - -., , /, ^ Z - -.F F /F R DD DN Z - -.QYQY/QYh  Z - -.' ' /' T Z - -.4 4 /4 n Z - -.   /  F Z - -.% % /% P Z - -.,#,#/,#^S2D  ZYz W78**9*0 W78@;@;9@;F W78";";9";L    Qx W'TF      F8AF@R F$N78 / 2%P*:6   Q=h.0 Z - -.AA/A* Z - -.SS/S&F  AH WBC99D9cFJK<s$>O+O;+ O87O8;PP