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