Implements interfaces: twisted.internet.interfaces.IProtocol, twisted.internet.interfaces.IPushProducer

A class representing a single HTTP/2 connection.

This implementation of L{IProtocol} works hand in hand with L{H2Stream}.
This is because we have the requirement to register multiple producers for
a single HTTP/2 connection, one for each stream. The standard Twisted
interfaces don't really allow for this, so instead there's a custom
interface between the two objects that allows them to work hand-in-hand here.

@ivar conn: The HTTP/2 connection state machine.
@type conn: L{h2.connection.H2Connection}

@ivar streams: A mapping of stream IDs to L{H2Stream} objects, used to call
    specific methods on streams when events occur.
@type streams: L{dict}, mapping L{int} stream IDs to L{H2Stream} objects.

@ivar priority: A HTTP/2 priority tree used to ensure that responses are
    prioritised appropriately.
@type priority: L{priority.PriorityTree}

@ivar _consumerBlocked: A flag tracking whether or not the L{IConsumer}
    that is consuming this data has asked us to stop producing.
@type _consumerBlocked: L{bool}

@ivar _sendingDeferred: A L{Deferred} used to restart the data-sending loop
    when more response data has been produced. Will not be present if there
    is outstanding data still to send.
@type _consumerBlocked: A L{twisted.internet.defer.Deferred}, or L{None}

@ivar _outboundStreamQueues: A map of stream IDs to queues, used to store
    data blocks that are yet to be sent on the connection. These are used
    both to handle producers that do not respect L{IConsumer} but also to
    allow priority to multiplex data appropriately.
@type _outboundStreamQueues: A L{dict} mapping L{int} stream IDs to
    L{collections.deque} queues, which contain either L{bytes} objects or
    C{_END_STREAM_SENTINEL}.

@ivar _sender: A handle to the data-sending loop, allowing it to be
    terminated if needed.
@type _sender: L{twisted.internet.task.LoopingCall}

@ivar abortTimeout: The number of seconds to wait after we attempt to shut
    the transport down cleanly to give up and forcibly terminate it. This
    is only used when we time a connection out, to prevent errors causing
    the FD to get leaked. If this is L{None}, we will wait forever.
@type abortTimeout: L{int}

@ivar _abortingCall: The L{twisted.internet.base.DelayedCall} that will be
    used to forcibly close the transport if it doesn't close cleanly.
