# ``twisted`.`web`.`http`.`HTTPChannel``

class documentation

`class HTTPChannel(basic.LineReceiver, policies.TimeoutMixin): (source)`

Known subclasses: `twisted.web.proxy.Proxy`, `twisted.web.proxy.ReverseProxy`

Implements interfaces: `twisted.internet.interfaces.IConsumer`, `twisted.internet.interfaces.IPushProducer`, `twisted.internet.interfaces.ITransport`

View In Hierarchy

A receiver for HTTP requests.

The `HTTPChannel` provides `interfaces.ITransport` and `interfaces.IConsumer` to the `Request` objects it creates. It also implements `interfaces.IPushProducer` to `self.transport`, allowing the transport to pause it.

Method | `__init__` | Undocumented
Method | `allContentReceived` | Undocumented
Method | `allHeadersReceived` | Undocumented
Method | `checkPersistence` | Check if the channel should close or not.
Method | `connectionLost` | Called when the connection is shut down.
Method | `connectionMade` | Called when a connection is made.
Method | `forceAbortClient` | No summary
Method | `getHost` | Get the local address of this connection.
Method | `getPeer` | Get the remote address of this connection.
Method | `headerReceived` | Do pre-processing (for content-length) and store this header away. Enforce the per-request header limit.
Method | `isSecure` | Return `True` if this channel is using a secure transport.
Method | `lineReceived` | Called for each line from request until the end of headers when it enters binary mode.
Method | `loseConnection` | Closes the connection. Will write any data that is pending to be sent on the network, but if this response has not yet been written to the network will not write anything.
Method | `pauseProducing` | Pause producing data.
Method | `rawDataReceived` | This is called when this HTTP/1.1 parser is in raw mode rather than line mode.
Method | `registerProducer` | Register to receive data from a producer.
Method | `requestDone` | Called by first request in queue when it is done.
Method | `resumeProducing` | Resume producing data.
Method | `stopProducing` | Stop producing data.
Method | `timeoutConnection` | Called when the connection times out.
Method | `unregisterProducer` | Stop consuming data from a producer, without disconnecting.
Method | `write` | Called by `Request` objects to write response data.
Method | `writeHeaders` | Called by `Request` objects to write a complete set of HTTP headers to a transport.
Method | `writeSequence` | Write a list of strings to the HTTP response.
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. If this is `None`, we will wait forever.
Instance Variable | `length` | Undocumented
Instance Variable | `MAX_LENGTH` | Maximum length for initial request line and each line from the header.
Instance Variable | `maxHeaders` | Maximum number of headers allowed per request.
Instance Variable | `persistent` | Undocumented
Instance Variable | `requests` | Undocumented
Instance Variable | `totalHeadersSize` | Maximum bytes for request line plus all headers from the request.
Method | `_finishRequestBody` | Undocumented
Method | `_maybeChooseTransferDecoder` | If the provided header is `content-length` or `transfer-encoding`, choose the appropriate decoder if any.
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.
Class Variable | `__content` | Undocumented
Class Variable | `_log` | Undocumented
Instance Variable | `__first_line` | Undocumented
Instance Variable | `__header` | 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 | `_command` | Undocumented
Instance Variable | `_dataBuffer` | Any data that has been received from the connection while processing an outstanding request.
Instance Variable | `_handlingRequest` | Whether a request is currently being processed.
Instance Variable | `_networkProducer` | Either the transport, if it provides `interfaces.IPushProducer`, or a null implementation of `interfaces.IPushProducer`. Used to attempt to prevent the transport from producing excess data when we're responding to a request.

Instance Variable

`_optimisticEagerReadSize`

When a resource takes a long time to answer a request (via `twisted.web.server.NOT_DONE_YET`, hopefully one day by a `Deferred`), we would like to be able to let that resource know about the underlying transport disappearing as promptly as possible, via `Request.notifyFinish`, and therefore via `self.requests[...].connectionLost()` on this `HTTPChannel`.

