• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1Python API Reference
2====================
3
4.. py:module:: nghttp2
5
6nghttp2 offers some high level Python API to C library.  The bindings
7currently provide HPACK compressor and decompressor classes and HTTP/2
8server class.
9
10The extension module is called ``nghttp2``.
11
12``make`` will build the bindings.  The target Python version is
13determined by configure script.  If the detected Python version is not
14what you expect, specify a path to Python executable in ``PYTHON``
15variable as an argument to configure script (e.g., ``./configure
16PYTHON=/usr/bin/python3.8``).
17
18HPACK API
19---------
20
21.. py:class:: HDDeflater(hd_table_bufsize_max=DEFLATE_MAX_HEADER_TABLE_SIZE)
22
23   This class is used to perform header compression.  The
24   *hd_table_bufsize_max* limits the usage of header table in the
25   given amount of bytes.  The default value is
26   :py:data:`DEFLATE_MAX_HEADER_TABLE_SIZE`.  This is necessary
27   because the deflater and inflater share the same amount of header
28   table and the inflater decides that number.  The deflater may not
29   want to use all header table size because of limited memory
30   availability.  In that case, *hd_table_bufsize_max* can be used to
31   cap the upper limit of table size whatever the header table size is
32   chosen by the inflater.
33
34   .. py:method:: deflate(headers)
35
36      Deflates the *headers*. The *headers* must be sequence of tuple
37      of name/value pair, which are byte strings (not unicode string).
38
39      This method returns the deflated header block in byte string.
40      Raises the exception if any error occurs.
41
42   .. py:method:: set_no_refset(no_refset)
43
44      Tells the deflater not to use reference set if *no_refset* is
45      evaluated to ``True``.  If that happens, on each subsequent
46      invocation of :py:meth:`deflate()`, deflater will clear up
47      refersent set.
48
49   .. py:method:: change_table_size(hd_table_bufsize_max)
50
51      Changes header table size to *hd_table_bufsize_max* byte.  if
52      *hd_table_bufsize_max* is strictly larger than
53      ``hd_table_bufsize_max`` given in constructor,
54      ``hd_table_bufsize_max`` is used as header table size instead.
55
56      Raises the exception if any error occurs.
57
58   .. py:method:: get_hd_table()
59
60      Returns copy of current dynamic header table.
61
62The following example shows how to deflate header name/value pairs:
63
64.. code-block:: python
65
66   import binascii, nghttp2
67
68   deflater = nghttp2.HDDeflater()
69
70   res = deflater.deflate([(b'foo', b'bar'),
71                           (b'baz', b'buz')])
72
73   print(binascii.b2a_hex(res))
74
75
76.. py:class:: HDInflater()
77
78   This class is used to perform header decompression.
79
80   .. py:method:: inflate(data)
81
82      Inflates the deflated header block *data*. The *data* must be
83      byte string.
84
85      Raises the exception if any error occurs.
86
87   .. py:method:: change_table_size(hd_table_bufsize_max)
88
89      Changes header table size to *hd_table_bufsize_max* byte.
90
91      Raises the exception if any error occurs.
92
93   .. py:method:: get_hd_table()
94
95      Returns copy of current dynamic header table.
96
97The following example shows how to inflate deflated header block:
98
99.. code-block:: python
100
101   deflater = nghttp2.HDDeflater()
102
103   data = deflater.deflate([(b'foo', b'bar'),
104                            (b'baz', b'buz')])
105
106   inflater = nghttp2.HDInflater()
107
108   hdrs = inflater.inflate(data)
109
110   print(hdrs)
111
112
113.. py:function:: print_hd_table(hdtable)
114
115   Convenient function to print *hdtable* to the standard output.  The
116   *hdtable* is the one retrieved by
117   :py:meth:`HDDeflater.get_hd_table()` or
118   :py:meth:`HDInflater.get_hd_table()`.  This function does not work
119   if header name/value cannot be decoded using UTF-8 encoding.
120
121   In output, ``s=N`` means the entry occupies ``N`` bytes in header
122   table.  If ``r=y``, then the entry is in the reference set.
123
124.. py:data:: DEFAULT_HEADER_TABLE_SIZE
125
126   The default header table size, which is 4096 as per HTTP/2
127   specification.
128
129.. py:data:: DEFLATE_MAX_HEADER_TABLE_SIZE
130
131   The default header table size for deflater.  The initial value
132   is 4096.
133
134HTTP/2 servers
135--------------
136
137.. note::
138
139   We use :py:mod:`asyncio` for HTTP/2 server classes, and ALPN.
140   Therefore, Python 3.8 or later is required to use these objects.
141   To explicitly configure nghttp2 build to use Python 3.8, specify
142   the ``PYTHON`` variable to the path to Python 3.8 executable when
143   invoking configure script like this:
144
145   .. code-block:: text
146
147       $ ./configure PYTHON=/usr/bin/python3.8
148
149.. py:class:: HTTP2Server(address, RequestHandlerClass, ssl=None)
150
151   This class builds on top of the :py:mod:`asyncio` event loop.  On
152   construction, *RequestHandlerClass* must be given, which must be a
153   subclass of :py:class:`BaseRequestHandler` class.
154
155   The *address* must be a tuple of hostname/IP address and port to
156   bind.  If hostname/IP address is ``None``, all interfaces are
157   assumed.
158
159   To enable SSL/TLS, specify instance of :py:class:`ssl.SSLContext`
160   in *ssl*.  Before passing *ssl* to
161   :py:func:`BaseEventLoop.create_server`, ALPN protocol identifiers
162   are set using :py:meth:`ssl.SSLContext.set_npn_protocols`.
163
164   To disable SSL/TLS, omit *ssl* or specify ``None``.
165
166   .. py:method:: serve_forever()
167
168      Runs server and processes incoming requests forever.
169
170.. py:class:: BaseRequestHandler(http2, stream_id)
171
172   The class is used to handle the single HTTP/2 stream.  By default,
173   it does not nothing.  It must be subclassed to handle each event
174   callback method.
175
176   The first callback method invoked is :py:meth:`on_headers()`. It is
177   called when HEADERS frame, which includes request header fields, is
178   arrived.
179
180   If request has request body, :py:meth:`on_data()` is invoked for
181   each chunk of received data chunk.
182
183   When whole request is received, :py:meth:`on_request_done()` is
184   invoked.
185
186   When stream is closed, :py:meth:`on_close()` is called.
187
188   The application can send response using :py:meth:`send_response()`
189   method.  It can be used in :py:meth:`on_headers()`,
190   :py:meth:`on_data()` or :py:meth:`on_request_done()`.
191
192   The application can push resource using :py:meth:`push()` method.
193   It must be used before :py:meth:`send_response()` call.
194
195   A :py:class:`BaseRequestHandler` has the following instance
196   variables:
197
198   .. py:attribute:: client_address
199
200      Contains a tuple of the form ``(host, port)`` referring to the
201      client's address.
202
203   .. py:attribute:: stream_id
204
205      Stream ID of this stream
206
207   .. py:attribute:: scheme
208
209      Scheme of the request URI.  This is a value of ``:scheme``
210      header field.
211
212   .. py:attribute:: method
213
214      Method of this stream.  This is a value of ``:method`` header
215      field.
216
217   .. py:attribute:: host
218
219      This is a value of ``:authority`` or ``host`` header field.
220
221   .. py:attribute:: path
222
223      This is a value of ``:path`` header field.
224
225   .. py:attribute:: headers
226
227      Request header fields.
228
229   A :py:class:`BaseRequestHandler` has the following methods:
230
231   .. py:method:: on_headers()
232
233      Called when request HEADERS is arrived.  By default, this method
234      does nothing.
235
236   .. py:method:: on_data(data)
237
238      Called when a chunk of request body *data* is arrived.  This
239      method will be called multiple times until all data are
240      received.  By default, this method does nothing.
241
242   .. py:method:: on_request_done()
243
244      Called when whole request was received.  By default, this method
245      does nothing.
246
247   .. py:method:: on_close(error_code)
248
249      Called when stream is about to close.  The *error_code*
250      indicates the reason of closure.  If it is ``0``, the stream is
251      going to close without error.
252
253   .. py:method:: send_response(status=200, headers=None, body=None)
254
255      Send response.  The *status* is HTTP status code.  The *headers*
256      is additional response headers.  The *:status* header field will
257      be appended by the library.  The *body* is the response body.
258      It could be ``None`` if response body is empty.  Or it must be
259      instance of either ``str``, ``bytes``, :py:class:`io.IOBase` or
260      callable, called body generator, which takes one parameter,
261      size.  The body generator generates response body.  It can pause
262      generation of response so that it can wait for slow backend data
263      generation.  When invoked, it should return tuple, byte string
264      at most size length and flag.  The flag is either
265      :py:data:`DATA_OK`, :py:data:`DATA_EOF` or
266      :py:data:`DATA_DEFERRED`.  For non-empty byte string and it is
267      not the last chunk of response, :py:data:`DATA_OK` must be
268      returned as flag.  If this is the last chunk of the response
269      (byte string could be ``None``), :py:data:`DATA_EOF` must be
270      returned as flag.  If there is no data available right now, but
271      additional data are anticipated, return tuple (``None``,
272      :py:data:`DATA_DEFERRED`).  When data arrived, call
273      :py:meth:`resume()` and restart response body transmission.
274
275      Only the body generator can pause response body generation;
276      instance of :py:class:`io.IOBase` must not block.
277
278      If instance of ``str`` is specified as *body*, it will be
279      encoded using UTF-8.
280
281      The *headers* is a list of tuple of the form ``(name,
282      value)``. The ``name`` and ``value`` can be either byte string
283      or unicode string.  In the latter case, they will be encoded
284      using UTF-8.
285
286      Raises the exception if any error occurs.
287
288   .. py:method:: push(path, method='GET', request_headers=None, status=200, headers=None, body=None)
289
290      Push a specified resource.  The *path* is a path portion of
291      request URI for this resource.  The *method* is a method to
292      access this resource.  The *request_headers* is additional
293      request headers to access this resource.  The ``:scheme``,
294      ``:method``, ``:authority`` and ``:path`` are appended by the
295      library.  The ``:scheme`` and ``:authority`` are inherited from
296      request header fields of the associated stream.
297
298      The *status* is HTTP status code.  The *headers* is additional
299      response headers.  The ``:status`` header field is appended by
300      the library.  The *body* is the response body.  It has the same
301      semantics of *body* parameter of :py:meth:`send_response()`.
302
303      The headers and request_headers are a list of tuple of the form
304      ``(name, value)``. The ``name`` and ``value`` can be either byte
305      string or unicode string.  In the latter case, they will be
306      encoded using UTF-8.
307
308      Returns an instance of ``RequestHandlerClass`` specified in
309      :py:class:`HTTP2Server` constructor for the pushed resource.
310
311      Raises the exception if any error occurs.
312
313   .. py:method:: resume()
314
315      Signals the restarting of response body transmission paused by
316      ``DATA_DEFERRED`` from the body generator (see
317      :py:meth:`send_response()` about the body generator).  It is not
318      an error calling this method while response body transmission is
319      not paused.
320
321.. py:data:: DATA_OK
322
323   ``DATA_OK`` indicates non empty data is generated from body generator.
324
325.. py:data:: DATA_EOF
326
327   ``DATA_EOF`` indicates the end of response body.
328
329.. py:data:: DATA_DEFERRED
330
331   ``DATA_DEFERRED`` indicates that data are not available right now
332   and response should be paused.
333
334The following example illustrates :py:class:`HTTP2Server` and
335:py:class:`BaseRequestHandler` usage:
336
337.. code-block:: python
338
339    #!/usr/bin/env python3
340
341    import io, ssl
342
343    import nghttp2
344
345    class Handler(nghttp2.BaseRequestHandler):
346
347        def on_headers(self):
348            self.push(path='/css/style.css',
349                      request_headers = [('content-type', 'text/css')],
350                      status=200,
351                      body='body{margin:0;}')
352
353            self.send_response(status=200,
354                               headers = [('content-type', 'text/plain')],
355                               body=io.BytesIO(b'nghttp2-python FTW'))
356
357    ctx = ssl.SSLContext(ssl.PROTOCOL_SSLv23)
358    ctx.options = ssl.OP_ALL | ssl.OP_NO_SSLv2 | ssl.OP_NO_SSLv3
359    ctx.load_cert_chain('server.crt', 'server.key')
360
361    # give None to ssl to make the server non-SSL/TLS
362    server = nghttp2.HTTP2Server(('127.0.0.1', 8443), Handler, ssl=ctx)
363    server.serve_forever()
364
365The following example illustrates HTTP/2 server using asynchronous
366response body generation.  This is simplified reverse proxy:
367
368.. code-block:: python
369
370    #!/usr/bin/env python3
371
372    import ssl
373    import os
374    import urllib
375    import asyncio
376    import io
377
378    import nghttp2
379
380    @asyncio.coroutine
381    def get_http_header(handler, url):
382        url = urllib.parse.urlsplit(url)
383        ssl = url.scheme == 'https'
384        if url.port == None:
385            if url.scheme == 'https':
386                port = 443
387            else:
388                port = 80
389        else:
390            port = url.port
391
392        connect = asyncio.open_connection(url.hostname, port, ssl=ssl)
393        reader, writer = yield from connect
394        req = 'GET {path} HTTP/1.0\r\n\r\n'.format(path=url.path or '/')
395        writer.write(req.encode('utf-8'))
396        # skip response header fields
397        while True:
398            line = yield from reader.readline()
399            line = line.rstrip()
400            if not line:
401                break
402        # read body
403        while True:
404            b = yield from reader.read(4096)
405            if not b:
406                break
407            handler.buf.write(b)
408        writer.close()
409        handler.buf.seek(0)
410        handler.eof = True
411        handler.resume()
412
413    class Body:
414        def __init__(self, handler):
415            self.handler = handler
416            self.handler.eof = False
417            self.handler.buf = io.BytesIO()
418
419        def generate(self, n):
420            buf = self.handler.buf
421            data = buf.read1(n)
422            if not data and not self.handler.eof:
423                return None, nghttp2.DATA_DEFERRED
424            return data, nghttp2.DATA_EOF if self.handler.eof else nghttp2.DATA_OK
425
426    class Handler(nghttp2.BaseRequestHandler):
427
428        def on_headers(self):
429            body = Body(self)
430            asyncio.async(get_http_header(
431                self, 'http://localhost' + self.path.decode('utf-8')))
432            self.send_response(status=200, body=body.generate)
433
434    ctx = ssl.SSLContext(ssl.PROTOCOL_SSLv23)
435    ctx.options = ssl.OP_ALL | ssl.OP_NO_SSLv2 | ssl.OP_NO_SSLv3
436    ctx.load_cert_chain('server.crt', 'server.key')
437
438    server = nghttp2.HTTP2Server(('127.0.0.1', 8443), Handler, ssl=ctx)
439    server.serve_forever()
440