class documentation

A class representing a single HTTP/2 connection.

This implementation of IProtocol works hand in hand with 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.

Method __init__ Undocumented
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 connectionLost Called when the transport connection is lost.
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 endRequest Called by H2Stream objects to signal completion of a response.
Method forceAbortClient 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.
Method getHost Similar to getPeer, but returns an address describing this side of the connection.
Method getPeer Get the remote address of this connection.
Method openStreamWindow Open the stream window by a given increment.
Method pauseProducing Pause producing data.
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 resumeProducing Resume producing data.
Method stopProducing Stop producing data.
Method timeoutConnection Called when the connection has been inactive for self.timeOut seconds. Cleanly tears the connection down, attempting to notify the peer if needed.
Method writeDataToStream May be called by H2Stream objects to write response data to a given stream. Writes a single data frame.
Method writeHeaders Called by twisted.web.http.Request objects to write a complete set of HTTP headers to a stream.
Class Variable factory Undocumented
Class Variable site Undocumented
Instance Variable 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...
Instance Variable conn The HTTP/2 connection state machine.
Instance Variable priority A HTTP/2 priority tree used to ensure that responses are prioritised appropriately.
Instance Variable streams A mapping of stream IDs to H2Stream objects, used to call specific methods on streams when events occur.
Method _flushBufferedControlData Called when the connection is marked writable again after being marked unwritable. Attempts to flush buffered control data if there is any.
Method _handlePriorityUpdate Internal handler for when a stream priority is updated.
Method _handleWindowUpdate Manage flow control windows.
Method _isSecure Returns True if this channel is using a secure transport.
Method _requestAborted Internal handler for when a request is aborted by a remote peer.
Method _requestDataReceived Internal handler for when a chunk of data is received for a given request.
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 _requestEnded Internal handler for when a request is complete, and we expect no further data for that request.
Method _requestReceived Internal handler for when a request has been received.
Method _respondToBadRequestAndDisconnect This is a quick and dirty way of responding to bad requests.
Method _send100Continue Sends a 100 Continue response, used to signal to clients that further processing will be performed.
Method _sendPrioritisedData The data sending loop. This function repeatedly calls itself, either from Deferreds or from reactor.callLater
Method _streamIsActive Checks whether Twisted has still got state for a given stream and so can process events for that stream.
Method _tryToWriteControlData Checks whether the connection is blocked on flow control and, if it isn't, writes any buffered control data.
Class Variable _log Undocumented
Instance Variable _abortingCall The twisted.internet.base.DelayedCall that will be used to forcibly close the transport if it doesn't close cleanly.
Instance Variable _bufferedControlFrameBytes Undocumented
Instance Variable _bufferedControlFrames Undocumented
Instance Variable _consumerBlocked A flag tracking whether or not the IConsumer that is consuming this data has asked us to stop producing.
Instance Variable _maxBufferedControlFrameBytes Undocumented
Instance Variable _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 IConsumer but also to allow priority to multiplex data appropriately.
Instance Variable _reactor Undocumented
Instance Variable _sender A handle to the data-sending loop, allowing it to be terminated if needed.
Instance Variable _sendingDeferred A 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.
Instance Variable _stillProducing Undocumented
Instance Variable _streamCleanupCallbacks Undocumented

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.
Instance Variable connected Undocumented
Instance Variable transport Undocumented

Inherited from TimeoutMixin (via Protocol, BaseProtocol):

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

Undocumented

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.

