| 1 | # Copyright (c) Twisted Matrix Laboratories. |
|---|
| 2 | # See LICENSE for details. |
|---|
| 3 | |
|---|
| 4 | """ |
|---|
| 5 | Interface documentation. |
|---|
| 6 | |
|---|
| 7 | Maintainer: Itamar Shtull-Trauring |
|---|
| 8 | """ |
|---|
| 9 | |
|---|
| 10 | from zope.interface import Interface, Attribute |
|---|
| 11 | from twisted.python.deprecate import deprecatedModuleAttribute |
|---|
| 12 | from twisted.python.versions import Version |
|---|
| 13 | |
|---|
| 14 | |
|---|
| 15 | class IAddress(Interface): |
|---|
| 16 | """ |
|---|
| 17 | An address, e.g. a TCP C{(host, port)}. |
|---|
| 18 | |
|---|
| 19 | Default implementations are in L{twisted.internet.address}. |
|---|
| 20 | """ |
|---|
| 21 | |
|---|
| 22 | ### Reactor Interfaces |
|---|
| 23 | |
|---|
| 24 | class IConnector(Interface): |
|---|
| 25 | """ |
|---|
| 26 | Object used to interface between connections and protocols. |
|---|
| 27 | |
|---|
| 28 | Each L{IConnector} manages one connection. |
|---|
| 29 | """ |
|---|
| 30 | |
|---|
| 31 | def stopConnecting(): |
|---|
| 32 | """ |
|---|
| 33 | Stop attempting to connect. |
|---|
| 34 | """ |
|---|
| 35 | |
|---|
| 36 | def disconnect(): |
|---|
| 37 | """ |
|---|
| 38 | Disconnect regardless of the connection state. |
|---|
| 39 | |
|---|
| 40 | If we are connected, disconnect, if we are trying to connect, |
|---|
| 41 | stop trying. |
|---|
| 42 | """ |
|---|
| 43 | |
|---|
| 44 | def connect(): |
|---|
| 45 | """ |
|---|
| 46 | Try to connect to remote address. |
|---|
| 47 | """ |
|---|
| 48 | |
|---|
| 49 | def getDestination(): |
|---|
| 50 | """ |
|---|
| 51 | Return destination this will try to connect to. |
|---|
| 52 | |
|---|
| 53 | @return: An object which provides L{IAddress}. |
|---|
| 54 | """ |
|---|
| 55 | |
|---|
| 56 | |
|---|
| 57 | class IResolverSimple(Interface): |
|---|
| 58 | |
|---|
| 59 | def getHostByName(name, timeout = (1, 3, 11, 45)): |
|---|
| 60 | """ |
|---|
| 61 | Resolve the domain name C{name} into an IP address. |
|---|
| 62 | |
|---|
| 63 | @type name: C{str} |
|---|
| 64 | @type timeout: C{tuple} |
|---|
| 65 | @rtype: L{twisted.internet.defer.Deferred} |
|---|
| 66 | @return: The callback of the Deferred that is returned will be |
|---|
| 67 | passed a string that represents the IP address of the specified |
|---|
| 68 | name, or the errback will be called if the lookup times out. If |
|---|
| 69 | multiple types of address records are associated with the name, |
|---|
| 70 | A6 records will be returned in preference to AAAA records, which |
|---|
| 71 | will be returned in preference to A records. If there are multiple |
|---|
| 72 | records of the type to be returned, one will be selected at random. |
|---|
| 73 | |
|---|
| 74 | @raise twisted.internet.defer.TimeoutError: Raised (asynchronously) |
|---|
| 75 | if the name cannot be resolved within the specified timeout period. |
|---|
| 76 | """ |
|---|
| 77 | |
|---|
| 78 | class IResolver(IResolverSimple): |
|---|
| 79 | def lookupRecord(name, cls, type, timeout = 10): |
|---|
| 80 | """ |
|---|
| 81 | Lookup the records associated with the given name |
|---|
| 82 | that are of the given type and in the given class. |
|---|
| 83 | """ |
|---|
| 84 | |
|---|
| 85 | def query(query, timeout = 10): |
|---|
| 86 | """ |
|---|
| 87 | Interpret and dispatch a query object to the appropriate |
|---|
| 88 | lookup* method. |
|---|
| 89 | """ |
|---|
| 90 | |
|---|
| 91 | def lookupAddress(name, timeout = 10): |
|---|
| 92 | """ |
|---|
| 93 | Lookup the A records associated with C{name}. |
|---|
| 94 | """ |
|---|
| 95 | |
|---|
| 96 | def lookupAddress6(name, timeout = 10): |
|---|
| 97 | """ |
|---|
| 98 | Lookup all the A6 records associated with C{name}. |
|---|
| 99 | """ |
|---|
| 100 | |
|---|
| 101 | def lookupIPV6Address(name, timeout = 10): |
|---|
| 102 | """ |
|---|
| 103 | Lookup all the AAAA records associated with C{name}. |
|---|
| 104 | """ |
|---|
| 105 | |
|---|
| 106 | def lookupMailExchange(name, timeout = 10): |
|---|
| 107 | """ |
|---|
| 108 | Lookup the MX records associated with C{name}. |
|---|
| 109 | """ |
|---|
| 110 | |
|---|
| 111 | def lookupNameservers(name, timeout = 10): |
|---|
| 112 | """ |
|---|
| 113 | Lookup the the NS records associated with C{name}. |
|---|
| 114 | """ |
|---|
| 115 | |
|---|
| 116 | def lookupCanonicalName(name, timeout = 10): |
|---|
| 117 | """ |
|---|
| 118 | Lookup the CNAME records associated with C{name}. |
|---|
| 119 | """ |
|---|
| 120 | |
|---|
| 121 | def lookupMailBox(name, timeout = 10): |
|---|
| 122 | """ |
|---|
| 123 | Lookup the MB records associated with C{name}. |
|---|
| 124 | """ |
|---|
| 125 | |
|---|
| 126 | def lookupMailGroup(name, timeout = 10): |
|---|
| 127 | """ |
|---|
| 128 | Lookup the MG records associated with C{name}. |
|---|
| 129 | """ |
|---|
| 130 | |
|---|
| 131 | def lookupMailRename(name, timeout = 10): |
|---|
| 132 | """ |
|---|
| 133 | Lookup the MR records associated with C{name}. |
|---|
| 134 | """ |
|---|
| 135 | |
|---|
| 136 | def lookupPointer(name, timeout = 10): |
|---|
| 137 | """ |
|---|
| 138 | Lookup the PTR records associated with C{name}. |
|---|
| 139 | """ |
|---|
| 140 | |
|---|
| 141 | def lookupAuthority(name, timeout = 10): |
|---|
| 142 | """ |
|---|
| 143 | Lookup the SOA records associated with C{name}. |
|---|
| 144 | """ |
|---|
| 145 | |
|---|
| 146 | def lookupNull(name, timeout = 10): |
|---|
| 147 | """ |
|---|
| 148 | Lookup the NULL records associated with C{name}. |
|---|
| 149 | """ |
|---|
| 150 | |
|---|
| 151 | def lookupWellKnownServices(name, timeout = 10): |
|---|
| 152 | """ |
|---|
| 153 | Lookup the WKS records associated with C{name}. |
|---|
| 154 | """ |
|---|
| 155 | |
|---|
| 156 | def lookupHostInfo(name, timeout = 10): |
|---|
| 157 | """ |
|---|
| 158 | Lookup the HINFO records associated with C{name}. |
|---|
| 159 | """ |
|---|
| 160 | |
|---|
| 161 | def lookupMailboxInfo(name, timeout = 10): |
|---|
| 162 | """ |
|---|
| 163 | Lookup the MINFO records associated with C{name}. |
|---|
| 164 | """ |
|---|
| 165 | |
|---|
| 166 | def lookupText(name, timeout = 10): |
|---|
| 167 | """ |
|---|
| 168 | Lookup the TXT records associated with C{name}. |
|---|
| 169 | """ |
|---|
| 170 | |
|---|
| 171 | def lookupResponsibility(name, timeout = 10): |
|---|
| 172 | """ |
|---|
| 173 | Lookup the RP records associated with C{name}. |
|---|
| 174 | """ |
|---|
| 175 | |
|---|
| 176 | def lookupAFSDatabase(name, timeout = 10): |
|---|
| 177 | """ |
|---|
| 178 | Lookup the AFSDB records associated with C{name}. |
|---|
| 179 | """ |
|---|
| 180 | |
|---|
| 181 | def lookupService(name, timeout = 10): |
|---|
| 182 | """ |
|---|
| 183 | Lookup the SRV records associated with C{name}. |
|---|
| 184 | """ |
|---|
| 185 | |
|---|
| 186 | def lookupAllRecords(name, timeout = 10): |
|---|
| 187 | """ |
|---|
| 188 | Lookup all records associated with C{name}. |
|---|
| 189 | """ |
|---|
| 190 | |
|---|
| 191 | def lookupZone(name, timeout = 10): |
|---|
| 192 | """ |
|---|
| 193 | Perform a zone transfer for the given C{name}. |
|---|
| 194 | """ |
|---|
| 195 | |
|---|
| 196 | |
|---|
| 197 | |
|---|
| 198 | class IReactorArbitrary(Interface): |
|---|
| 199 | """ |
|---|
| 200 | This interface is redundant with L{IReactorFDSet} and is deprecated. |
|---|
| 201 | """ |
|---|
| 202 | deprecatedModuleAttribute( |
|---|
| 203 | Version("Twisted", 10, 1, 0), |
|---|
| 204 | "See IReactorFDSet.", |
|---|
| 205 | __name__, |
|---|
| 206 | "IReactorArbitrary") |
|---|
| 207 | |
|---|
| 208 | |
|---|
| 209 | def listenWith(portType, *args, **kw): |
|---|
| 210 | """ |
|---|
| 211 | Start an instance of the given C{portType} listening. |
|---|
| 212 | |
|---|
| 213 | @type portType: type which implements L{IListeningPort} |
|---|
| 214 | |
|---|
| 215 | @param portType: The object given by C{portType(*args, **kw)} will be |
|---|
| 216 | started listening. |
|---|
| 217 | |
|---|
| 218 | @return: an object which provides L{IListeningPort}. |
|---|
| 219 | """ |
|---|
| 220 | |
|---|
| 221 | |
|---|
| 222 | def connectWith(connectorType, *args, **kw): |
|---|
| 223 | """ |
|---|
| 224 | Start an instance of the given C{connectorType} connecting. |
|---|
| 225 | |
|---|
| 226 | @type connectorType: type which implements L{IConnector} |
|---|
| 227 | |
|---|
| 228 | @param connectorType: The object given by C{connectorType(*args, **kw)} |
|---|
| 229 | will be started connecting. |
|---|
| 230 | |
|---|
| 231 | @return: An object which provides L{IConnector}. |
|---|
| 232 | """ |
|---|
| 233 | |
|---|
| 234 | # Alias for IReactorArbitrary so that internal Twisted code can continue to |
|---|
| 235 | # provide the interface without emitting a deprecation warning. This can be |
|---|
| 236 | # removed when IReactorArbitrary is removed. |
|---|
| 237 | _IReactorArbitrary = IReactorArbitrary |
|---|
| 238 | |
|---|
| 239 | |
|---|
| 240 | |
|---|
| 241 | class IReactorTCP(Interface): |
|---|
| 242 | |
|---|
| 243 | def listenTCP(port, factory, backlog=50, interface=''): |
|---|
| 244 | """ |
|---|
| 245 | Connects a given protocol factory to the given numeric TCP/IP port. |
|---|
| 246 | |
|---|
| 247 | @param port: a port number on which to listen |
|---|
| 248 | |
|---|
| 249 | @param factory: a L{twisted.internet.protocol.ServerFactory} instance |
|---|
| 250 | |
|---|
| 251 | @param backlog: size of the listen queue |
|---|
| 252 | |
|---|
| 253 | @param interface: The local IPv4 or IPv6 address to which to bind; |
|---|
| 254 | defaults to '', ie all IPv4 addresses. To bind to all IPv4 and IPv6 |
|---|
| 255 | addresses, you must call this method twice. |
|---|
| 256 | |
|---|
| 257 | @return: an object that provides L{IListeningPort}. |
|---|
| 258 | |
|---|
| 259 | @raise CannotListenError: as defined here |
|---|
| 260 | L{twisted.internet.error.CannotListenError}, |
|---|
| 261 | if it cannot listen on this port (e.g., it |
|---|
| 262 | cannot bind to the required port number) |
|---|
| 263 | """ |
|---|
| 264 | |
|---|
| 265 | def connectTCP(host, port, factory, timeout=30, bindAddress=None): |
|---|
| 266 | """ |
|---|
| 267 | Connect a TCP client. |
|---|
| 268 | |
|---|
| 269 | @param host: a host name |
|---|
| 270 | |
|---|
| 271 | @param port: a port number |
|---|
| 272 | |
|---|
| 273 | @param factory: a L{twisted.internet.protocol.ClientFactory} instance |
|---|
| 274 | |
|---|
| 275 | @param timeout: number of seconds to wait before assuming the |
|---|
| 276 | connection has failed. |
|---|
| 277 | |
|---|
| 278 | @param bindAddress: a (host, port) tuple of local address to bind |
|---|
| 279 | to, or None. |
|---|
| 280 | |
|---|
| 281 | @return: An object which provides L{IConnector}. This connector will |
|---|
| 282 | call various callbacks on the factory when a connection is |
|---|
| 283 | made, failed, or lost - see |
|---|
| 284 | L{ClientFactory<twisted.internet.protocol.ClientFactory>} |
|---|
| 285 | docs for details. |
|---|
| 286 | """ |
|---|
| 287 | |
|---|
| 288 | class IReactorSSL(Interface): |
|---|
| 289 | |
|---|
| 290 | def connectSSL(host, port, factory, contextFactory, timeout=30, bindAddress=None): |
|---|
| 291 | """ |
|---|
| 292 | Connect a client Protocol to a remote SSL socket. |
|---|
| 293 | |
|---|
| 294 | @param host: a host name |
|---|
| 295 | |
|---|
| 296 | @param port: a port number |
|---|
| 297 | |
|---|
| 298 | @param factory: a L{twisted.internet.protocol.ClientFactory} instance |
|---|
| 299 | |
|---|
| 300 | @param contextFactory: a L{twisted.internet.ssl.ClientContextFactory} object. |
|---|
| 301 | |
|---|
| 302 | @param timeout: number of seconds to wait before assuming the |
|---|
| 303 | connection has failed. |
|---|
| 304 | |
|---|
| 305 | @param bindAddress: a (host, port) tuple of local address to bind to, |
|---|
| 306 | or C{None}. |
|---|
| 307 | |
|---|
| 308 | @return: An object which provides L{IConnector}. |
|---|
| 309 | """ |
|---|
| 310 | |
|---|
| 311 | def listenSSL(port, factory, contextFactory, backlog=50, interface=''): |
|---|
| 312 | """ |
|---|
| 313 | Connects a given protocol factory to the given numeric TCP/IP port. |
|---|
| 314 | The connection is a SSL one, using contexts created by the context |
|---|
| 315 | factory. |
|---|
| 316 | |
|---|
| 317 | @param port: a port number on which to listen |
|---|
| 318 | |
|---|
| 319 | @param factory: a L{twisted.internet.protocol.ServerFactory} instance |
|---|
| 320 | |
|---|
| 321 | @param contextFactory: a L{twisted.internet.ssl.ContextFactory} instance |
|---|
| 322 | |
|---|
| 323 | @param backlog: size of the listen queue |
|---|
| 324 | |
|---|
| 325 | @param interface: the hostname to bind to, defaults to '' (all) |
|---|
| 326 | """ |
|---|
| 327 | |
|---|
| 328 | |
|---|
| 329 | |
|---|
| 330 | class IReactorUNIX(Interface): |
|---|
| 331 | """ |
|---|
| 332 | UNIX socket methods. |
|---|
| 333 | """ |
|---|
| 334 | |
|---|
| 335 | def connectUNIX(address, factory, timeout=30, checkPID=0): |
|---|
| 336 | """ |
|---|
| 337 | Connect a client protocol to a UNIX socket. |
|---|
| 338 | |
|---|
| 339 | @param address: a path to a unix socket on the filesystem. |
|---|
| 340 | |
|---|
| 341 | @param factory: a L{twisted.internet.protocol.ClientFactory} instance |
|---|
| 342 | |
|---|
| 343 | @param timeout: number of seconds to wait before assuming the connection |
|---|
| 344 | has failed. |
|---|
| 345 | |
|---|
| 346 | @param checkPID: if True, check for a pid file to verify that a server |
|---|
| 347 | is listening. If C{address} is a Linux abstract namespace path, |
|---|
| 348 | this must be C{False}. |
|---|
| 349 | |
|---|
| 350 | @return: An object which provides L{IConnector}. |
|---|
| 351 | """ |
|---|
| 352 | |
|---|
| 353 | |
|---|
| 354 | def listenUNIX(address, factory, backlog=50, mode=0666, wantPID=0): |
|---|
| 355 | """ |
|---|
| 356 | Listen on a UNIX socket. |
|---|
| 357 | |
|---|
| 358 | @param address: a path to a unix socket on the filesystem. |
|---|
| 359 | |
|---|
| 360 | @param factory: a L{twisted.internet.protocol.Factory} instance. |
|---|
| 361 | |
|---|
| 362 | @param backlog: number of connections to allow in backlog. |
|---|
| 363 | |
|---|
| 364 | @param mode: The mode (B{not} umask) to set on the unix socket. See |
|---|
| 365 | platform specific documentation for information about how this |
|---|
| 366 | might affect connection attempts. |
|---|
| 367 | @type mode: C{int} |
|---|
| 368 | |
|---|
| 369 | @param wantPID: if True, create a pidfile for the socket. If C{address} |
|---|
| 370 | is a Linux abstract namespace path, this must be C{False}. |
|---|
| 371 | |
|---|
| 372 | @return: An object which provides L{IListeningPort}. |
|---|
| 373 | """ |
|---|
| 374 | |
|---|
| 375 | |
|---|
| 376 | |
|---|
| 377 | class IReactorUNIXDatagram(Interface): |
|---|
| 378 | """ |
|---|
| 379 | Datagram UNIX socket methods. |
|---|
| 380 | """ |
|---|
| 381 | |
|---|
| 382 | def connectUNIXDatagram(address, protocol, maxPacketSize=8192, mode=0666, bindAddress=None): |
|---|
| 383 | """ |
|---|
| 384 | Connect a client protocol to a datagram UNIX socket. |
|---|
| 385 | |
|---|
| 386 | @param address: a path to a unix socket on the filesystem. |
|---|
| 387 | |
|---|
| 388 | @param protocol: a L{twisted.internet.protocol.ConnectedDatagramProtocol} instance |
|---|
| 389 | |
|---|
| 390 | @param maxPacketSize: maximum packet size to accept |
|---|
| 391 | |
|---|
| 392 | @param mode: The mode (B{not} umask) to set on the unix socket. See |
|---|
| 393 | platform specific documentation for information about how this |
|---|
| 394 | might affect connection attempts. |
|---|
| 395 | @type mode: C{int} |
|---|
| 396 | |
|---|
| 397 | @param bindAddress: address to bind to |
|---|
| 398 | |
|---|
| 399 | @return: An object which provides L{IConnector}. |
|---|
| 400 | """ |
|---|
| 401 | |
|---|
| 402 | |
|---|
| 403 | def listenUNIXDatagram(address, protocol, maxPacketSize=8192, mode=0666): |
|---|
| 404 | """ |
|---|
| 405 | Listen on a datagram UNIX socket. |
|---|
| 406 | |
|---|
| 407 | @param address: a path to a unix socket on the filesystem. |
|---|
| 408 | |
|---|
| 409 | @param protocol: a L{twisted.internet.protocol.DatagramProtocol} instance. |
|---|
| 410 | |
|---|
| 411 | @param maxPacketSize: maximum packet size to accept |
|---|
| 412 | |
|---|
| 413 | @param mode: The mode (B{not} umask) to set on the unix socket. See |
|---|
| 414 | platform specific documentation for information about how this |
|---|
| 415 | might affect connection attempts. |
|---|
| 416 | @type mode: C{int} |
|---|
| 417 | |
|---|
| 418 | @return: An object which provides L{IListeningPort}. |
|---|
| 419 | """ |
|---|
| 420 | |
|---|
| 421 | |
|---|
| 422 | |
|---|
| 423 | class IReactorWin32Events(Interface): |
|---|
| 424 | """ |
|---|
| 425 | Win32 Event API methods |
|---|
| 426 | |
|---|
| 427 | @since: 10.2 |
|---|
| 428 | """ |
|---|
| 429 | |
|---|
| 430 | def addEvent(event, fd, action): |
|---|
| 431 | """ |
|---|
| 432 | Add a new win32 event to the event loop. |
|---|
| 433 | |
|---|
| 434 | @param event: a Win32 event object created using win32event.CreateEvent() |
|---|
| 435 | |
|---|
| 436 | @param fd: an instance of L{twisted.internet.abstract.FileDescriptor} |
|---|
| 437 | |
|---|
| 438 | @param action: a string that is a method name of the fd instance. |
|---|
| 439 | This method is called in response to the event. |
|---|
| 440 | |
|---|
| 441 | @return: None |
|---|
| 442 | """ |
|---|
| 443 | |
|---|
| 444 | |
|---|
| 445 | def removeEvent(event): |
|---|
| 446 | """ |
|---|
| 447 | Remove an event. |
|---|
| 448 | |
|---|
| 449 | @param event: a Win32 event object added using L{IReactorWin32Events.addEvent} |
|---|
| 450 | |
|---|
| 451 | @return: None |
|---|
| 452 | """ |
|---|
| 453 | |
|---|
| 454 | |
|---|
| 455 | |
|---|
| 456 | class IReactorUDP(Interface): |
|---|
| 457 | """ |
|---|
| 458 | UDP socket methods. |
|---|
| 459 | """ |
|---|
| 460 | |
|---|
| 461 | def listenUDP(port, protocol, interface='', maxPacketSize=8192): |
|---|
| 462 | """ |
|---|
| 463 | Connects a given DatagramProtocol to the given numeric UDP port. |
|---|
| 464 | |
|---|
| 465 | @return: object which provides L{IListeningPort}. |
|---|
| 466 | """ |
|---|
| 467 | |
|---|
| 468 | |
|---|
| 469 | |
|---|
| 470 | class IReactorMulticast(Interface): |
|---|
| 471 | """ |
|---|
| 472 | UDP socket methods that support multicast. |
|---|
| 473 | |
|---|
| 474 | IMPORTANT: This is an experimental new interface. It may change |
|---|
| 475 | without backwards compatability. Suggestions are welcome. |
|---|
| 476 | """ |
|---|
| 477 | |
|---|
| 478 | def listenMulticast(port, protocol, interface='', maxPacketSize=8192, |
|---|
| 479 | listenMultiple=False): |
|---|
| 480 | """ |
|---|
| 481 | Connects a given |
|---|
| 482 | L{DatagramProtocol<twisted.internet.protocol.DatagramProtocol>} to the |
|---|
| 483 | given numeric UDP port. |
|---|
| 484 | |
|---|
| 485 | @param listenMultiple: If set to True, allows multiple sockets to |
|---|
| 486 | bind to the same address and port number at the same time. |
|---|
| 487 | @type listenMultiple: C{bool} |
|---|
| 488 | |
|---|
| 489 | @returns: An object which provides L{IListeningPort}. |
|---|
| 490 | |
|---|
| 491 | @see: L{twisted.internet.interfaces.IMulticastTransport} |
|---|
| 492 | @see: U{http://twistedmatrix.com/documents/current/core/howto/udp.html} |
|---|
| 493 | """ |
|---|
| 494 | |
|---|
| 495 | |
|---|
| 496 | |
|---|
| 497 | class IReactorSocket(Interface): |
|---|
| 498 | """ |
|---|
| 499 | Methods which allow a reactor to use externally created sockets. |
|---|
| 500 | |
|---|
| 501 | For example, to use C{adoptStreamPort} to implement behavior equivalent |
|---|
| 502 | to that of L{IReactorTCP.listenTCP}, you might write code like this:: |
|---|
| 503 | |
|---|
| 504 | from socket import SOMAXCONN, AF_INET, SOCK_STREAM, socket |
|---|
| 505 | portSocket = socket(AF_INET, SOCK_STREAM) |
|---|
| 506 | # Set FD_CLOEXEC on port, left as an exercise. Then make it into a |
|---|
| 507 | # non-blocking listening port: |
|---|
| 508 | portSocket.setblocking(False) |
|---|
| 509 | portSocket.bind(('192.168.1.2', 12345)) |
|---|
| 510 | portSocket.listen(SOMAXCONN) |
|---|
| 511 | |
|---|
| 512 | # Now have the reactor use it as a TCP port |
|---|
| 513 | port = reactor.adoptStreamPort( |
|---|
| 514 | portSocket.fileno(), AF_INET, YourFactory()) |
|---|
| 515 | |
|---|
| 516 | # portSocket itself is no longer necessary, and needs to be cleaned |
|---|
| 517 | # up by us. |
|---|
| 518 | portSocket.close() |
|---|
| 519 | |
|---|
| 520 | # Whenever the server is no longer needed, stop it as usual. |
|---|
| 521 | stoppedDeferred = port.stopListening() |
|---|
| 522 | |
|---|
| 523 | Another potential use is to inherit a listening descriptor from a parent |
|---|
| 524 | process (for example, systemd or launchd), or to receive one over a UNIX |
|---|
| 525 | domain socket. |
|---|
| 526 | |
|---|
| 527 | Some plans for extending this interface exist. See: |
|---|
| 528 | |
|---|
| 529 | - U{http://twistedmatrix.com/trac/ticket/5570}: established connections |
|---|
| 530 | - U{http://twistedmatrix.com/trac/ticket/5573}: AF_UNIX ports |
|---|
| 531 | - U{http://twistedmatrix.com/trac/ticket/5574}: SOCK_DGRAM sockets |
|---|
| 532 | """ |
|---|
| 533 | |
|---|
| 534 | def adoptStreamPort(fileDescriptor, addressFamily, factory): |
|---|
| 535 | """ |
|---|
| 536 | Add an existing listening I{SOCK_STREAM} socket to the reactor to |
|---|
| 537 | monitor for new connections to accept and handle. |
|---|
| 538 | @param fileDescriptor: A file descriptor associated with a socket which |
|---|
| 539 | is already bound to an address and marked as listening. The socket |
|---|
| 540 | must be set non-blocking. Any additional flags (for example, |
|---|
| 541 | close-on-exec) must also be set by application code. Application |
|---|
| 542 | code is responsible for closing the file descriptor, which may be |
|---|
| 543 | done as soon as C{adoptStreamPort} returns. |
|---|
| 544 | @type fileDescriptor: C{int} |
|---|
| 545 | |
|---|
| 546 | @param addressFamily: The address family (or I{domain}) of the socket. |
|---|
| 547 | For example, L{socket.AF_INET6}. |
|---|
| 548 | |
|---|
| 549 | @param factory: A L{ServerFactory} instance to use to create new |
|---|
| 550 | protocols to handle connections accepted via this socket. |
|---|
| 551 | |
|---|
| 552 | @return: An object providing L{IListeningPort}. |
|---|
| 553 | |
|---|
| 554 | @raise UnsupportedAddressFamily: If the given address family is not |
|---|
| 555 | supported by this reactor, or not supported with the given socket |
|---|
| 556 | type. |
|---|
| 557 | |
|---|
| 558 | @raise UnsupportedSocketType: If the given socket type is not supported |
|---|
| 559 | by this reactor, or not supported with the given socket type. |
|---|
| 560 | """ |
|---|
| 561 | |
|---|
| 562 | |
|---|
| 563 | |
|---|
| 564 | class IReactorProcess(Interface): |
|---|
| 565 | |
|---|
| 566 | def spawnProcess(processProtocol, executable, args=(), env={}, path=None, |
|---|
| 567 | uid=None, gid=None, usePTY=0, childFDs=None): |
|---|
| 568 | """ |
|---|
| 569 | Spawn a process, with a process protocol. |
|---|
| 570 | |
|---|
| 571 | @type processProtocol: L{IProcessProtocol} provider |
|---|
| 572 | @param processProtocol: An object which will be notified of all |
|---|
| 573 | events related to the created process. |
|---|
| 574 | |
|---|
| 575 | @param executable: the file name to spawn - the full path should be |
|---|
| 576 | used. |
|---|
| 577 | |
|---|
| 578 | @param args: the command line arguments to pass to the process; a |
|---|
| 579 | sequence of strings. The first string should be the |
|---|
| 580 | executable's name. |
|---|
| 581 | |
|---|
| 582 | @type env: a C{dict} mapping C{str} to C{str}, or C{None}. |
|---|
| 583 | @param env: the environment variables to pass to the child process. The |
|---|
| 584 | resulting behavior varies between platforms. If |
|---|
| 585 | - C{env} is not set: |
|---|
| 586 | - On POSIX: pass an empty environment. |
|---|
| 587 | - On Windows: pass C{os.environ}. |
|---|
| 588 | - C{env} is C{None}: |
|---|
| 589 | - On POSIX: pass C{os.environ}. |
|---|
| 590 | - On Windows: pass C{os.environ}. |
|---|
| 591 | - C{env} is a C{dict}: |
|---|
| 592 | - On POSIX: pass the key/value pairs in C{env} as the |
|---|
| 593 | complete environment. |
|---|
| 594 | - On Windows: update C{os.environ} with the key/value |
|---|
| 595 | pairs in the C{dict} before passing it. As a |
|---|
| 596 | consequence of U{bug #1640 |
|---|
| 597 | <http://twistedmatrix.com/trac/ticket/1640>}, passing |
|---|
| 598 | keys with empty values in an effort to unset |
|---|
| 599 | environment variables I{won't} unset them. |
|---|
| 600 | |
|---|
| 601 | @param path: the path to run the subprocess in - defaults to the |
|---|
| 602 | current directory. |
|---|
| 603 | |
|---|
| 604 | @param uid: user ID to run the subprocess as. (Only available on |
|---|
| 605 | POSIX systems.) |
|---|
| 606 | |
|---|
| 607 | @param gid: group ID to run the subprocess as. (Only available on |
|---|
| 608 | POSIX systems.) |
|---|
| 609 | |
|---|
| 610 | @param usePTY: if true, run this process in a pseudo-terminal. |
|---|
| 611 | optionally a tuple of C{(masterfd, slavefd, ttyname)}, |
|---|
| 612 | in which case use those file descriptors. |
|---|
| 613 | (Not available on all systems.) |
|---|
| 614 | |
|---|
| 615 | @param childFDs: A dictionary mapping file descriptors in the new child |
|---|
| 616 | process to an integer or to the string 'r' or 'w'. |
|---|
| 617 | |
|---|
| 618 | If the value is an integer, it specifies a file |
|---|
| 619 | descriptor in the parent process which will be mapped |
|---|
| 620 | to a file descriptor (specified by the key) in the |
|---|
| 621 | child process. This is useful for things like inetd |
|---|
| 622 | and shell-like file redirection. |
|---|
| 623 | |
|---|
| 624 | If it is the string 'r', a pipe will be created and |
|---|
| 625 | attached to the child at that file descriptor: the |
|---|
| 626 | child will be able to write to that file descriptor |
|---|
| 627 | and the parent will receive read notification via the |
|---|
| 628 | L{IProcessProtocol.childDataReceived} callback. This |
|---|
| 629 | is useful for the child's stdout and stderr. |
|---|
| 630 | |
|---|
| 631 | If it is the string 'w', similar setup to the previous |
|---|
| 632 | case will occur, with the pipe being readable by the |
|---|
| 633 | child instead of writeable. The parent process can |
|---|
| 634 | write to that file descriptor using |
|---|
| 635 | L{IProcessTransport.writeToChild}. This is useful for |
|---|
| 636 | the child's stdin. |
|---|
| 637 | |
|---|
| 638 | If childFDs is not passed, the default behaviour is to |
|---|
| 639 | use a mapping that opens the usual stdin/stdout/stderr |
|---|
| 640 | pipes. |
|---|
| 641 | |
|---|
| 642 | @see: L{twisted.internet.protocol.ProcessProtocol} |
|---|
| 643 | |
|---|
| 644 | @return: An object which provides L{IProcessTransport}. |
|---|
| 645 | |
|---|
| 646 | @raise OSError: Raised with errno C{EAGAIN} or C{ENOMEM} if there are |
|---|
| 647 | insufficient system resources to create a new process. |
|---|
| 648 | """ |
|---|
| 649 | |
|---|
| 650 | class IReactorTime(Interface): |
|---|
| 651 | """ |
|---|
| 652 | Time methods that a Reactor should implement. |
|---|
| 653 | """ |
|---|
| 654 | |
|---|
| 655 | def seconds(): |
|---|
| 656 | """ |
|---|
| 657 | Get the current time in seconds. |
|---|
| 658 | |
|---|
| 659 | @return: A number-like object of some sort. |
|---|
| 660 | """ |
|---|
| 661 | |
|---|
| 662 | |
|---|
| 663 | def callLater(delay, callable, *args, **kw): |
|---|
| 664 | """ |
|---|
| 665 | Call a function later. |
|---|
| 666 | |
|---|
| 667 | @type delay: C{float} |
|---|
| 668 | @param delay: the number of seconds to wait. |
|---|
| 669 | |
|---|
| 670 | @param callable: the callable object to call later. |
|---|
| 671 | |
|---|
| 672 | @param args: the arguments to call it with. |
|---|
| 673 | |
|---|
| 674 | @param kw: the keyword arguments to call it with. |
|---|
| 675 | |
|---|
| 676 | @return: An object which provides L{IDelayedCall} and can be used to |
|---|
| 677 | cancel the scheduled call, by calling its C{cancel()} method. |
|---|
| 678 | It also may be rescheduled by calling its C{delay()} or |
|---|
| 679 | C{reset()} methods. |
|---|
| 680 | """ |
|---|
| 681 | |
|---|
| 682 | |
|---|
| 683 | def getDelayedCalls(): |
|---|
| 684 | """ |
|---|
| 685 | Retrieve all currently scheduled delayed calls. |
|---|
| 686 | |
|---|
| 687 | @return: A tuple of all L{IDelayedCall} providers representing all |
|---|
| 688 | currently scheduled calls. This is everything that has been |
|---|
| 689 | returned by C{callLater} but not yet called or canceled. |
|---|
| 690 | """ |
|---|
| 691 | |
|---|
| 692 | |
|---|
| 693 | class IDelayedCall(Interface): |
|---|
| 694 | """ |
|---|
| 695 | A scheduled call. |
|---|
| 696 | |
|---|
| 697 | There are probably other useful methods we can add to this interface; |
|---|
| 698 | suggestions are welcome. |
|---|
| 699 | """ |
|---|
| 700 | |
|---|
| 701 | def getTime(): |
|---|
| 702 | """ |
|---|
| 703 | Get time when delayed call will happen. |
|---|
| 704 | |
|---|
| 705 | @return: time in seconds since epoch (a float). |
|---|
| 706 | """ |
|---|
| 707 | |
|---|
| 708 | def cancel(): |
|---|
| 709 | """ |
|---|
| 710 | Cancel the scheduled call. |
|---|
| 711 | |
|---|
| 712 | @raises twisted.internet.error.AlreadyCalled: if the call has already |
|---|
| 713 | happened. |
|---|
| 714 | @raises twisted.internet.error.AlreadyCancelled: if the call has already |
|---|
| 715 | been cancelled. |
|---|
| 716 | """ |
|---|
| 717 | |
|---|
| 718 | def delay(secondsLater): |
|---|
| 719 | """ |
|---|
| 720 | Delay the scheduled call. |
|---|
| 721 | |
|---|
| 722 | @param secondsLater: how many seconds from its current firing time to delay |
|---|
| 723 | |
|---|
| 724 | @raises twisted.internet.error.AlreadyCalled: if the call has already |
|---|
| 725 | happened. |
|---|
| 726 | @raises twisted.internet.error.AlreadyCancelled: if the call has already |
|---|
| 727 | been cancelled. |
|---|
| 728 | """ |
|---|
| 729 | |
|---|
| 730 | def reset(secondsFromNow): |
|---|
| 731 | """ |
|---|
| 732 | Reset the scheduled call's timer. |
|---|
| 733 | |
|---|
| 734 | @param secondsFromNow: how many seconds from now it should fire, |
|---|
| 735 | equivalent to C{.cancel()} and then doing another |
|---|
| 736 | C{reactor.callLater(secondsLater, ...)} |
|---|
| 737 | |
|---|
| 738 | @raises twisted.internet.error.AlreadyCalled: if the call has already |
|---|
| 739 | happened. |
|---|
| 740 | @raises twisted.internet.error.AlreadyCancelled: if the call has already |
|---|
| 741 | been cancelled. |
|---|
| 742 | """ |
|---|
| 743 | |
|---|
| 744 | def active(): |
|---|
| 745 | """ |
|---|
| 746 | @return: True if this call is still active, False if it has been |
|---|
| 747 | called or cancelled. |
|---|
| 748 | """ |
|---|
| 749 | |
|---|
| 750 | class IReactorThreads(Interface): |
|---|
| 751 | """ |
|---|
| 752 | Dispatch methods to be run in threads. |
|---|
| 753 | |
|---|
| 754 | Internally, this should use a thread pool and dispatch methods to them. |
|---|
| 755 | """ |
|---|
| 756 | |
|---|
| 757 | def getThreadPool(): |
|---|
| 758 | """ |
|---|
| 759 | Return the threadpool used by L{callInThread}. Create it first if |
|---|
| 760 | necessary. |
|---|
| 761 | |
|---|
| 762 | @rtype: L{twisted.python.threadpool.ThreadPool} |
|---|
| 763 | """ |
|---|
| 764 | |
|---|
| 765 | |
|---|
| 766 | def callInThread(callable, *args, **kwargs): |
|---|
| 767 | """ |
|---|
| 768 | Run the callable object in a separate thread. |
|---|
| 769 | """ |
|---|
| 770 | |
|---|
| 771 | |
|---|
| 772 | def callFromThread(callable, *args, **kw): |
|---|
| 773 | """ |
|---|
| 774 | Cause a function to be executed by the reactor thread. |
|---|
| 775 | |
|---|
| 776 | Use this method when you want to run a function in the reactor's thread |
|---|
| 777 | from another thread. Calling L{callFromThread} should wake up the main |
|---|
| 778 | thread (where L{reactor.run()<reactor.run>} is executing) and run the |
|---|
| 779 | given callable in that thread. |
|---|
| 780 | |
|---|
| 781 | If you're writing a multi-threaded application the C{callable} may need |
|---|
| 782 | to be thread safe, but this method doesn't require it as such. If you |
|---|
| 783 | want to call a function in the next mainloop iteration, but you're in |
|---|
| 784 | the same thread, use L{callLater} with a delay of 0. |
|---|
| 785 | """ |
|---|
| 786 | |
|---|
| 787 | |
|---|
| 788 | def suggestThreadPoolSize(size): |
|---|
| 789 | """ |
|---|
| 790 | Suggest the size of the internal threadpool used to dispatch functions |
|---|
| 791 | passed to L{callInThread}. |
|---|
| 792 | """ |
|---|
| 793 | |
|---|
| 794 | |
|---|
| 795 | class IReactorCore(Interface): |
|---|
| 796 | """ |
|---|
| 797 | Core methods that a Reactor must implement. |
|---|
| 798 | """ |
|---|
| 799 | |
|---|
| 800 | running = Attribute( |
|---|
| 801 | "A C{bool} which is C{True} from I{during startup} to " |
|---|
| 802 | "I{during shutdown} and C{False} the rest of the time.") |
|---|
| 803 | |
|---|
| 804 | |
|---|
| 805 | def resolve(name, timeout=10): |
|---|
| 806 | """ |
|---|
| 807 | Return a L{twisted.internet.defer.Deferred} that will resolve a hostname. |
|---|
| 808 | """ |
|---|
| 809 | |
|---|
| 810 | def run(): |
|---|
| 811 | """ |
|---|
| 812 | Fire 'startup' System Events, move the reactor to the 'running' |
|---|
| 813 | state, then run the main loop until it is stopped with C{stop()} or |
|---|
| 814 | C{crash()}. |
|---|
| 815 | """ |
|---|
| 816 | |
|---|
| 817 | def stop(): |
|---|
| 818 | """ |
|---|
| 819 | Fire 'shutdown' System Events, which will move the reactor to the |
|---|
| 820 | 'stopped' state and cause C{reactor.run()} to exit. |
|---|
| 821 | """ |
|---|
| 822 | |
|---|
| 823 | def crash(): |
|---|
| 824 | """ |
|---|
| 825 | Stop the main loop *immediately*, without firing any system events. |
|---|
| 826 | |
|---|
| 827 | This is named as it is because this is an extremely "rude" thing to do; |
|---|
| 828 | it is possible to lose data and put your system in an inconsistent |
|---|
| 829 | state by calling this. However, it is necessary, as sometimes a system |
|---|
| 830 | can become wedged in a pre-shutdown call. |
|---|
| 831 | """ |
|---|
| 832 | |
|---|
| 833 | def iterate(delay=0): |
|---|
| 834 | """ |
|---|
| 835 | Run the main loop's I/O polling function for a period of time. |
|---|
| 836 | |
|---|
| 837 | This is most useful in applications where the UI is being drawn "as |
|---|
| 838 | fast as possible", such as games. All pending L{IDelayedCall}s will |
|---|
| 839 | be called. |
|---|
| 840 | |
|---|
| 841 | The reactor must have been started (via the C{run()} method) prior to |
|---|
| 842 | any invocations of this method. It must also be stopped manually |
|---|
| 843 | after the last call to this method (via the C{stop()} method). This |
|---|
| 844 | method is not re-entrant: you must not call it recursively; in |
|---|
| 845 | particular, you must not call it while the reactor is running. |
|---|
| 846 | """ |
|---|
| 847 | |
|---|
| 848 | def fireSystemEvent(eventType): |
|---|
| 849 | """ |
|---|
| 850 | Fire a system-wide event. |
|---|
| 851 | |
|---|
| 852 | System-wide events are things like 'startup', 'shutdown', and |
|---|
| 853 | 'persist'. |
|---|
| 854 | """ |
|---|
| 855 | |
|---|
| 856 | def addSystemEventTrigger(phase, eventType, callable, *args, **kw): |
|---|
| 857 | """ |
|---|
| 858 | Add a function to be called when a system event occurs. |
|---|
| 859 | |
|---|
| 860 | Each "system event" in Twisted, such as 'startup', 'shutdown', and |
|---|
| 861 | 'persist', has 3 phases: 'before', 'during', and 'after' (in that |
|---|
| 862 | order, of course). These events will be fired internally by the |
|---|
| 863 | Reactor. |
|---|
| 864 | |
|---|
| 865 | An implementor of this interface must only implement those events |
|---|
| 866 | described here. |
|---|
| 867 | |
|---|
| 868 | Callbacks registered for the "before" phase may return either None or a |
|---|
| 869 | Deferred. The "during" phase will not execute until all of the |
|---|
| 870 | Deferreds from the "before" phase have fired. |
|---|
| 871 | |
|---|
| 872 | Once the "during" phase is running, all of the remaining triggers must |
|---|
| 873 | execute; their return values must be ignored. |
|---|
| 874 | |
|---|
| 875 | @param phase: a time to call the event -- either the string 'before', |
|---|
| 876 | 'after', or 'during', describing when to call it |
|---|
| 877 | relative to the event's execution. |
|---|
| 878 | |
|---|
| 879 | @param eventType: this is a string describing the type of event. |
|---|
| 880 | |
|---|
| 881 | @param callable: the object to call before shutdown. |
|---|
| 882 | |
|---|
| 883 | @param args: the arguments to call it with. |
|---|
| 884 | |
|---|
| 885 | @param kw: the keyword arguments to call it with. |
|---|
| 886 | |
|---|
| 887 | @return: an ID that can be used to remove this call with |
|---|
| 888 | removeSystemEventTrigger. |
|---|
| 889 | """ |
|---|
| 890 | |
|---|
| 891 | def removeSystemEventTrigger(triggerID): |
|---|
| 892 | """ |
|---|
| 893 | Removes a trigger added with addSystemEventTrigger. |
|---|
| 894 | |
|---|
| 895 | @param triggerID: a value returned from addSystemEventTrigger. |
|---|
| 896 | |
|---|
| 897 | @raise KeyError: If there is no system event trigger for the given |
|---|
| 898 | C{triggerID}. |
|---|
| 899 | |
|---|
| 900 | @raise ValueError: If there is no system event trigger for the given |
|---|
| 901 | C{triggerID}. |
|---|
| 902 | |
|---|
| 903 | @raise TypeError: If there is no system event trigger for the given |
|---|
| 904 | C{triggerID}. |
|---|
| 905 | """ |
|---|
| 906 | |
|---|
| 907 | def callWhenRunning(callable, *args, **kw): |
|---|
| 908 | """ |
|---|
| 909 | Call a function when the reactor is running. |
|---|
| 910 | |
|---|
| 911 | If the reactor has not started, the callable will be scheduled |
|---|
| 912 | to run when it does start. Otherwise, the callable will be invoked |
|---|
| 913 | immediately. |
|---|
| 914 | |
|---|
| 915 | @param callable: the callable object to call later. |
|---|
| 916 | |
|---|
| 917 | @param args: the arguments to call it with. |
|---|
| 918 | |
|---|
| 919 | @param kw: the keyword arguments to call it with. |
|---|
| 920 | |
|---|
| 921 | @return: None if the callable was invoked, otherwise a system |
|---|
| 922 | event id for the scheduled call. |
|---|
| 923 | """ |
|---|
| 924 | |
|---|
| 925 | |
|---|
| 926 | class IReactorPluggableResolver(Interface): |
|---|
| 927 | """ |
|---|
| 928 | A reactor with a pluggable name resolver interface. |
|---|
| 929 | """ |
|---|
| 930 | |
|---|
| 931 | def installResolver(resolver): |
|---|
| 932 | """ |
|---|
| 933 | Set the internal resolver to use to for name lookups. |
|---|
| 934 | |
|---|
| 935 | @type resolver: An object implementing the L{IResolverSimple} interface |
|---|
| 936 | @param resolver: The new resolver to use. |
|---|
| 937 | |
|---|
| 938 | @return: The previously installed resolver. |
|---|
| 939 | """ |
|---|
| 940 | |
|---|
| 941 | |
|---|
| 942 | class IReactorDaemonize(Interface): |
|---|
| 943 | """ |
|---|
| 944 | A reactor which provides hooks that need to be called before and after |
|---|
| 945 | daemonization. |
|---|
| 946 | |
|---|
| 947 | Notes: |
|---|
| 948 | - This interface SHOULD NOT be called by applications. |
|---|
| 949 | - This interface should only be implemented by reactors as a workaround |
|---|
| 950 | (in particular, it's implemented currently only by kqueue()). |
|---|
| 951 | For details please see the comments on ticket #1918. |
|---|
| 952 | """ |
|---|
| 953 | |
|---|
| 954 | def beforeDaemonize(): |
|---|
| 955 | """ |
|---|
| 956 | Hook to be called immediately before daemonization. No reactor methods |
|---|
| 957 | may be called until L{afterDaemonize} is called. |
|---|
| 958 | |
|---|
| 959 | @return: C{None}. |
|---|
| 960 | """ |
|---|
| 961 | |
|---|
| 962 | |
|---|
| 963 | def afterDaemonize(): |
|---|
| 964 | """ |
|---|
| 965 | Hook to be called immediately after daemonization. This may only be |
|---|
| 966 | called after L{beforeDaemonize} had been called previously. |
|---|
| 967 | |
|---|
| 968 | @return: C{None}. |
|---|
| 969 | """ |
|---|
| 970 | |
|---|
| 971 | |
|---|
| 972 | |
|---|
| 973 | class IReactorFDSet(Interface): |
|---|
| 974 | """ |
|---|
| 975 | Implement me to be able to use L{IFileDescriptor} type resources. |
|---|
| 976 | |
|---|
| 977 | This assumes that your main-loop uses UNIX-style numeric file descriptors |
|---|
| 978 | (or at least similarly opaque IDs returned from a .fileno() method) |
|---|
| 979 | """ |
|---|
| 980 | |
|---|
| 981 | def addReader(reader): |
|---|
| 982 | """ |
|---|
| 983 | I add reader to the set of file descriptors to get read events for. |
|---|
| 984 | |
|---|
| 985 | @param reader: An L{IReadDescriptor} provider that will be checked for |
|---|
| 986 | read events until it is removed from the reactor with |
|---|
| 987 | L{removeReader}. |
|---|
| 988 | |
|---|
| 989 | @return: C{None}. |
|---|
| 990 | """ |
|---|
| 991 | |
|---|
| 992 | def addWriter(writer): |
|---|
| 993 | """ |
|---|
| 994 | I add writer to the set of file descriptors to get write events for. |
|---|
| 995 | |
|---|
| 996 | @param writer: An L{IWriteDescriptor} provider that will be checked for |
|---|
| 997 | write events until it is removed from the reactor with |
|---|
| 998 | L{removeWriter}. |
|---|
| 999 | |
|---|
| 1000 | @return: C{None}. |
|---|
| 1001 | """ |
|---|
| 1002 | |
|---|
| 1003 | def removeReader(reader): |
|---|
| 1004 | """ |
|---|
| 1005 | Removes an object previously added with L{addReader}. |
|---|
| 1006 | |
|---|
| 1007 | @return: C{None}. |
|---|
| 1008 | """ |
|---|
| 1009 | |
|---|
| 1010 | def removeWriter(writer): |
|---|
| 1011 | """ |
|---|
| 1012 | Removes an object previously added with L{addWriter}. |
|---|
| 1013 | |
|---|
| 1014 | @return: C{None}. |
|---|
| 1015 | """ |
|---|
| 1016 | |
|---|
| 1017 | def removeAll(): |
|---|
| 1018 | """ |
|---|
| 1019 | Remove all readers and writers. |
|---|
| 1020 | |
|---|
| 1021 | Should not remove reactor internal reactor connections (like a waker). |
|---|
| 1022 | |
|---|
| 1023 | @return: A list of L{IReadDescriptor} and L{IWriteDescriptor} providers |
|---|
| 1024 | which were removed. |
|---|
| 1025 | """ |
|---|
| 1026 | |
|---|
| 1027 | def getReaders(): |
|---|
| 1028 | """ |
|---|
| 1029 | Return the list of file descriptors currently monitored for input |
|---|
| 1030 | events by the reactor. |
|---|
| 1031 | |
|---|
| 1032 | @return: the list of file descriptors monitored for input events. |
|---|
| 1033 | @rtype: C{list} of C{IReadDescriptor} |
|---|
| 1034 | """ |
|---|
| 1035 | |
|---|
| 1036 | def getWriters(): |
|---|
| 1037 | """ |
|---|
| 1038 | Return the list file descriptors currently monitored for output events |
|---|
| 1039 | by the reactor. |
|---|
| 1040 | |
|---|
| 1041 | @return: the list of file descriptors monitored for output events. |
|---|
| 1042 | @rtype: C{list} of C{IWriteDescriptor} |
|---|
| 1043 | """ |
|---|
| 1044 | |
|---|
| 1045 | |
|---|
| 1046 | class IListeningPort(Interface): |
|---|
| 1047 | """ |
|---|
| 1048 | A listening port. |
|---|
| 1049 | """ |
|---|
| 1050 | |
|---|
| 1051 | def startListening(): |
|---|
| 1052 | """ |
|---|
| 1053 | Start listening on this port. |
|---|
| 1054 | |
|---|
| 1055 | @raise CannotListenError: If it cannot listen on this port (e.g., it is |
|---|
| 1056 | a TCP port and it cannot bind to the required |
|---|
| 1057 | port number). |
|---|
| 1058 | """ |
|---|
| 1059 | |
|---|
| 1060 | def stopListening(): |
|---|
| 1061 | """ |
|---|
| 1062 | Stop listening on this port. |
|---|
| 1063 | |
|---|
| 1064 | If it does not complete immediately, will return Deferred that fires |
|---|
| 1065 | upon completion. |
|---|
| 1066 | """ |
|---|
| 1067 | |
|---|
| 1068 | def getHost(): |
|---|
| 1069 | """ |
|---|
| 1070 | Get the host that this port is listening for. |
|---|
| 1071 | |
|---|
| 1072 | @return: An L{IAddress} provider. |
|---|
| 1073 | """ |
|---|
| 1074 | |
|---|
| 1075 | |
|---|
| 1076 | class ILoggingContext(Interface): |
|---|
| 1077 | """ |
|---|
| 1078 | Give context information that will be used to log events generated by |
|---|
| 1079 | this item. |
|---|
| 1080 | """ |
|---|
| 1081 | |
|---|
| 1082 | def logPrefix(): |
|---|
| 1083 | """ |
|---|
| 1084 | @return: Prefix used during log formatting to indicate context. |
|---|
| 1085 | @rtype: C{str} |
|---|
| 1086 | """ |
|---|
| 1087 | |
|---|
| 1088 | |
|---|
| 1089 | |
|---|
| 1090 | class IFileDescriptor(ILoggingContext): |
|---|
| 1091 | """ |
|---|
| 1092 | An interface representing a UNIX-style numeric file descriptor. |
|---|
| 1093 | """ |
|---|
| 1094 | |
|---|
| 1095 | def fileno(): |
|---|
| 1096 | """ |
|---|
| 1097 | @raise: If the descriptor no longer has a valid file descriptor |
|---|
| 1098 | number associated with it. |
|---|
| 1099 | |
|---|
| 1100 | @return: The platform-specified representation of a file descriptor |
|---|
| 1101 | number. Or C{-1} if the descriptor no longer has a valid file |
|---|
| 1102 | descriptor number associated with it. As long as the descriptor |
|---|
| 1103 | is valid, calls to this method on a particular instance must |
|---|
| 1104 | return the same value. |
|---|
| 1105 | """ |
|---|
| 1106 | |
|---|
| 1107 | |
|---|
| 1108 | def connectionLost(reason): |
|---|
| 1109 | """ |
|---|
| 1110 | Called when the connection was lost. |
|---|
| 1111 | |
|---|
| 1112 | This is called when the connection on a selectable object has been |
|---|
| 1113 | lost. It will be called whether the connection was closed explicitly, |
|---|
| 1114 | an exception occurred in an event handler, or the other end of the |
|---|
| 1115 | connection closed it first. |
|---|
| 1116 | |
|---|
| 1117 | See also L{IHalfCloseableDescriptor} if your descriptor wants to be |
|---|
| 1118 | notified separately of the two halves of the connection being closed. |
|---|
| 1119 | |
|---|
| 1120 | @param reason: A failure instance indicating the reason why the |
|---|
| 1121 | connection was lost. L{error.ConnectionLost} and |
|---|
| 1122 | L{error.ConnectionDone} are of special note, but the |
|---|
| 1123 | failure may be of other classes as well. |
|---|
| 1124 | """ |
|---|
| 1125 | |
|---|
| 1126 | |
|---|
| 1127 | |
|---|
| 1128 | class IReadDescriptor(IFileDescriptor): |
|---|
| 1129 | """ |
|---|
| 1130 | An L{IFileDescriptor} that can read. |
|---|
| 1131 | |
|---|
| 1132 | This interface is generally used in conjunction with L{IReactorFDSet}. |
|---|
| 1133 | """ |
|---|
| 1134 | |
|---|
| 1135 | def doRead(): |
|---|
| 1136 | """ |
|---|
| 1137 | Some data is available for reading on your descriptor. |
|---|
| 1138 | |
|---|
| 1139 | @return: If an error is encountered which causes the descriptor to |
|---|
| 1140 | no longer be valid, a L{Failure} should be returned. Otherwise, |
|---|
| 1141 | C{None}. |
|---|
| 1142 | """ |
|---|
| 1143 | |
|---|
| 1144 | |
|---|
| 1145 | class IWriteDescriptor(IFileDescriptor): |
|---|
| 1146 | """ |
|---|
| 1147 | An L{IFileDescriptor} that can write. |
|---|
| 1148 | |
|---|
| 1149 | This interface is generally used in conjunction with L{IReactorFDSet}. |
|---|
| 1150 | """ |
|---|
| 1151 | |
|---|
| 1152 | def doWrite(): |
|---|
| 1153 | """ |
|---|
| 1154 | Some data can be written to your descriptor. |
|---|
| 1155 | |
|---|
| 1156 | @return: If an error is encountered which causes the descriptor to |
|---|
| 1157 | no longer be valid, a L{Failure} should be returned. Otherwise, |
|---|
| 1158 | C{None}. |
|---|
| 1159 | """ |
|---|
| 1160 | |
|---|
| 1161 | |
|---|
| 1162 | class IReadWriteDescriptor(IReadDescriptor, IWriteDescriptor): |
|---|
| 1163 | """ |
|---|
| 1164 | An L{IFileDescriptor} that can both read and write. |
|---|
| 1165 | """ |
|---|
| 1166 | |
|---|
| 1167 | |
|---|
| 1168 | class IHalfCloseableDescriptor(Interface): |
|---|
| 1169 | """ |
|---|
| 1170 | A descriptor that can be half-closed. |
|---|
| 1171 | """ |
|---|
| 1172 | |
|---|
| 1173 | def writeConnectionLost(reason): |
|---|
| 1174 | """ |
|---|
| 1175 | Indicates write connection was lost. |
|---|
| 1176 | """ |
|---|
| 1177 | |
|---|
| 1178 | def readConnectionLost(reason): |
|---|
| 1179 | """ |
|---|
| 1180 | Indicates read connection was lost. |
|---|
| 1181 | """ |
|---|
| 1182 | |
|---|
| 1183 | |
|---|
| 1184 | class ISystemHandle(Interface): |
|---|
| 1185 | """ |
|---|
| 1186 | An object that wraps a networking OS-specific handle. |
|---|
| 1187 | """ |
|---|
| 1188 | |
|---|
| 1189 | def getHandle(): |
|---|
| 1190 | """ |
|---|
| 1191 | Return a system- and reactor-specific handle. |
|---|
| 1192 | |
|---|
| 1193 | This might be a socket.socket() object, or some other type of |
|---|
| 1194 | object, depending on which reactor is being used. Use and |
|---|
| 1195 | manipulate at your own risk. |
|---|
| 1196 | |
|---|
| 1197 | This might be used in cases where you want to set specific |
|---|
| 1198 | options not exposed by the Twisted APIs. |
|---|
| 1199 | """ |
|---|
| 1200 | |
|---|
| 1201 | |
|---|
| 1202 | class IConsumer(Interface): |
|---|
| 1203 | """ |
|---|
| 1204 | A consumer consumes data from a producer. |
|---|
| 1205 | """ |
|---|
| 1206 | |
|---|
| 1207 | def registerProducer(producer, streaming): |
|---|
| 1208 | """ |
|---|
| 1209 | Register to receive data from a producer. |
|---|
| 1210 | |
|---|
| 1211 | This sets self to be a consumer for a producer. When this object runs |
|---|
| 1212 | out of data (as when a send(2) call on a socket succeeds in moving the |
|---|
| 1213 | last data from a userspace buffer into a kernelspace buffer), it will |
|---|
| 1214 | ask the producer to resumeProducing(). |
|---|
| 1215 | |
|---|
| 1216 | For L{IPullProducer} providers, C{resumeProducing} will be called once |
|---|
| 1217 | each time data is required. |
|---|
| 1218 | |
|---|
| 1219 | For L{IPushProducer} providers, C{pauseProducing} will be called |
|---|
| 1220 | whenever the write buffer fills up and C{resumeProducing} will only be |
|---|
| 1221 | called when it empties. |
|---|
| 1222 | |
|---|
| 1223 | @type producer: L{IProducer} provider |
|---|
| 1224 | |
|---|
| 1225 | @type streaming: C{bool} |
|---|
| 1226 | @param streaming: C{True} if C{producer} provides L{IPushProducer}, |
|---|
| 1227 | C{False} if C{producer} provides L{IPullProducer}. |
|---|
| 1228 | |
|---|
| 1229 | @raise RuntimeError: If a producer is already registered. |
|---|
| 1230 | |
|---|
| 1231 | @return: C{None} |
|---|
| 1232 | """ |
|---|
| 1233 | |
|---|
| 1234 | |
|---|
| 1235 | def unregisterProducer(): |
|---|
| 1236 | """ |
|---|
| 1237 | Stop consuming data from a producer, without disconnecting. |
|---|
| 1238 | """ |
|---|
| 1239 | |
|---|
| 1240 | |
|---|
| 1241 | def write(data): |
|---|
| 1242 | """ |
|---|
| 1243 | The producer will write data by calling this method. |
|---|
| 1244 | |
|---|
| 1245 | The implementation must be non-blocking and perform whatever |
|---|
| 1246 | buffering is necessary. If the producer has provided enough data |
|---|
| 1247 | for now and it is a L{IPushProducer}, the consumer may call its |
|---|
| 1248 | C{pauseProducing} method. |
|---|
| 1249 | """ |
|---|
| 1250 | |
|---|
| 1251 | |
|---|
| 1252 | |
|---|
| 1253 | deprecatedModuleAttribute(Version("Twisted", 11, 1, 0), |
|---|
| 1254 | "Please use IConsumer (and IConsumer.unregisterProducer) instead.", |
|---|
| 1255 | __name__, "IFinishableConsumer") |
|---|
| 1256 | |
|---|
| 1257 | class IFinishableConsumer(IConsumer): |
|---|
| 1258 | """ |
|---|
| 1259 | A Consumer for producers that finish. This interface offers no advantages |
|---|
| 1260 | over L{IConsumer} and is deprecated. Please use |
|---|
| 1261 | L{IConsumer.unregisterProducer} instead of L{IFinishableConsumer.finish}. |
|---|
| 1262 | """ |
|---|
| 1263 | |
|---|
| 1264 | def finish(): |
|---|
| 1265 | """ |
|---|
| 1266 | The producer has finished producing. This method is deprecated. |
|---|
| 1267 | Please use L{IConsumer.unregisterProducer} instead. |
|---|
| 1268 | """ |
|---|
| 1269 | |
|---|
| 1270 | |
|---|
| 1271 | |
|---|
| 1272 | class IProducer(Interface): |
|---|
| 1273 | """ |
|---|
| 1274 | A producer produces data for a consumer. |
|---|
| 1275 | |
|---|
| 1276 | Typically producing is done by calling the write method of an class |
|---|
| 1277 | implementing L{IConsumer}. |
|---|
| 1278 | """ |
|---|
| 1279 | |
|---|
| 1280 | def stopProducing(): |
|---|
| 1281 | """ |
|---|
| 1282 | Stop producing data. |
|---|
| 1283 | |
|---|
| 1284 | This tells a producer that its consumer has died, so it must stop |
|---|
| 1285 | producing data for good. |
|---|
| 1286 | """ |
|---|
| 1287 | |
|---|
| 1288 | |
|---|
| 1289 | class IPushProducer(IProducer): |
|---|
| 1290 | """ |
|---|
| 1291 | A push producer, also known as a streaming producer is expected to |
|---|
| 1292 | produce (write to this consumer) data on a continuous basis, unless |
|---|
| 1293 | it has been paused. A paused push producer will resume producing |
|---|
| 1294 | after its resumeProducing() method is called. For a push producer |
|---|
| 1295 | which is not pauseable, these functions may be noops. |
|---|
| 1296 | """ |
|---|
| 1297 | |
|---|
| 1298 | def pauseProducing(): |
|---|
| 1299 | """ |
|---|
| 1300 | Pause producing data. |
|---|
| 1301 | |
|---|
| 1302 | Tells a producer that it has produced too much data to process for |
|---|
| 1303 | the time being, and to stop until resumeProducing() is called. |
|---|
| 1304 | """ |
|---|
| 1305 | def resumeProducing(): |
|---|
| 1306 | """ |
|---|
| 1307 | Resume producing data. |
|---|
| 1308 | |
|---|
| 1309 | This tells a producer to re-add itself to the main loop and produce |
|---|
| 1310 | more data for its consumer. |
|---|
| 1311 | """ |
|---|
| 1312 | |
|---|
| 1313 | class IPullProducer(IProducer): |
|---|
| 1314 | """ |
|---|
| 1315 | A pull producer, also known as a non-streaming producer, is |
|---|
| 1316 | expected to produce data each time resumeProducing() is called. |
|---|
| 1317 | """ |
|---|
| 1318 | |
|---|
| 1319 | def resumeProducing(): |
|---|
| 1320 | """ |
|---|
| 1321 | Produce data for the consumer a single time. |
|---|
| 1322 | |
|---|
| 1323 | This tells a producer to produce data for the consumer once |
|---|
| 1324 | (not repeatedly, once only). Typically this will be done |
|---|
| 1325 | by calling the consumer's write() method a single time with |
|---|
| 1326 | produced data. |
|---|
| 1327 | """ |
|---|
| 1328 | |
|---|
| 1329 | class IProtocol(Interface): |
|---|
| 1330 | |
|---|
| 1331 | def dataReceived(data): |
|---|
| 1332 | """ |
|---|
| 1333 | Called whenever data is received. |
|---|
| 1334 | |
|---|
| 1335 | Use this method to translate to a higher-level message. Usually, some |
|---|
| 1336 | callback will be made upon the receipt of each complete protocol |
|---|
| 1337 | message. |
|---|
| 1338 | |
|---|
| 1339 | @param data: a string of indeterminate length. Please keep in mind |
|---|
| 1340 | that you will probably need to buffer some data, as partial |
|---|
| 1341 | (or multiple) protocol messages may be received! I recommend |
|---|
| 1342 | that unit tests for protocols call through to this method with |
|---|
| 1343 | differing chunk sizes, down to one byte at a time. |
|---|
| 1344 | """ |
|---|
| 1345 | |
|---|
| 1346 | def connectionLost(reason): |
|---|
| 1347 | """ |
|---|
| 1348 | Called when the connection is shut down. |
|---|
| 1349 | |
|---|
| 1350 | Clear any circular references here, and any external references |
|---|
| 1351 | to this Protocol. The connection has been closed. The C{reason} |
|---|
| 1352 | Failure wraps a L{twisted.internet.error.ConnectionDone} or |
|---|
| 1353 | L{twisted.internet.error.ConnectionLost} instance (or a subclass |
|---|
| 1354 | of one of those). |
|---|
| 1355 | |
|---|
| 1356 | @type reason: L{twisted.python.failure.Failure} |
|---|
| 1357 | """ |
|---|
| 1358 | |
|---|
| 1359 | def makeConnection(transport): |
|---|
| 1360 | """ |
|---|
| 1361 | Make a connection to a transport and a server. |
|---|
| 1362 | """ |
|---|
| 1363 | |
|---|
| 1364 | def connectionMade(): |
|---|
| 1365 | """ |
|---|
| 1366 | Called when a connection is made. |
|---|
| 1367 | |
|---|
| 1368 | This may be considered the initializer of the protocol, because |
|---|
| 1369 | it is called when the connection is completed. For clients, |
|---|
| 1370 | this is called once the connection to the server has been |
|---|
| 1371 | established; for servers, this is called after an accept() call |
|---|
| 1372 | stops blocking and a socket has been received. If you need to |
|---|
| 1373 | send any greeting or initial message, do it here. |
|---|
| 1374 | """ |
|---|
| 1375 | |
|---|
| 1376 | |
|---|
| 1377 | class IProcessProtocol(Interface): |
|---|
| 1378 | """ |
|---|
| 1379 | Interface for process-related event handlers. |
|---|
| 1380 | """ |
|---|
| 1381 | |
|---|
| 1382 | def makeConnection(process): |
|---|
| 1383 | """ |
|---|
| 1384 | Called when the process has been created. |
|---|
| 1385 | |
|---|
| 1386 | @type process: L{IProcessTransport} provider |
|---|
| 1387 | @param process: An object representing the process which has been |
|---|
| 1388 | created and associated with this protocol. |
|---|
| 1389 | """ |
|---|
| 1390 | |
|---|
| 1391 | |
|---|
| 1392 | def childDataReceived(childFD, data): |
|---|
| 1393 | """ |
|---|
| 1394 | Called when data arrives from the child process. |
|---|
| 1395 | |
|---|
| 1396 | @type childFD: C{int} |
|---|
| 1397 | @param childFD: The file descriptor from which the data was |
|---|
| 1398 | received. |
|---|
| 1399 | |
|---|
| 1400 | @type data: C{str} |
|---|
| 1401 | @param data: The data read from the child's file descriptor. |
|---|
| 1402 | """ |
|---|
| 1403 | |
|---|
| 1404 | |
|---|
| 1405 | def childConnectionLost(childFD): |
|---|
| 1406 | """ |
|---|
| 1407 | Called when a file descriptor associated with the child process is |
|---|
| 1408 | closed. |
|---|
| 1409 | |
|---|
| 1410 | @type childFD: C{int} |
|---|
| 1411 | @param childFD: The file descriptor which was closed. |
|---|
| 1412 | """ |
|---|
| 1413 | |
|---|
| 1414 | |
|---|
| 1415 | def processExited(reason): |
|---|
| 1416 | """ |
|---|
| 1417 | Called when the child process exits. |
|---|
| 1418 | |
|---|
| 1419 | @type reason: L{twisted.python.failure.Failure} |
|---|
| 1420 | @param reason: A failure giving the reason the child process |
|---|
| 1421 | terminated. The type of exception for this failure is either |
|---|
| 1422 | L{twisted.internet.error.ProcessDone} or |
|---|
| 1423 | L{twisted.internet.error.ProcessTerminated}. |
|---|
| 1424 | |
|---|
| 1425 | @since: 8.2 |
|---|
| 1426 | """ |
|---|
| 1427 | |
|---|
| 1428 | |
|---|
| 1429 | def processEnded(reason): |
|---|
| 1430 | """ |
|---|
| 1431 | Called when the child process exits and all file descriptors associated |
|---|
| 1432 | with it have been closed. |
|---|
| 1433 | |
|---|
| 1434 | @type reason: L{twisted.python.failure.Failure} |
|---|
| 1435 | @param reason: A failure giving the reason the child process |
|---|
| 1436 | terminated. The type of exception for this failure is either |
|---|
| 1437 | L{twisted.internet.error.ProcessDone} or |
|---|
| 1438 | L{twisted.internet.error.ProcessTerminated}. |
|---|
| 1439 | """ |
|---|
| 1440 | |
|---|
| 1441 | |
|---|
| 1442 | |
|---|
| 1443 | class IHalfCloseableProtocol(Interface): |
|---|
| 1444 | """ |
|---|
| 1445 | Implemented to indicate they want notification of half-closes. |
|---|
| 1446 | |
|---|
| 1447 | TCP supports the notion of half-closing the connection, e.g. |
|---|
| 1448 | closing the write side but still not stopping reading. A protocol |
|---|
| 1449 | that implements this interface will be notified of such events, |
|---|
| 1450 | instead of having connectionLost called. |
|---|
| 1451 | """ |
|---|
| 1452 | |
|---|
| 1453 | def readConnectionLost(): |
|---|
| 1454 | """ |
|---|
| 1455 | Notification of the read connection being closed. |
|---|
| 1456 | |
|---|
| 1457 | This indicates peer did half-close of write side. It is now |
|---|
| 1458 | the responsibility of the this protocol to call |
|---|
| 1459 | loseConnection(). In addition, the protocol MUST make sure a |
|---|
| 1460 | reference to it still exists (i.e. by doing a callLater with |
|---|
| 1461 | one of its methods, etc.) as the reactor will only have a |
|---|
| 1462 | reference to it if it is writing. |
|---|
| 1463 | |
|---|
| 1464 | If the protocol does not do so, it might get garbage collected |
|---|
| 1465 | without the connectionLost method ever being called. |
|---|
| 1466 | """ |
|---|
| 1467 | |
|---|
| 1468 | def writeConnectionLost(): |
|---|
| 1469 | """ |
|---|
| 1470 | Notification of the write connection being closed. |
|---|
| 1471 | |
|---|
| 1472 | This will never be called for TCP connections as TCP does not |
|---|
| 1473 | support notification of this type of half-close. |
|---|
| 1474 | """ |
|---|
| 1475 | |
|---|
| 1476 | |
|---|
| 1477 | |
|---|
| 1478 | class IFileDescriptorReceiver(Interface): |
|---|
| 1479 | """ |
|---|
| 1480 | Protocols may implement L{IFileDescriptorReceiver} to receive file |
|---|
| 1481 | descriptors sent to them. This is useful in conjunction with |
|---|
| 1482 | L{IUNIXTransport}, which allows file descriptors to be sent between |
|---|
| 1483 | processes on a single host. |
|---|
| 1484 | """ |
|---|
| 1485 | def fileDescriptorReceived(descriptor): |
|---|
| 1486 | """ |
|---|
| 1487 | Called when a file descriptor is received over the connection. |
|---|
| 1488 | |
|---|
| 1489 | @param descriptor: The descriptor which was received. |
|---|
| 1490 | @type descriptor: C{int} |
|---|
| 1491 | |
|---|
| 1492 | @return: C{None} |
|---|
| 1493 | """ |
|---|
| 1494 | |
|---|
| 1495 | |
|---|
| 1496 | |
|---|
| 1497 | class IProtocolFactory(Interface): |
|---|
| 1498 | """ |
|---|
| 1499 | Interface for protocol factories. |
|---|
| 1500 | """ |
|---|
| 1501 | |
|---|
| 1502 | def buildProtocol(addr): |
|---|
| 1503 | """ |
|---|
| 1504 | Called when a connection has been established to addr. |
|---|
| 1505 | |
|---|
| 1506 | If None is returned, the connection is assumed to have been refused, |
|---|
| 1507 | and the Port will close the connection. |
|---|
| 1508 | |
|---|
| 1509 | @type addr: (host, port) |
|---|
| 1510 | @param addr: The address of the newly-established connection |
|---|
| 1511 | |
|---|
| 1512 | @return: None if the connection was refused, otherwise an object |
|---|
| 1513 | providing L{IProtocol}. |
|---|
| 1514 | """ |
|---|
| 1515 | |
|---|
| 1516 | def doStart(): |
|---|
| 1517 | """ |
|---|
| 1518 | Called every time this is connected to a Port or Connector. |
|---|
| 1519 | """ |
|---|
| 1520 | |
|---|
| 1521 | def doStop(): |
|---|
| 1522 | """ |
|---|
| 1523 | Called every time this is unconnected from a Port or Connector. |
|---|
| 1524 | """ |
|---|
| 1525 | |
|---|
| 1526 | |
|---|
| 1527 | class ITransport(Interface): |
|---|
| 1528 | """ |
|---|
| 1529 | I am a transport for bytes. |
|---|
| 1530 | |
|---|
| 1531 | I represent (and wrap) the physical connection and synchronicity |
|---|
| 1532 | of the framework which is talking to the network. I make no |
|---|
| 1533 | representations about whether calls to me will happen immediately |
|---|
| 1534 | or require returning to a control loop, or whether they will happen |
|---|
| 1535 | in the same or another thread. Consider methods of this class |
|---|
| 1536 | (aside from getPeer) to be 'thrown over the wall', to happen at some |
|---|
| 1537 | indeterminate time. |
|---|
| 1538 | """ |
|---|
| 1539 | |
|---|
| 1540 | def write(data): |
|---|
| 1541 | """ |
|---|
| 1542 | Write some data to the physical connection, in sequence, in a |
|---|
| 1543 | non-blocking fashion. |
|---|
| 1544 | |
|---|
| 1545 | If possible, make sure that it is all written. No data will |
|---|
| 1546 | ever be lost, although (obviously) the connection may be closed |
|---|
| 1547 | before it all gets through. |
|---|
| 1548 | """ |
|---|
| 1549 | |
|---|
| 1550 | def writeSequence(data): |
|---|
| 1551 | """ |
|---|
| 1552 | Write a list of strings to the physical connection. |
|---|
| 1553 | |
|---|
| 1554 | If possible, make sure that all of the data is written to |
|---|
| 1555 | the socket at once, without first copying it all into a |
|---|
| 1556 | single string. |
|---|
| 1557 | """ |
|---|
| 1558 | |
|---|
| 1559 | def loseConnection(): |
|---|
| 1560 | """ |
|---|
| 1561 | Close my connection, after writing all pending data. |
|---|
| 1562 | |
|---|
| 1563 | Note that if there is a registered producer on a transport it |
|---|
| 1564 | will not be closed until the producer has been unregistered. |
|---|
| 1565 | """ |
|---|
| 1566 | |
|---|
| 1567 | def getPeer(): |
|---|
| 1568 | """ |
|---|
| 1569 | Get the remote address of this connection. |
|---|
| 1570 | |
|---|
| 1571 | Treat this method with caution. It is the unfortunate result of the |
|---|
| 1572 | CGI and Jabber standards, but should not be considered reliable for |
|---|
| 1573 | the usual host of reasons; port forwarding, proxying, firewalls, IP |
|---|
| 1574 | masquerading, etc. |
|---|
| 1575 | |
|---|
| 1576 | @return: An L{IAddress} provider. |
|---|
| 1577 | """ |
|---|
| 1578 | |
|---|
| 1579 | def getHost(): |
|---|
| 1580 | """ |
|---|
| 1581 | Similar to getPeer, but returns an address describing this side of the |
|---|
| 1582 | connection. |
|---|
| 1583 | |
|---|
| 1584 | @return: An L{IAddress} provider. |
|---|
| 1585 | """ |
|---|
| 1586 | |
|---|
| 1587 | |
|---|
| 1588 | class ITCPTransport(ITransport): |
|---|
| 1589 | """ |
|---|
| 1590 | A TCP based transport. |
|---|
| 1591 | """ |
|---|
| 1592 | |
|---|
| 1593 | def loseWriteConnection(): |
|---|
| 1594 | """ |
|---|
| 1595 | Half-close the write side of a TCP connection. |
|---|
| 1596 | |
|---|
| 1597 | If the protocol instance this is attached to provides |
|---|
| 1598 | IHalfCloseableProtocol, it will get notified when the operation is |
|---|
| 1599 | done. When closing write connection, as with loseConnection this will |
|---|
| 1600 | only happen when buffer has emptied and there is no registered |
|---|
| 1601 | producer. |
|---|
| 1602 | """ |
|---|
| 1603 | |
|---|
| 1604 | |
|---|
| 1605 | def abortConnection(): |
|---|
| 1606 | """ |
|---|
| 1607 | Close the connection abruptly. |
|---|
| 1608 | |
|---|
| 1609 | Discards any buffered data, stops any registered producer, |
|---|
| 1610 | and, if possible, notifies the other end of the unclean |
|---|
| 1611 | closure. |
|---|
| 1612 | |
|---|
| 1613 | @since: 11.1 |
|---|
| 1614 | """ |
|---|
| 1615 | |
|---|
| 1616 | |
|---|
| 1617 | def getTcpNoDelay(): |
|---|
| 1618 | """ |
|---|
| 1619 | Return if C{TCP_NODELAY} is enabled. |
|---|
| 1620 | """ |
|---|
| 1621 | |
|---|
| 1622 | def setTcpNoDelay(enabled): |
|---|
| 1623 | """ |
|---|
| 1624 | Enable/disable C{TCP_NODELAY}. |
|---|
| 1625 | |
|---|
| 1626 | Enabling C{TCP_NODELAY} turns off Nagle's algorithm. Small packets are |
|---|
| 1627 | sent sooner, possibly at the expense of overall throughput. |
|---|
| 1628 | """ |
|---|
| 1629 | |
|---|
| 1630 | def getTcpKeepAlive(): |
|---|
| 1631 | """ |
|---|
| 1632 | Return if C{SO_KEEPALIVE} is enabled. |
|---|
| 1633 | """ |
|---|
| 1634 | |
|---|
| 1635 | def setTcpKeepAlive(enabled): |
|---|
| 1636 | """ |
|---|
| 1637 | Enable/disable C{SO_KEEPALIVE}. |
|---|
| 1638 | |
|---|
| 1639 | Enabling C{SO_KEEPALIVE} sends packets periodically when the connection |
|---|
| 1640 | is otherwise idle, usually once every two hours. They are intended |
|---|
| 1641 | to allow detection of lost peers in a non-infinite amount of time. |
|---|
| 1642 | """ |
|---|
| 1643 | |
|---|
| 1644 | def getHost(): |
|---|
| 1645 | """ |
|---|
| 1646 | Returns L{IPv4Address} or L{IPv6Address}. |
|---|
| 1647 | """ |
|---|
| 1648 | |
|---|
| 1649 | def getPeer(): |
|---|
| 1650 | """ |
|---|
| 1651 | Returns L{IPv4Address} or L{IPv6Address}. |
|---|
| 1652 | """ |
|---|
| 1653 | |
|---|
| 1654 | |
|---|
| 1655 | |
|---|
| 1656 | class IUNIXTransport(ITransport): |
|---|
| 1657 | """ |
|---|
| 1658 | Transport for stream-oriented unix domain connections. |
|---|
| 1659 | """ |
|---|
| 1660 | def sendFileDescriptor(descriptor): |
|---|
| 1661 | """ |
|---|
| 1662 | Send a duplicate of this (file, socket, pipe, etc) descriptor to the |
|---|
| 1663 | other end of this connection. |
|---|
| 1664 | |
|---|
| 1665 | The send is non-blocking and will be queued if it cannot be performed |
|---|
| 1666 | immediately. The send will be processed in order with respect to other |
|---|
| 1667 | C{sendFileDescriptor} calls on this transport, but not necessarily with |
|---|
| 1668 | respect to C{write} calls on this transport. The send can only be |
|---|
| 1669 | processed if there are also bytes in the normal connection-oriented send |
|---|
| 1670 | buffer (ie, you must call C{write} at least as many times as you call |
|---|
| 1671 | C{sendFileDescriptor}). |
|---|
| 1672 | |
|---|
| 1673 | @param descriptor: An C{int} giving a valid file descriptor in this |
|---|
| 1674 | process. Note that a I{file descriptor} may actually refer to a |
|---|
| 1675 | socket, a pipe, or anything else POSIX tries to treat in the same |
|---|
| 1676 | way as a file. |
|---|
| 1677 | |
|---|
| 1678 | @return: C{None} |
|---|
| 1679 | """ |
|---|
| 1680 | |
|---|
| 1681 | |
|---|
| 1682 | |
|---|
| 1683 | class ITLSTransport(ITCPTransport): |
|---|
| 1684 | """ |
|---|
| 1685 | A TCP transport that supports switching to TLS midstream. |
|---|
| 1686 | |
|---|
| 1687 | Once TLS mode is started the transport will implement L{ISSLTransport}. |
|---|
| 1688 | """ |
|---|
| 1689 | |
|---|
| 1690 | def startTLS(contextFactory): |
|---|
| 1691 | """ |
|---|
| 1692 | Initiate TLS negotiation. |
|---|
| 1693 | |
|---|
| 1694 | @param contextFactory: A context factory (see L{ssl.py<twisted.internet.ssl>}) |
|---|
| 1695 | """ |
|---|
| 1696 | |
|---|
| 1697 | class ISSLTransport(ITCPTransport): |
|---|
| 1698 | """ |
|---|
| 1699 | A SSL/TLS based transport. |
|---|
| 1700 | """ |
|---|
| 1701 | |
|---|
| 1702 | def getPeerCertificate(): |
|---|
| 1703 | """ |
|---|
| 1704 | Return an object with the peer's certificate info. |
|---|
| 1705 | """ |
|---|
| 1706 | |
|---|
| 1707 | |
|---|
| 1708 | class IProcessTransport(ITransport): |
|---|
| 1709 | """ |
|---|
| 1710 | A process transport. |
|---|
| 1711 | """ |
|---|
| 1712 | |
|---|
| 1713 | pid = Attribute( |
|---|
| 1714 | "From before L{IProcessProtocol.makeConnection} is called to before " |
|---|
| 1715 | "L{IProcessProtocol.processEnded} is called, C{pid} is an L{int} " |
|---|
| 1716 | "giving the platform process ID of this process. C{pid} is L{None} " |
|---|
| 1717 | "at all other times.") |
|---|
| 1718 | |
|---|
| 1719 | def closeStdin(): |
|---|
| 1720 | """ |
|---|
| 1721 | Close stdin after all data has been written out. |
|---|
| 1722 | """ |
|---|
| 1723 | |
|---|
| 1724 | def closeStdout(): |
|---|
| 1725 | """ |
|---|
| 1726 | Close stdout. |
|---|
| 1727 | """ |
|---|
| 1728 | |
|---|
| 1729 | def closeStderr(): |
|---|
| 1730 | """ |
|---|
| 1731 | Close stderr. |
|---|
| 1732 | """ |
|---|
| 1733 | |
|---|
| 1734 | def closeChildFD(descriptor): |
|---|
| 1735 | """ |
|---|
| 1736 | Close a file descriptor which is connected to the child process, identified |
|---|
| 1737 | by its FD in the child process. |
|---|
| 1738 | """ |
|---|
| 1739 | |
|---|
| 1740 | def writeToChild(childFD, data): |
|---|
| 1741 | """ |
|---|
| 1742 | Similar to L{ITransport.write} but also allows the file descriptor in |
|---|
| 1743 | the child process which will receive the bytes to be specified. |
|---|
| 1744 | |
|---|
| 1745 | @type childFD: C{int} |
|---|
| 1746 | @param childFD: The file descriptor to which to write. |
|---|
| 1747 | |
|---|
| 1748 | @type data: C{str} |
|---|
| 1749 | @param data: The bytes to write. |
|---|
| 1750 | |
|---|
| 1751 | @return: C{None} |
|---|
| 1752 | |
|---|
| 1753 | @raise KeyError: If C{childFD} is not a file descriptor that was mapped |
|---|
| 1754 | in the child when L{IReactorProcess.spawnProcess} was used to create |
|---|
| 1755 | it. |
|---|
| 1756 | """ |
|---|
| 1757 | |
|---|
| 1758 | def loseConnection(): |
|---|
| 1759 | """ |
|---|
| 1760 | Close stdin, stderr and stdout. |
|---|
| 1761 | """ |
|---|
| 1762 | |
|---|
| 1763 | def signalProcess(signalID): |
|---|
| 1764 | """ |
|---|
| 1765 | Send a signal to the process. |
|---|
| 1766 | |
|---|
| 1767 | @param signalID: can be |
|---|
| 1768 | - one of C{"KILL"}, C{"TERM"}, or C{"INT"}. |
|---|
| 1769 | These will be implemented in a |
|---|
| 1770 | cross-platform manner, and so should be used |
|---|
| 1771 | if possible. |
|---|
| 1772 | - an integer, where it represents a POSIX |
|---|
| 1773 | signal ID. |
|---|
| 1774 | |
|---|
| 1775 | @raise twisted.internet.error.ProcessExitedAlready: The process has |
|---|
| 1776 | already exited. |
|---|
| 1777 | """ |
|---|
| 1778 | |
|---|
| 1779 | |
|---|
| 1780 | class IServiceCollection(Interface): |
|---|
| 1781 | """ |
|---|
| 1782 | An object which provides access to a collection of services. |
|---|
| 1783 | """ |
|---|
| 1784 | |
|---|
| 1785 | def getServiceNamed(serviceName): |
|---|
| 1786 | """ |
|---|
| 1787 | Retrieve the named service from this application. |
|---|
| 1788 | |
|---|
| 1789 | Raise a C{KeyError} if there is no such service name. |
|---|
| 1790 | """ |
|---|
| 1791 | |
|---|
| 1792 | def addService(service): |
|---|
| 1793 | """ |
|---|
| 1794 | Add a service to this collection. |
|---|
| 1795 | """ |
|---|
| 1796 | |
|---|
| 1797 | def removeService(service): |
|---|
| 1798 | """ |
|---|
| 1799 | Remove a service from this collection. |
|---|
| 1800 | """ |
|---|
| 1801 | |
|---|
| 1802 | |
|---|
| 1803 | class IUDPTransport(Interface): |
|---|
| 1804 | """ |
|---|
| 1805 | Transport for UDP DatagramProtocols. |
|---|
| 1806 | """ |
|---|
| 1807 | |
|---|
| 1808 | def write(packet, addr=None): |
|---|
| 1809 | """ |
|---|
| 1810 | Write packet to given address. |
|---|
| 1811 | |
|---|
| 1812 | @param addr: a tuple of (ip, port). For connected transports must |
|---|
| 1813 | be the address the transport is connected to, or None. |
|---|
| 1814 | In non-connected mode this is mandatory. |
|---|
| 1815 | |
|---|
| 1816 | @raise twisted.internet.error.MessageLengthError: C{packet} was too |
|---|
| 1817 | long. |
|---|
| 1818 | """ |
|---|
| 1819 | |
|---|
| 1820 | def connect(host, port): |
|---|
| 1821 | """ |
|---|
| 1822 | Connect the transport to an address. |
|---|
| 1823 | |
|---|
| 1824 | This changes it to connected mode. Datagrams can only be sent to |
|---|
| 1825 | this address, and will only be received from this address. In addition |
|---|
| 1826 | the protocol's connectionRefused method might get called if destination |
|---|
| 1827 | is not receiving datagrams. |
|---|
| 1828 | |
|---|
| 1829 | @param host: an IP address, not a domain name ('127.0.0.1', not 'localhost') |
|---|
| 1830 | @param port: port to connect to. |
|---|
| 1831 | """ |
|---|
| 1832 | |
|---|
| 1833 | def getHost(): |
|---|
| 1834 | """ |
|---|
| 1835 | Returns L{IPv4Address}. |
|---|
| 1836 | """ |
|---|
| 1837 | |
|---|
| 1838 | def stopListening(): |
|---|
| 1839 | """ |
|---|
| 1840 | Stop listening on this port. |
|---|
| 1841 | |
|---|
| 1842 | If it does not complete immediately, will return L{Deferred} that fires |
|---|
| 1843 | upon completion. |
|---|
| 1844 | """ |
|---|
| 1845 | |
|---|
| 1846 | |
|---|
| 1847 | |
|---|
| 1848 | class IUNIXDatagramTransport(Interface): |
|---|
| 1849 | """ |
|---|
| 1850 | Transport for UDP PacketProtocols. |
|---|
| 1851 | """ |
|---|
| 1852 | |
|---|
| 1853 | def write(packet, address): |
|---|
| 1854 | """ |
|---|
| 1855 | Write packet to given address. |
|---|
| 1856 | """ |
|---|
| 1857 | |
|---|
| 1858 | def getHost(): |
|---|
| 1859 | """ |
|---|
| 1860 | Returns L{UNIXAddress}. |
|---|
| 1861 | """ |
|---|
| 1862 | |
|---|
| 1863 | |
|---|
| 1864 | class IUNIXDatagramConnectedTransport(Interface): |
|---|
| 1865 | """ |
|---|
| 1866 | Transport for UDP ConnectedPacketProtocols. |
|---|
| 1867 | """ |
|---|
| 1868 | |
|---|
| 1869 | def write(packet): |
|---|
| 1870 | """ |
|---|
| 1871 | Write packet to address we are connected to. |
|---|
| 1872 | """ |
|---|
| 1873 | |
|---|
| 1874 | def getHost(): |
|---|
| 1875 | """ |
|---|
| 1876 | Returns L{UNIXAddress}. |
|---|
| 1877 | """ |
|---|
| 1878 | |
|---|
| 1879 | def getPeer(): |
|---|
| 1880 | """ |
|---|
| 1881 | Returns L{UNIXAddress}. |
|---|
| 1882 | """ |
|---|
| 1883 | |
|---|
| 1884 | |
|---|
| 1885 | class IMulticastTransport(Interface): |
|---|
| 1886 | """ |
|---|
| 1887 | Additional functionality for multicast UDP. |
|---|
| 1888 | """ |
|---|
| 1889 | |
|---|
| 1890 | def getOutgoingInterface(): |
|---|
| 1891 | """ |
|---|
| 1892 | Return interface of outgoing multicast packets. |
|---|
| 1893 | """ |
|---|
| 1894 | |
|---|
| 1895 | def setOutgoingInterface(addr): |
|---|
| 1896 | """ |
|---|
| 1897 | Set interface for outgoing multicast packets. |
|---|
| 1898 | |
|---|
| 1899 | Returns Deferred of success. |
|---|
| 1900 | """ |
|---|
| 1901 | |
|---|
| 1902 | def getLoopbackMode(): |
|---|
| 1903 | """ |
|---|
| 1904 | Return if loopback mode is enabled. |
|---|
| 1905 | """ |
|---|
| 1906 | |
|---|
| 1907 | def setLoopbackMode(mode): |
|---|
| 1908 | """ |
|---|
| 1909 | Set if loopback mode is enabled. |
|---|
| 1910 | """ |
|---|
| 1911 | |
|---|
| 1912 | def getTTL(): |
|---|
| 1913 | """ |
|---|
| 1914 | Get time to live for multicast packets. |
|---|
| 1915 | """ |
|---|
| 1916 | |
|---|
| 1917 | def setTTL(ttl): |
|---|
| 1918 | """ |
|---|
| 1919 | Set time to live on multicast packets. |
|---|
| 1920 | """ |
|---|
| 1921 | |
|---|
| 1922 | def joinGroup(addr, interface=""): |
|---|
| 1923 | """ |
|---|
| 1924 | Join a multicast group. Returns L{Deferred} of success or failure. |
|---|
| 1925 | |
|---|
| 1926 | If an error occurs, the returned L{Deferred} will fail with |
|---|
| 1927 | L{error.MulticastJoinError}. |
|---|
| 1928 | """ |
|---|
| 1929 | |
|---|
| 1930 | def leaveGroup(addr, interface=""): |
|---|
| 1931 | """ |
|---|
| 1932 | Leave multicast group, return L{Deferred} of success. |
|---|
| 1933 | """ |
|---|
| 1934 | |
|---|
| 1935 | |
|---|
| 1936 | class IStreamClientEndpoint(Interface): |
|---|
| 1937 | """ |
|---|
| 1938 | A stream client endpoint is a place that L{ClientFactory} can connect to. |
|---|
| 1939 | For example, a remote TCP host/port pair would be a TCP client endpoint. |
|---|
| 1940 | |
|---|
| 1941 | @since: 10.1 |
|---|
| 1942 | """ |
|---|
| 1943 | |
|---|
| 1944 | def connect(protocolFactory): |
|---|
| 1945 | """ |
|---|
| 1946 | Connect the C{protocolFactory} to the location specified by this |
|---|
| 1947 | L{IStreamClientEndpoint} provider. |
|---|
| 1948 | |
|---|
| 1949 | @param protocolFactory: A provider of L{IProtocolFactory} |
|---|
| 1950 | @return: A L{Deferred} that results in an L{IProtocol} upon successful |
|---|
| 1951 | connection otherwise a L{ConnectError} |
|---|
| 1952 | """ |
|---|
| 1953 | |
|---|
| 1954 | |
|---|
| 1955 | |
|---|
| 1956 | class IStreamServerEndpoint(Interface): |
|---|
| 1957 | """ |
|---|
| 1958 | A stream server endpoint is a place that a L{Factory} can listen for |
|---|
| 1959 | incoming connections. |
|---|
| 1960 | |
|---|
| 1961 | @since: 10.1 |
|---|
| 1962 | """ |
|---|
| 1963 | |
|---|
| 1964 | def listen(protocolFactory): |
|---|
| 1965 | """ |
|---|
| 1966 | Listen with C{protocolFactory} at the location specified by this |
|---|
| 1967 | L{IStreamServerEndpoint} provider. |
|---|
| 1968 | |
|---|
| 1969 | @param protocolFactory: A provider of L{IProtocolFactory} |
|---|
| 1970 | @return: A L{Deferred} that results in an L{IListeningPort} or an |
|---|
| 1971 | L{CannotListenError} |
|---|
| 1972 | """ |
|---|
| 1973 | |
|---|
| 1974 | |
|---|
| 1975 | |
|---|
| 1976 | class IStreamServerEndpointStringParser(Interface): |
|---|
| 1977 | """ |
|---|
| 1978 | An L{IStreamServerEndpointStringParser} is like an |
|---|
| 1979 | L{IStreamClientEndpointStringParser}, except for L{IStreamServerEndpoint}s |
|---|
| 1980 | instead of clients. It integrates with L{endpoints.serverFromString} in |
|---|
| 1981 | much the same way. |
|---|
| 1982 | """ |
|---|
| 1983 | |
|---|
| 1984 | prefix = Attribute( |
|---|
| 1985 | """ |
|---|
| 1986 | @see: L{IStreamClientEndpointStringParser.prefix} |
|---|
| 1987 | """ |
|---|
| 1988 | ) |
|---|
| 1989 | |
|---|
| 1990 | |
|---|
| 1991 | def parseStreamServer(reactor, *args, **kwargs): |
|---|
| 1992 | """ |
|---|
| 1993 | Parse a stream server endpoint from a reactor and string-only arguments |
|---|
| 1994 | and keyword arguments. |
|---|
| 1995 | |
|---|
| 1996 | @see: L{IStreamClientEndpointStringParser.parseStreamClient} |
|---|
| 1997 | |
|---|
| 1998 | @return: a stream server endpoint |
|---|
| 1999 | @rtype: L{IStreamServerEndpoint} |
|---|
| 2000 | """ |
|---|
| 2001 | |
|---|
| 2002 | |
|---|
| 2003 | |
|---|
| 2004 | class IStreamClientEndpointStringParser(Interface): |
|---|
| 2005 | """ |
|---|
| 2006 | An L{IStreamClientEndpointStringParser} is a parser which can convert |
|---|
| 2007 | a set of string C{*args} and C{**kwargs} into an L{IStreamClientEndpoint} |
|---|
| 2008 | provider. |
|---|
| 2009 | |
|---|
| 2010 | This interface is really only useful in the context of the plugin system |
|---|
| 2011 | for L{endpoints.clientFromString}. See the document entitled "I{The |
|---|
| 2012 | Twisted Plugin System}" for more details on how to write a plugin. |
|---|
| 2013 | |
|---|
| 2014 | If you place an L{IStreamClientEndpointStringParser} plugin in the |
|---|
| 2015 | C{twisted.plugins} package, that plugin's C{parseStreamClient} method will |
|---|
| 2016 | be used to produce endpoints for any description string that begins with |
|---|
| 2017 | the result of that L{IStreamClientEndpointStringParser}'s prefix attribute. |
|---|
| 2018 | """ |
|---|
| 2019 | |
|---|
| 2020 | prefix = Attribute( |
|---|
| 2021 | """ |
|---|
| 2022 | A C{str}, the description prefix to respond to. For example, an |
|---|
| 2023 | L{IStreamClientEndpointStringParser} plugin which had C{"foo"} for its |
|---|
| 2024 | C{prefix} attribute would be called for endpoint descriptions like |
|---|
| 2025 | C{"foo:bar:baz"} or C{"foo:"}. |
|---|
| 2026 | """ |
|---|
| 2027 | ) |
|---|
| 2028 | |
|---|
| 2029 | |
|---|
| 2030 | def parseStreamClient(*args, **kwargs): |
|---|
| 2031 | """ |
|---|
| 2032 | This method is invoked by L{endpoints.clientFromString}, if the type of |
|---|
| 2033 | endpoint matches the return value from this |
|---|
| 2034 | L{IStreamClientEndpointStringParser}'s C{prefix} method. |
|---|
| 2035 | |
|---|
| 2036 | @param args: The string arguments, minus the endpoint type, in the |
|---|
| 2037 | endpoint description string, parsed according to the rules |
|---|
| 2038 | described in L{endpoints.quoteStringArgument}. For example, if the |
|---|
| 2039 | description were C{"my-type:foo:bar:baz=qux"}, C{args} would be |
|---|
| 2040 | C{('foo','bar')} |
|---|
| 2041 | |
|---|
| 2042 | @param kwargs: The string arguments from the endpoint description |
|---|
| 2043 | passed as keyword arguments. For example, if the description were |
|---|
| 2044 | C{"my-type:foo:bar:baz=qux"}, C{kwargs} would be |
|---|
| 2045 | C{dict(baz='qux')}. |
|---|
| 2046 | |
|---|
| 2047 | @return: a client endpoint |
|---|
| 2048 | @rtype: L{IStreamClientEndpoint} |
|---|
| 2049 | """ |
|---|