320 lines
10 KiB
ReStructuredText
320 lines
10 KiB
ReStructuredText
|
Python API Reference
|
||
|
====================
|
||
|
|
||
|
.. py:module:: nghttp2
|
||
|
|
||
|
nghttp2 offers some high level Python API to C library. The bindings
|
||
|
currently provide HPACK compressor and decompressor classes and HTTP/2
|
||
|
server class.
|
||
|
|
||
|
The extension module is called ``nghttp2``.
|
||
|
|
||
|
``make`` will build the bindings. The target Python version is
|
||
|
determined by configure script. If the detected Python version is not
|
||
|
what you expect, specify a path to Python executable in ``PYTHON``
|
||
|
variable as an argument to configure script (e.g., ``./configure
|
||
|
PYTHON=/usr/bin/python3.4``).
|
||
|
|
||
|
HPACK API
|
||
|
---------
|
||
|
|
||
|
.. py:class:: HDDeflater(hd_table_bufsize_max=DEFLATE_MAX_HEADER_TABLE_SIZE)
|
||
|
|
||
|
This class is used to perform header compression. The
|
||
|
*hd_table_bufsize_max* limits the usage of header table in the
|
||
|
given amount of bytes. The default value is
|
||
|
:py:data:`DEFLATE_MAX_HEADER_TABLE_SIZE`. This is necessary
|
||
|
because the deflater and inflater share the same amount of header
|
||
|
table and the inflater decides that number. The deflater may not
|
||
|
want to use all header table size because of limited memory
|
||
|
availability. In that case, *hd_table_bufsize_max* can be used to
|
||
|
cap the upper limit of table size whatever the header table size is
|
||
|
chosen by the inflater.
|
||
|
|
||
|
.. py:method:: deflate(headers)
|
||
|
|
||
|
Deflates the *headers*. The *headers* must be sequence of tuple
|
||
|
of name/value pair, which are byte strings (not unicode string).
|
||
|
|
||
|
This method returns the deflated header block in byte string.
|
||
|
Raises the exception if any error occurs.
|
||
|
|
||
|
.. py:method:: set_no_refset(no_refset)
|
||
|
|
||
|
Tells the deflater not to use reference set if *no_refset* is
|
||
|
evaluated to ``True``. If that happens, on each subsequent
|
||
|
invocation of :py:meth:`deflate()`, deflater will clear up
|
||
|
refersent set.
|
||
|
|
||
|
.. py:method:: change_table_size(hd_table_bufsize_max)
|
||
|
|
||
|
Changes header table size to *hd_table_bufsize_max* byte. if
|
||
|
*hd_table_bufsize_max* is strictly larger than
|
||
|
``hd_table_bufsize_max`` given in constructor,
|
||
|
``hd_table_bufsize_max`` is used as header table size instead.
|
||
|
|
||
|
Raises the exception if any error occurs.
|
||
|
|
||
|
.. py:method:: get_hd_table()
|
||
|
|
||
|
Returns copy of current dynamic header table.
|
||
|
|
||
|
The following example shows how to deflate header name/value pairs:
|
||
|
|
||
|
.. code-block:: python
|
||
|
|
||
|
import binascii, nghttp2
|
||
|
|
||
|
deflater = nghttp2.HDDeflater()
|
||
|
|
||
|
res = deflater.deflate([(b'foo', b'bar'),
|
||
|
(b'baz', b'buz')])
|
||
|
|
||
|
print(binascii.b2a_hex(res))
|
||
|
|
||
|
|
||
|
.. py:class:: HDInflater()
|
||
|
|
||
|
This class is used to perform header decompression.
|
||
|
|
||
|
.. py:method:: inflate(data)
|
||
|
|
||
|
Inflates the deflated header block *data*. The *data* must be
|
||
|
byte string.
|
||
|
|
||
|
Raises the exception if any error occurs.
|
||
|
|
||
|
.. py:method:: change_table_size(hd_table_bufsize_max)
|
||
|
|
||
|
Changes header table size to *hd_table_bufsize_max* byte.
|
||
|
|
||
|
Raises the exception if any error occurs.
|
||
|
|
||
|
.. py:method:: get_hd_table()
|
||
|
|
||
|
Returns copy of current dynamic header table.
|
||
|
|
||
|
The following example shows how to inflate deflated header block:
|
||
|
|
||
|
.. code-block:: python
|
||
|
|
||
|
deflater = nghttp2.HDDeflater()
|
||
|
|
||
|
data = deflater.deflate([(b'foo', b'bar'),
|
||
|
(b'baz', b'buz')])
|
||
|
|
||
|
inflater = nghttp2.HDInflater()
|
||
|
|
||
|
hdrs = inflater.inflate(data)
|
||
|
|
||
|
print(hdrs)
|
||
|
|
||
|
|
||
|
.. py:function:: print_hd_table(hdtable)
|
||
|
|
||
|
Convenient function to print *hdtable* to the standard output. The
|
||
|
*hdtable* is the one retrieved by
|
||
|
:py:meth:`HDDeflater.get_hd_table()` or
|
||
|
:py:meth:`HDInflater.get_hd_table()`. This function does not work
|
||
|
if header name/value cannot be decoded using UTF-8 encoding.
|
||
|
|
||
|
In output, ``s=N`` means the entry occupies ``N`` bytes in header
|
||
|
table. If ``r=y``, then the entry is in the reference set.
|
||
|
|
||
|
.. py:data:: DEFAULT_HEADER_TABLE_SIZE
|
||
|
|
||
|
The default header table size, which is 4096 as per HTTP/2
|
||
|
specification.
|
||
|
|
||
|
.. py:data:: DEFLATE_MAX_HEADER_TABLE_SIZE
|
||
|
|
||
|
The default header table size for deflater. The initial value
|
||
|
is 4096.
|
||
|
|
||
|
HTTP/2 servers
|
||
|
--------------
|
||
|
|
||
|
.. note::
|
||
|
|
||
|
We use :py:mod:`asyncio` for HTTP/2 server classes. Therefore,
|
||
|
Python 3.4 or later is required to use these objects. To
|
||
|
explicitly configure nghttp2 build to use Python 3.4, specify the
|
||
|
``PYTHON`` variable to the path to Python 3.4 executable when
|
||
|
invoking configure script like this::
|
||
|
|
||
|
$ ./configure PYTHON=/usr/bin/python3.4
|
||
|
|
||
|
.. py:class:: HTTP2Server(address, RequestHandlerClass, ssl=None)
|
||
|
|
||
|
This class builds on top of the :py:mod:`asyncio` event loop. On
|
||
|
construction, *RequestHandlerClass* must be given, which must be a
|
||
|
subclass of :py:class:`BaseRequestHandler` class.
|
||
|
|
||
|
The *address* must be a tuple of hostname/IP address and port to
|
||
|
bind. If hostname/IP address is ``None``, all interfaces are
|
||
|
assumed.
|
||
|
|
||
|
To enable SSL/TLS, specify instance of :py:class:`ssl.SSLContext`
|
||
|
in *ssl*. Before passing *ssl* to
|
||
|
:py:func:`BaseEventLoop.create_server`, ALPN protocol identifiers
|
||
|
are set using :py:meth:`ssl.SSLContext.set_npn_protocols`.
|
||
|
|
||
|
To disable SSL/TLS, omit *ssl* or specify ``None``.
|
||
|
|
||
|
.. py:method:: serve_forever()
|
||
|
|
||
|
Runs server and processes incoming requests forever.
|
||
|
|
||
|
.. py:class:: BaseRequestHandler(http2, stream_id)
|
||
|
|
||
|
The class is used to handle the single HTTP/2 stream. By default,
|
||
|
it does not nothing. It must be subclassed to handle each event
|
||
|
callback method.
|
||
|
|
||
|
The first callback method invoked is :py:meth:`on_headers()`. It is
|
||
|
called when HEADERS frame, which includes request header fields, is
|
||
|
arrived.
|
||
|
|
||
|
If request has request body, :py:meth:`on_data()` is invoked for
|
||
|
each chunk of received data chunk.
|
||
|
|
||
|
When whole request is received, :py:meth:`on_request_done()` is
|
||
|
invoked.
|
||
|
|
||
|
When stream is closed, :py:meth:`on_close()` is called.
|
||
|
|
||
|
The application can send response using :py:meth:`send_response()`
|
||
|
method. It can be used in :py:meth:`on_headers()`,
|
||
|
:py:meth:`on_data()` or :py:meth:`on_request_done()`.
|
||
|
|
||
|
The application can push resource using :py:meth:`push()` method.
|
||
|
It must be used before :py:meth:`send_response()` call.
|
||
|
|
||
|
A :py:class:`BaseRequestHandler` has the following instance
|
||
|
variables:
|
||
|
|
||
|
.. py:attribute:: client_address
|
||
|
|
||
|
Contains a tuple of the form ``(host, port)`` referring to the
|
||
|
client's address.
|
||
|
|
||
|
.. py:attribute:: stream_id
|
||
|
|
||
|
Stream ID of this stream
|
||
|
|
||
|
.. py:attribute:: scheme
|
||
|
|
||
|
Scheme of the request URI. This is a value of ``:scheme``
|
||
|
header field.
|
||
|
|
||
|
.. py:attribute:: method
|
||
|
|
||
|
Method of this stream. This is a value of ``:method`` header
|
||
|
field.
|
||
|
|
||
|
.. py:attribute:: host
|
||
|
|
||
|
This is a value of ``:authority`` or ``host`` header field.
|
||
|
|
||
|
.. py:attribute:: path
|
||
|
|
||
|
This is a value of ``:path`` header field.
|
||
|
|
||
|
A :py:class:`BaseRequestHandler` has the following methods:
|
||
|
|
||
|
.. py:method:: on_headers()
|
||
|
|
||
|
Called when request HEADERS is arrived. By default, this method
|
||
|
does nothing.
|
||
|
|
||
|
.. py:method:: on_data(data)
|
||
|
|
||
|
Called when a chunk of request body *data* is arrived. This
|
||
|
method will be called multiple times until all data are
|
||
|
received. By default, this method does nothing.
|
||
|
|
||
|
.. py:method:: on_request_done()
|
||
|
|
||
|
Called when whole request was received. By default, this method
|
||
|
does nothing.
|
||
|
|
||
|
.. py:method:: on_close(error_code)
|
||
|
|
||
|
Called when stream is about to close. The *error_code*
|
||
|
indicates the reason of closure. If it is ``0``, the stream is
|
||
|
going to close without error.
|
||
|
|
||
|
.. py:method:: send_response(status=200, headers=None, body=None)
|
||
|
|
||
|
Send response. The *status* is HTTP status code. The *headers*
|
||
|
is additional response headers. The *:status* header field will
|
||
|
be appended by the library. The *body* is the response body.
|
||
|
It could be ``None`` if response body is empty. Or it must be
|
||
|
instance of either ``str``, ``bytes`` or :py:class:`io.IOBase`.
|
||
|
If instance of ``str`` is specified, it will be encoded using
|
||
|
UTF-8.
|
||
|
|
||
|
The *headers* is a list of tuple of the form ``(name,
|
||
|
value)``. The ``name`` and ``value`` can be either byte string
|
||
|
or unicode string. In the latter case, they will be encoded
|
||
|
using UTF-8.
|
||
|
|
||
|
Raises the exception if any error occurs.
|
||
|
|
||
|
.. py:method:: push(path, method='GET', request_headers=None, status=200, headers=None, body=None)
|
||
|
|
||
|
Push a specified resource. The *path* is a path portion of
|
||
|
request URI for this resource. The *method* is a method to
|
||
|
access this resource. The *request_headers* is additional
|
||
|
request headers to access this resource. The ``:scheme``,
|
||
|
``:method``, ``:authority`` and ``:path`` are appended by the
|
||
|
library. The ``:scheme`` and ``:authority`` are inherited from
|
||
|
request header fields of the associated stream.
|
||
|
|
||
|
The *status* is HTTP status code. The *headers* is additional
|
||
|
response headers. The ``:status`` header field is appended by
|
||
|
the library. The *body* is the response body. It could be
|
||
|
``None`` if response body is empty. Or it must be instance of
|
||
|
either ``str``, ``bytes`` or ``io.IOBase``. If instance of
|
||
|
``str`` is specified, it is encoded using UTF-8.
|
||
|
|
||
|
The headers and request_headers are a list of tuple of the form
|
||
|
``(name, value)``. The ``name`` and ``value`` can be either byte
|
||
|
string or unicode string. In the latter case, they will be
|
||
|
encoded using UTF-8.
|
||
|
|
||
|
Returns an instance of ``RequestHandlerClass`` specified in
|
||
|
:py:class:`HTTP2Server` constructor for the pushed resource.
|
||
|
|
||
|
Raises the exception if any error occurs.
|
||
|
|
||
|
The following example illustrates :py:class:`HTTP2Server` and
|
||
|
:py:class:`BaseRequestHandler` usage:
|
||
|
|
||
|
.. code-block:: python
|
||
|
|
||
|
#!/usr/bin/env python
|
||
|
|
||
|
import io, ssl
|
||
|
import nghttp2
|
||
|
|
||
|
class Handler(nghttp2.BaseRequestHandler):
|
||
|
|
||
|
def on_headers(self):
|
||
|
self.push(path='/css/style.css',
|
||
|
request_headers = [('content-type', 'text/css')],
|
||
|
status=200,
|
||
|
body='body{margin:0;}')
|
||
|
|
||
|
self.send_response(status=200,
|
||
|
headers = [('content-type', 'text/plain')],
|
||
|
body=io.BytesIO(b'nghttp2-python FTW'))
|
||
|
|
||
|
ctx = ssl.SSLContext(ssl.PROTOCOL_SSLv23)
|
||
|
ctx.options = ssl.OP_ALL | ssl.OP_NO_SSLv2
|
||
|
ctx.load_cert_chain('server.crt', 'server.key')
|
||
|
|
||
|
# give None to ssl to make the server non-SSL/TLS
|
||
|
server = nghttp2.HTTP2Server(('127.0.0.1', 8443), Handler, ssl=ctx)
|
||
|
server.serve_forever()
|