Instance Variable | `_path` | Undocumented
Instance Variable | `_receivedHeaderCount` | Undocumented
Instance Variable | `_receivedHeaderSize` | Bytes received so far for the header.
Instance Variable | `_requestProducer` | If the `Request` object or anything it calls registers itself as an `interfaces.IProducer`, it will be stored here. This is used to create a producing pipeline: pause/resume producing methods will be propagated from the `transport`, through the `HTTPChannel` instance, to the c{_requestProducer}.
Instance Variable | `_requestProducerStreaming` | A boolean that tracks whether the producer on the `Request` side of this channel has registered itself as a `interfaces.IPushProducer` or an `interfaces.IPullProducer`.
Instance Variable | `_savedTimeOut` | Undocumented
Instance Variable | `_transferDecoder` | `None` or a decoder instance if the request body uses the chunked Transfer-Encoding.
Instance Variable | `_version` | Undocumented
Instance Variable | `_waitingForTransport` | A boolean that tracks whether the transport has asked us to stop producing. This is used to keep track of what we're waiting for: if the transport has asked us to stop producing then we don't want to unpause the transport until it asks us to produce again.

Inherited from `LineReceiver`:

Method | `clearLineBuffer` | Clear buffered data.
Method | `dataReceived` | Protocol.dataReceived. Translates bytes into lines, and calls lineReceived (or rawDataReceived, depending on mode.)
Method | `lineLengthExceeded` | Called when the maximum line length has been reached. Override if it needs to be dealt with in some special way.
Method | `sendLine` | Sends a line to the other end of the connection.
Method | `setLineMode` | Sets the line-mode of this receiver.
Method | `setRawMode` | Sets the raw mode of this receiver. Further data received will be sent to rawDataReceived rather than lineReceived.
Class Variable | `delimiter` | The line-ending delimiter to use. By default this is `b'\r\n'`.
Instance Variable | `line_mode` | Undocumented
Instance Variable | `_buffer` | Undocumented
Instance Variable | `_busyReceiving` | Undocumented

Inherited from `Protocol` (via `LineReceiver`):

Method | `logPrefix` | Return a prefix matching the class name, to identify log messages related to this protocol instance.
Class Variable | `factory` | Undocumented

Inherited from `BaseProtocol` (via `LineReceiver`, `Protocol`):

Method | `makeConnection` | Make a connection to a transport and a server.
Instance Variable | `connected` | Undocumented
Instance Variable | `transport` | Undocumented

Inherited from `_PauseableMixin` (via `LineReceiver`):

Instance Variable | `paused` | Undocumented

Inherited from `TimeoutMixin`:

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): (source)

Undocumented

def allContentReceived(self): (source)

Undocumented

def allHeadersReceived(self): (source)

Undocumented

def checkPersistence(self, request, version): (source)
Check if the channel should close or not.

Parameters
request | The request most recently received over this channel against which checks will be made to determine if this connection can remain open after a matching response is returned.
version:`bytes` | The version of the request.
Returns
`bool` | A flag which, if `True`, indicates that this connection may remain open to receive another request; if `False`, the connection must be closed in order to indicate the completion of the response to `request`.

def connectionLost(self, reason): (source)
from `twisted.internet.interfaces.IProtocol`
overrides `twisted.internet.protocol.Protocol.connectionLost`

Called when the connection is shut down.

Clear any circular references here, and any external references to this Protocol. The connection has been closed.

Parameters
reason:`twisted.python.failure.Failure` | Undocumented

def connectionMade(self): (source)
from `twisted.internet.interfaces.IProtocol`
overrides `twisted.internet.protocol.BaseProtocol.connectionMade`

Called when a connection is made.

This may be considered the initializer of the protocol, because it is called when the connection is completed. For clients, this is called once the connection to the server has been established; for servers, this is called after an accept() call stops blocking and a socket has been received. If you need to send any greeting or initial message, do it here.

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)
from `twisted.internet.interfaces.ITransport`
Get the local address of this connection.

Returns
An `IAddress` provider.

def getPeer(self): (source)
from `twisted.internet.interfaces.ITransport`
Get the remote address of this connection.

Returns
An `IAddress` provider.

def headerReceived(self, line): (source)
Do pre-processing (for content-length) and store this header away. Enforce the per-request header limit.

Parameters
line:`bytes` | A line from the header section of a request, excluding the line delimiter.
Returns
`bool` | A flag indicating whether the header was valid.

def isSecure(self): (source)

Return `True` if this channel is using a secure transport.

Normally this method returns `True` if this instance is using a transport that implements `interfaces.ISSLTransport`.

Returns
`bool` | `True` if this request is secure

def lineReceived(self, line): (source)
overrides `twisted.protocols.basic.LineReceiver.lineReceived`
Called for each line from request until the end of headers when it enters binary mode.
def loseConnection(self): (source)
from `twisted.internet.interfaces.ITransport`
Closes the connection. Will write any data that is pending to be sent on the network, but if this response has not yet been written to the network will not write anything.