@type _abortingCall: L{twisted.internet.base.DelayedCall
Method __init__ Undocumented
Method connectionMade Called by the reactor when a connection is received. May also be called by the twisted.web.http._GenericHTTPChannelProtocol during upgrade to HTTP/2.
Method dataReceived Called whenever a chunk of data is received from the transport.
Method timeoutConnection No summary
Method forceAbortClient No summary
Method connectionLost Called when the transport connection is lost.
Method stopProducing Stop producing data.
Method pauseProducing Pause producing data.
Method resumeProducing Resume producing data.
Method writeHeaders Called by twisted.web.http.Request objects to write a complete set of HTTP headers to a stream.
Method writeDataToStream May be called by H2Stream objects to write response data to a given stream. Writes a single data frame.
Method endRequest Called by H2Stream objects to signal completion of a response.
Method abortRequest Called by H2Stream objects to request early termination of a stream. This emits a RstStream frame and then removes all stream state.
Method remainingOutboundWindow Called to determine how much room is left in the send window for a given stream. Allows us to handle blocking and unblocking producers.
Method getPeer Get the remote address of this connection.
Method getHost Similar to getPeer, but returns an address describing this side of the connection.
Method openStreamWindow Open the stream window by a given increment.
Method _sendPrioritisedData The data sending loop. This function repeatedly calls itself, either from Deferreds or from reactor.callLater
Method _requestReceived Internal handler for when a request has been received.
Method _requestDataReceived Internal handler for when a chunk of data is received for a given request.
Method _requestEnded Internal handler for when a request is complete, and we expect no further data for that request.
Method _requestAborted Internal handler for when a request is aborted by a remote peer.
Method _handlePriorityUpdate Internal handler for when a stream priority is updated.
Method _requestDone Called internally by the data sending loop to clean up state that was being used for the stream. Called when the stream is complete.
Method _handleWindowUpdate Manage flow control windows.
Method _isSecure Returns True if this channel is using a secure transport.
Method _send100Continue Sends a 100 Continue response, used to signal to clients that further processing will be performed.
Method _respondToBadRequestAndDisconnect This is a quick and dirty way of responding to bad requests.
Method _streamIsActive Checks whether Twisted has still got state for a given stream and so can process events for that stream.

Inherited from Protocol:

Method logPrefix Return a prefix matching the class name, to identify log messages related to this protocol instance.

Inherited from BaseProtocol (via Protocol):

Method makeConnection Make a connection to a transport and a server.

Inherited from TimeoutMixin:

Class Variable timeOut The number of seconds after which to timeout the connection.
Method callLater Wrapper around reactor.callLater for test purpose.
Method resetTimeout Reset the timeout count down.
Method setTimeout Change the timeout period
Method __timedOut Undocumented
def __init__(self, reactor=None): (source)
Undocumented
def connectionMade(self): (source)

Called by the reactor when a connection is received. May also be called by the twisted.web.http._GenericHTTPChannelProtocol during upgrade to HTTP/2.

def dataReceived(self, data): (source)

Called whenever a chunk of data is received from the transport.

ParametersdataThe data received from the transport. (type: bytes)
def timeoutConnection(self): (source)

Called when the connection has been inactive for self.timeOut seconds. Cleanly tears the connection down, attempting to notify the peer if needed.

We override this method to add two extra bits of functionality:

  • We want to log the timeout.
  • We want to send a GOAWAY frame indicating that the connection is being terminated, and whether it was clean or not. We have to do this before the connection is torn down.
def forceAbortClient(self): (source)

Called if abortTimeout seconds have passed since the timeout fired, and the connection still hasn't gone away. This can really only happen on extremely bad connections or when clients are maliciously attempting to keep connections open.

def connectionLost(self, reason): (source)

Called when the transport connection is lost.

Informs all outstanding response handlers that the connection has been lost, and cleans up all internal state.

def stopProducing(self): (source)

Stop producing data.

This tells the H2Connection that its consumer has died, so it must stop producing data for good.

def pauseProducing(self): (source)

Pause producing data.

Tells the H2Connection that it has produced too much data to process for the time being, and to stop until resumeProducing() is called.

def resumeProducing(self): (source)

Resume producing data.

This tells the H2Connection to re-add itself to the main loop and produce more data for the consumer.

def _sendPrioritisedData(self, *args): (source)

The data sending loop. This function repeatedly calls itself, either from Deferreds or from reactor.callLater

This function sends data on streams according to the rules of HTTP/2 priority. It ensures that the data from each stream is interleved according to the priority signalled by the client, making sure that the connection is used with maximal efficiency.

This function will execute if data is available: if all data is exhausted, the function will place a deferred onto the H2Connection object and wait until it is called to resume executing.

def _requestReceived(self, event): (source)

Internal handler for when a request has been received.

ParameterseventThe Hyper-h2 event that encodes information about the received request. (type: h2.events.RequestReceived)
def _requestDataReceived(self, event): (source)

Internal handler for when a chunk of data is received for a given request.

ParameterseventThe Hyper-h2 event that encodes information about the received data. (type: h2.events.DataReceived)
def _requestEnded(self, event): (source)

Internal handler for when a request is complete, and we expect no further data for that request.

ParameterseventThe Hyper-h2 event that encodes information about the completed stream. (type: h2.events.StreamEnded)
def _requestAborted(self, event): (source)

Internal handler for when a request is aborted by a remote peer.

ParameterseventThe Hyper-h2 event that encodes information about the reset stream. (type: h2.events.StreamReset)
def _handlePriorityUpdate(self, event): (source)

Internal handler for when a stream priority is updated.

ParameterseventThe Hyper-h2 event that encodes information about the stream reprioritization. (type: h2.events.PriorityUpdated)
def writeHeaders(self, version, code, reason, headers, streamID): (source)

Called by twisted.web.http.Request objects to write a complete set of HTTP headers to a stream.

ParametersversionThe HTTP version in use. Unused in HTTP/2. (type: bytes)
codeThe HTTP status code to write. (type: bytes)
reasonThe HTTP reason phrase to write. Unused in HTTP/2. (type: bytes)
headersThe headers to write to the stream. (type: twisted.web.http_headers.Headers)
streamIDThe ID of the stream to write the headers to. (type: int)
def writeDataToStream(self, streamID, data): (source)

May be called by H2Stream objects to write response data to a given stream. Writes a single data frame.

ParametersstreamIDThe ID of the stream to write the data to. (type: int)
dataThe data chunk to write to the stream. (type: bytes)
def endRequest(self, streamID): (source)

Called by H2Stream objects to signal completion of a response.

ParametersstreamIDThe ID of the stream to write the data to. (type: int)
def abortRequest(self, streamID): (source)

Called by H2Stream objects to request early termination of a stream. This emits a RstStream frame and then removes all stream state.

ParametersstreamIDThe ID of the stream to write the data to. (type: int)
def _requestDone(self, streamID): (source)

Called internally by the data sending loop to clean up state that was being used for the stream. Called when the stream is complete.

ParametersstreamIDThe ID of the stream to clean up state for. (type: int)
def remainingOutboundWindow(self, streamID): (source)

Called to determine how much room is left in the send window for a given stream. Allows us to handle blocking and unblocking producers.

ParametersstreamIDThe ID of the stream whose flow control window we'll check. (type: int)
ReturnsThe amount of room remaining in the send window for the given stream, including the data queued to be sent. (type: int)
def _handleWindowUpdate(self, event): (source)

Manage flow control windows.

Streams that are blocked on flow control will register themselves with the connection. This will fire deferreds that wake those streams up and allow them to continue processing.

ParameterseventThe Hyper-h2 event that encodes information about the flow control window change. (type: h2.events.WindowUpdated)
def getPeer(self): (source)

Get the remote address of this connection.

Treat this method with caution. It is the unfortunate result of the CGI and Jabber standards, but should not be considered reliable for the usual host of reasons; port forwarding, proxying, firewalls, IP masquerading, etc.

ReturnsAn IAddress provider.
def getHost(self): (source)

Similar to getPeer, but returns an address describing this side of the connection.

ReturnsAn IAddress provider.
def openStreamWindow(self, streamID, increment): (source)

Open the stream window by a given increment.

ParametersstreamIDThe ID of the stream whose window needs to be opened. (type: int)
incrementThe amount by which the stream window must be incremented. (type: int)
def _isSecure(self): (source)

Returns True if this channel is using a secure transport.

ReturnsTrue if this channel is secure. (type: bool)
def _send100Continue(self, streamID): (source)

Sends a 100 Continue response, used to signal to clients that further processing will be performed.

ParametersstreamIDThe ID of the stream that needs the 100 Continue response (type: int)
def _respondToBadRequestAndDisconnect(self, streamID): (source)

This is a quick and dirty way of responding to bad requests.

As described by HTTP standard we should be patient and accept the whole request from the client before sending a polite bad request response, even in the case when clients send tons of data.

Unlike in the HTTP/1.1 case, this does not actually disconnect the underlying transport: there's no need. This instead just sends a 400 response and terminates the stream.

ParametersstreamIDThe ID of the stream that needs the 100 Continue response (type: int)
def _streamIsActive(self, streamID): (source)

Checks whether Twisted has still got state for a given stream and so can process events for that stream.

ParametersstreamIDThe ID of the stream that needs processing. (type: int)
ReturnsWhether the stream still has state allocated. (type: bool)
API Documentation for Twisted, generated by pydoctor at 2017-09-23 19:45:03.