kyoukai.backends.http2

A HTTP/2 interface to Kyoukai.

This uses https://python-hyper.org/projects/h2/en/stable/asyncio-example.html as a reference and a base. Massive thanks to the authors of this page.

This server has some notable pitfalls:

  • It ignores any priority data that is sent by the client.
  • It is not paticularly fast (unbenchmarked, but it can be assumed to be slower than the httptools backend.)
  • It does not fully implement all events.

Additionally, this server is untested - it can and probably will fail horribly in production. Use with caution :)

Functions

create_wsgi_environment(r) Creates a new WSGI environment from the RequestData provided.
get_header(headers, name) Gets a header from the list of headers, or None if it doesn’t exist.

Classes

H2KyoukaiComponent(app, ssl_keyfile: str, …) A component subclass that creates H2KyoukaiProtocol instances.
H2KyoukaiProtocol(component, …) The base protocol for Kyoukai, using H2.
H2State(headers: list, stream_id, …) A temporary class that is used to store request data for a HTTP/2 connection.
kyoukai.backends.http2.get_header(headers, name)[source]

Gets a header from the list of headers, or None if it doesn’t exist.

Return type:str
kyoukai.backends.http2.create_wsgi_environment(r)[source]

Creates a new WSGI environment from the RequestData provided.

Return type:MultiDict
class kyoukai.backends.http2.H2State(headers: list, stream_id, protocol: kyoukai.backends.http2.H2KyoukaiProtocol)[source]

Bases: object

A temporary class that is used to store request data for a HTTP/2 connection.

This is also passed to the Werkzeug request to emit data.

insert_data(data)[source]

Writes data from the stream into the body.

coroutine read_async(to_end=True)[source]

There’s no good way to do this - WSGI isn’t async, after all.

However, you can use read_async on the Werkzeug request (which we subclass) to wait until the request has finished streaming.

Parameters:to_end – If to_end is specified, then read until the end of the request. Otherwise, it will read one data chunk.
read(size=-1)[source]

Reads data from the request until it’s all done.

Parameters:size (int) – The maximum amount of data to receive.
Return type:bytes
get_chunk()[source]

Gets a chunk of data from the queue.

Return type:bytes
start_response(status, headers, exc_info=None)[source]

The start_response callable that is plugged into a Werkzeug response.

get_response_headers()[source]

Called by the protocol once the Response is writable to submit the request to the HTTP/2 state machine.

class kyoukai.backends.http2.H2KyoukaiComponent(app, ssl_keyfile: str, ssl_certfile: str, *, ip: str = '127.0.0.1', port: int = 4444)[source]

Bases: kyoukai.asphalt.KyoukaiBaseComponent

A component subclass that creates H2KyoukaiProtocol instances.

Creates a new HTTP/2 SSL-based context.

This will use the HTTP/2 protocol, disabling HTTP/1.1 support for this port. It is possible to run two servers side-by-side, one HTTP/2 and one HTTP/1.1, if you run them on different ports.

get_server_name()
Returns:The server name of this app.
class kyoukai.backends.http2.H2KyoukaiProtocol(component, parent_context: asphalt.core.context.Context)[source]

Bases: asyncio.protocols.Protocol

The base protocol for Kyoukai, using H2.

raw_write(data)[source]

Writes to the underlying transport.

connection_made(transport)[source]

Called when a connection is made.

Parameters:transport (WriteTransport) – The transport made by the connection.
data_received(data)[source]

Called when data is received from the underlying socket.

_processing_done(environ, stream_id)[source]

Callback for when processing is done on a request.

coroutine sending_loop(stream_id)[source]

This loop continues sending data to the client as it comes off of the queue.

request_received(event)[source]

Called when a request has been received.

window_opened(event)[source]

Called when a control flow window has opened again.

receive_data(event)[source]

Called when a request has data that has been received.

stream_complete(event)[source]

Called when a stream is complete.

This will invoke Kyoukai, which will handle the request.

close(error_code=0)[source]

Called to terminate the connection for some reason.

This will close the underlying transport.

eof_received()

Called when the other end calls write_eof() or equivalent.

If this returns a false value (including None), the transport will close itself. If it returns a true value, closing the transport is up to the protocol.

pause_writing()

Called when the transport’s buffer goes over the high-water mark.

Pause and resume calls are paired – pause_writing() is called once when the buffer goes strictly over the high-water mark (even if subsequent writes increases the buffer size even more), and eventually resume_writing() is called once when the buffer size reaches the low-water mark.

Note that if the buffer size equals the high-water mark, pause_writing() is not called – it must go strictly over. Conversely, resume_writing() is called when the buffer size is equal or lower than the low-water mark. These end conditions are important to ensure that things go as expected when either mark is zero.

NOTE: This is the only Protocol callback that is not called through EventLoop.call_soon() – if it were, it would have no effect when it’s most needed (when the app keeps writing without yielding until pause_writing() is called).

resume_writing()

Called when the transport’s buffer drains below the low-water mark.

See pause_writing() for details.