Returns
`None`

def pauseProducing(self): (source)
from `twisted.internet.interfaces.IPushProducer`
overrides `twisted.protocols.basic._PauseableMixin.pauseProducing`

Pause producing data.

This will be called by the transport when the send buffers have been filled up. We want to simultaneously pause the producing `Request` object and also pause our transport.

The logic behind pausing the transport is specifically to avoid issues like https://twistedmatrix.com/trac/ticket/8868. In this case, our inability to send does not prevent us handling more requests, which means we increasingly queue up more responses in our send buffer without end. The easiest way to handle this is to ensure that if we are unable to send our responses, we will not read further data from the connection until the client pulls some data out. This is a bit of a blunt instrument, but it's ok.

Note that this potentially interacts with timeout handling in a positive way. Once the transport is paused the client may run into a timeout which will cause us to tear the connection down. That's a good thing!

def rawDataReceived(self, data): (source)
overrides `twisted.protocols.basic.LineReceiver.rawDataReceived`

This is called when this HTTP/1.1 parser is in raw mode rather than line mode.

It may be in raw mode for one of two reasons:

1. All the headers of a request have been received and this `HTTPChannel` is currently receiving its body.
2. The full content of a request has been received and is currently being processed asynchronously, and this `HTTPChannel` is buffering the data of all subsequent requests to be parsed later.

In the second state, the data will be played back later.

Parameters
data:`bytes` | Undocumented
See Also
`LineReceive.rawDataReceived`
Note
This isn't really a public API, and should be invoked only by `LineReceiver`'s line parsing logic. If you wish to drive an `HTTPChannel` from a custom data source, call `dataReceived` on it directly.

def registerProducer(self, producer, streaming): (source)
from `twisted.internet.interfaces.IConsumer`

Register to receive data from a producer.

This sets self to be a consumer for a producer. When this object runs out of data (as when a send(2) call on a socket succeeds in moving the last data from a userspace buffer into a kernelspace buffer), it will ask the producer to resumeProducing().

For `IPullProducer` providers, `resumeProducing` will be called once each time data is required.

For `IPushProducer` providers, `pauseProducing` will be called whenever the write buffer fills up and `resumeProducing` will only be called when it empties.

Parameters
producer:`IProducer` provider | The `IProducer` that will be producing data.
streaming:`bool` | `True` if `producer` provides `IPushProducer`, `False` if `producer` provides `IPullProducer`.
Returns
`None`
Raises
`RuntimeError` | If a producer is already registered.

def requestDone(self, request): (source)
Called by first request in queue when it is done.
def resumeProducing(self): (source)
from `twisted.internet.interfaces.IPushProducer`
overrides `twisted.protocols.basic._PauseableMixin.resumeProducing`

Resume producing data.

This will be called by the transport when the send buffer has dropped enough to actually send more data. When this happens we can unpause any outstanding `Request` producers we have, and also unpause our transport.

def stopProducing(self): (source)
from `twisted.internet.interfaces.IProducer`
overrides `twisted.protocols.basic._PauseableMixin.stopProducing`

Stop producing data.

The HTTPChannel doesn't *actually* implement this, beacuse the assumption is that it will only be called just before `loseConnection` is called. There's nothing sensible we can do other than call `loseConnection` anyway.

def timeoutConnection(self): (source)
overrides `twisted.protocols.policies.TimeoutMixin.timeoutConnection`

Called when the connection times out.

Override to define behavior other than dropping the connection.

def unregisterProducer(self): (source)
from `twisted.internet.interfaces.IConsumer`
Stop consuming data from a producer, without disconnecting.

Returns
`None`

def write(self, data): (source)
from `twisted.internet.interfaces.ITransport`
Called by `Request` objects to write response data.

Parameters
data:`bytes` | The data chunk to write to the stream.
Returns
`None`

def writeHeaders(self, version, code, reason, headers): (source)
Called by `Request` objects to write a complete set of HTTP headers to a transport.

Parameters
version:`bytes` | The HTTP version in use.
code:`bytes` | The HTTP status code to write.
reason:`bytes` | The HTTP reason phrase to write.
headers:`twisted.web.http_headers.Headers` | The headers to write to the transport.

