r"""A non-blocking, single-threaded HTTP server. A server is defined by a subclass of `.HTTPServerConnectionDelegate`, or, for backwards compatibility, a callback that takes an `.HTTPServerRequest` as an argument. The delegate is usually a `tornado.web.Application`. `HTTPServer
| 44 | |
| 45 | |
| 46 | class HTTPServer(TCPServer, Configurable, httputil.HTTPServerConnectionDelegate): |
| 47 | r"""A non-blocking, single-threaded HTTP server. |
| 48 | |
| 49 | A server is defined by a subclass of `.HTTPServerConnectionDelegate`, |
| 50 | or, for backwards compatibility, a callback that takes an |
| 51 | `.HTTPServerRequest` as an argument. The delegate is usually a |
| 52 | `tornado.web.Application`. |
| 53 | |
| 54 | `HTTPServer` supports keep-alive connections by default |
| 55 | (automatically for HTTP/1.1, or for HTTP/1.0 when the client |
| 56 | requests ``Connection: keep-alive``). |
| 57 | |
| 58 | If ``xheaders`` is ``True``, we support the |
| 59 | ``X-Real-Ip``/``X-Forwarded-For`` and |
| 60 | ``X-Scheme``/``X-Forwarded-Proto`` headers, which override the |
| 61 | remote IP and URI scheme/protocol for all requests. These headers |
| 62 | are useful when running Tornado behind a reverse proxy or load |
| 63 | balancer. The ``protocol`` argument can also be set to ``https`` |
| 64 | if Tornado is run behind an SSL-decoding proxy that does not set one of |
| 65 | the supported ``xheaders``. |
| 66 | |
| 67 | By default, when parsing the ``X-Forwarded-For`` header, Tornado will |
| 68 | select the last (i.e., the closest) address on the list of hosts as the |
| 69 | remote host IP address. To select the next server in the chain, a list of |
| 70 | trusted downstream hosts may be passed as the ``trusted_downstream`` |
| 71 | argument. These hosts will be skipped when parsing the ``X-Forwarded-For`` |
| 72 | header. |
| 73 | |
| 74 | To make this server serve SSL traffic, send the ``ssl_options`` keyword |
| 75 | argument with an `ssl.SSLContext` object. For compatibility with older |
| 76 | versions of Python ``ssl_options`` may also be a dictionary of keyword |
| 77 | arguments for the `ssl.SSLContext.wrap_socket` method.:: |
| 78 | |
| 79 | ssl_ctx = ssl.create_default_context(ssl.Purpose.CLIENT_AUTH) |
| 80 | ssl_ctx.load_cert_chain(os.path.join(data_dir, "mydomain.crt"), |
| 81 | os.path.join(data_dir, "mydomain.key")) |
| 82 | HTTPServer(application, ssl_options=ssl_ctx) |
| 83 | |
| 84 | `HTTPServer` initialization follows one of three patterns (the |
| 85 | initialization methods are defined on `tornado.tcpserver.TCPServer`): |
| 86 | |
| 87 | 1. `~tornado.tcpserver.TCPServer.listen`: single-process:: |
| 88 | |
| 89 | async def main(): |
| 90 | server = HTTPServer() |
| 91 | server.listen(8888) |
| 92 | await asyncio.Event().wait() |
| 93 | |
| 94 | asyncio.run(main()) |
| 95 | |
| 96 | In many cases, `tornado.web.Application.listen` can be used to avoid |
| 97 | the need to explicitly create the `HTTPServer`. |
| 98 | |
| 99 | While this example does not create multiple processes on its own, when |
| 100 | the ``reuse_port=True`` argument is passed to ``listen()`` you can run |
| 101 | the program multiple times to create a multi-process service. |
| 102 | |
| 103 | 2. `~tornado.tcpserver.TCPServer.add_sockets`: multi-process:: |
no outgoing calls