Parameters
streamID:intThe ID of the stream to write the data to.
def connectionLost(self, reason, _cancelTimeouts=True): (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.

Parameters
reasonSee IProtocol.connectionLost
_cancelTimeoutsPropagate the reason to this connection's streams but don't cancel any timers, so that peers who never read the data we've written are eventually timed out.
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.

Parameters
data:bytesThe data received from the transport.
def endRequest(self, streamID): (source)

Called by H2Stream objects to signal completion of a response.

Parameters
streamID:intThe ID of the stream to write the data to.
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 getHost(self): (source)

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

Returns
An IAddress provider.
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.

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

Open the stream window by a given increment.

Parameters
streamID:intThe ID of the stream whose window needs to be opened.
increment:intThe amount by which the stream window must be incremented.
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 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.

Parameters
streamID:intThe ID of the stream whose flow control window we'll check.
Returns
intThe amount of room remaining in the send window for the given stream, including the data queued to be sent.
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 stopProducing(self): (source)

Stop producing data.

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

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 writeDataToStream(self, streamID, data): (source)

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

Parameters
streamID:intThe ID of the stream to write the data to.
data:bytesThe data chunk to write to the stream.
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.

Parameters
version:bytesThe HTTP version in use. Unused in HTTP/2.
code:bytesThe HTTP status code to write.
reason:bytesThe HTTP reason phrase to write. Unused in HTTP/2.
headers:twisted.web.http_headers.HeadersThe headers to write to the stream.
streamID:intThe ID of the stream to write the headers to.

Undocumented

abortTimeout: int = (source)

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 None, we will wait forever.

The HTTP/2 connection state machine.

A HTTP/2 priority tree used to ensure that responses are prioritised appropriately.

streams: dict, mapping int stream IDs to H2Stream objects. = (source)

A mapping of stream IDs to H2Stream objects, used to call specific methods on streams when events occur.

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

Called when the connection is marked writable again after being marked unwritable. Attempts to flush buffered control data if there is any.

def _handlePriorityUpdate(self, event): (source)

Internal handler for when a stream priority is updated.

Parameters
event:h2.events.PriorityUpdatedThe Hyper-h2 event that encodes information about the stream reprioritization.
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.

Parameters
event:h2.events.WindowUpdatedThe Hyper-h2 event that encodes information about the flow control window change.
def _isSecure(self): (source)

Returns True if this channel is using a secure transport.

Returns
boolTrue if this channel is secure.
def _requestAborted(self, event): (source)

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

Parameters
event:h2.events.StreamResetThe Hyper-h2 event that encodes information about the reset stream.
def _requestDataReceived(self, event): (source)

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

Parameters
event:h2.events.DataReceivedThe Hyper-h2 event that encodes information about the received data.
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.

Parameters
streamID:intThe ID of the stream to clean up state for.
def _requestEnded(self, event): (source)

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

Parameters
event:h2.events.StreamEndedThe Hyper-h2 event that encodes information about the completed stream.
def _requestReceived(self, event): (source)

Internal handler for when a request has been received.

Parameters
event:h2.events.RequestReceivedThe Hyper-h2 event that encodes information about the received request.
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.

Parameters
streamID:intThe ID of the stream that needs the 100 Continue response
def _send100Continue(self, streamID): (source)

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

Parameters
streamID:intThe ID of the stream that needs the 100 Continue response
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 _streamIsActive(self, streamID): (source)

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

Parameters
streamID:intThe ID of the stream that needs processing.
Returns
boolWhether the stream still has state allocated.
def _tryToWriteControlData(self): (source)

Checks whether the connection is blocked on flow control and, if it isn't, writes any buffered control data.

Returns
True if the connection is still active and False if it was aborted because too many bytes have been written but not consumed by the other end.

Undocumented

The twisted.internet.base.DelayedCall that will be used to forcibly close the transport if it doesn't close cleanly.

_bufferedControlFrameBytes: int = (source)

Undocumented

_bufferedControlFrames = (source)

Undocumented

A flag tracking whether or not the IConsumer that is consuming this data has asked us to stop producing.

_maxBufferedControlFrameBytes = (source)

Undocumented

_outboundStreamQueues: A dict mapping int stream IDs to collections.deque queues, which contain either bytes objects or _END_STREAM_SENTINEL. = (source)

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 IConsumer but also to allow priority to multiplex data appropriately.

_reactor = (source)

Undocumented

A handle to the data-sending loop, allowing it to be terminated if needed.

_sendingDeferred = (source)

A 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.

_stillProducing: bool = (source)

Undocumented

_streamCleanupCallbacks: dict = (source)

Undocumented