def writeSequence(self, iovec): (source)
from `twisted.internet.interfaces.ITransport`
Write a list of strings to the HTTP response.

Parameters
iovec:`list` of `bytes` | A list of byte strings to write to the stream.
Returns
`None`

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.
length: `int` = (source)

Undocumented

MAX_LENGTH = (source)
overrides `twisted.protocols.basic.LineReceiver.MAX_LENGTH`
Maximum length for initial request line and each line from the header.
maxHeaders: `int` = (source)
Maximum number of headers allowed per request.
persistent = (source)

Undocumented

requests: `list` = (source)

Undocumented

totalHeadersSize: `int` = (source)
Maximum bytes for request line plus all headers from the request.
def _finishRequestBody(self, data): (source)

Undocumented

def _maybeChooseTransferDecoder(self, header, data): (source)

If the provided header is `content-length` or `transfer-encoding`, choose the appropriate decoder if any.

Returns `True` if the request can proceed and `False` if not.

def _respondToBadRequestAndDisconnect(self): (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.

def _send100Continue(self): (source)
Sends a 100 Continue response, used to signal to clients that further processing will be performed.
__content = (source)

Undocumented

_log = (source)

Undocumented

__first_line: `int` = (source)

Undocumented

__header = (source)

Undocumented

_abortingCall: `twisted.internet.base.DelayedCall` = (source)
The `twisted.internet.base.DelayedCall` that will be used to forcibly close the transport if it doesn't close cleanly.
_command = (source)

Undocumented

_dataBuffer: `list` of `bytes` = (source)
Any data that has been received from the connection while processing an outstanding request.
_handlingRequest: `bool` = (source)
Whether a request is currently being processed.
_networkProducer: `interfaces.IPushProducer` = (source)
Either the transport, if it provides `interfaces.IPushProducer`, or a null implementation of `interfaces.IPushProducer`. Used to attempt to prevent the transport from producing excess data when we're responding to a request.
_optimisticEagerReadSize: `int` = (source)

When a resource takes a long time to answer a request (via `twisted.web.server.NOT_DONE_YET`, hopefully one day by a `Deferred`), we would like to be able to let that resource know about the underlying transport disappearing as promptly as possible, via `Request.notifyFinish`, and therefore via `self.requests[...].connectionLost()` on this `HTTPChannel`.

However, in order to simplify application logic, we implement head-of-line blocking, and do not relay pipelined requests to the application until the previous request has been answered. This means that said application cannot dispose of any entity-body that comes in from those subsequent requests, which may be arbitrarily large, and it may need to be buffered in memory.

To implement this tradeoff between prompt notification when possible (in the most frequent case of non-pipelined requests) and correct behavior when not (say, if a client sends a very long-running GET request followed by a PUT request with a very large body) we will continue reading pipelined requests into `self._dataBuffer` up to a given limit.

`_optimisticEagerReadSize` is the number of bytes we will accept from the client and buffer before pausing the transport.

This behavior has been in place since Twisted 17.9.0 .

_path = (source)

Undocumented

_receivedHeaderCount: `int` = (source)

Undocumented

_receivedHeaderSize: `int` = (source)
Bytes received so far for the header.
_requestProducer: `interfaces.IPushProducer` = (source)

If the `Request` object or anything it calls registers itself as an `interfaces.IProducer`, it will be stored here. This is used to create a producing pipeline: pause/resume producing methods will be propagated from the `transport`, through the `HTTPChannel` instance, to the c{_requestProducer}.

The reason we proxy through the producing methods rather than the old behaviour (where we literally just set the `Request` object as the producer on the transport) is because we want to be able to exert backpressure on the client to prevent it from sending in arbitrarily many requests without ever reading responses. Essentially, if the client never reads our responses we will eventually stop reading its requests.

_requestProducerStreaming: `bool` or `None` = (source)
A boolean that tracks whether the producer on the `Request` side of this channel has registered itself as a `interfaces.IPushProducer` or an `interfaces.IPullProducer`.
_savedTimeOut = (source)

Undocumented

_transferDecoder: `_ChunkedTransferDecoder` = (source)
`None` or a decoder instance if the request body uses the chunked Transfer-Encoding.
_version = (source)

Undocumented

_waitingForTransport: `bool` = (source)
A boolean that tracks whether the transport has asked us to stop producing. This is used to keep track of what we're waiting for: if the transport has asked us to stop producing then we don't want to unpause the transport until it asks us to produce again.