1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150
|
.. _aiohttp-server:
Low-level HTTP Server
=====================
.. highlight:: python
.. currentmodule:: aiohttp.server
.. note::
This topic describes the low-level HTTP support. For high-level
interface please take a look on :mod:`aiohttp.web`.
Run a basic server
------------------
Start implementing the basic server by inheriting the
:class:`ServerHttpProtocol` object. Your class should
implement the only method :meth:`ServerHttpProtocol.handle_request`
which must be a coroutine to handle requests asynchronously
.. code-block:: python
from urllib.parse import urlparse, parse_qsl
import aiohttp
import aiohttp.server
from aiohttp.multidict import MultiDict
import asyncio
class HttpRequestHandler(aiohttp.server.ServerHttpProtocol):
@asyncio.coroutine
def handle_request(self, message, payload):
response = aiohttp.Response(
self.writer, 200, http_version=message.version
)
response.add_header('Content-Type', 'text/html')
response.add_header('Content-Length', '18')
response.send_headers()
response.write(b'<h1>It Works!</h1>')
yield from response.write_eof()
The next step is to create a loop and register your handler within a server.
:exc:`KeyboardInterrupt` exception handling is necessary so you can stop
your server with Ctrl+C at any time.
.. code-block:: python
if __name__ == '__main__':
loop = asyncio.get_event_loop()
f = loop.create_server(
lambda: HttpRequestHandler(debug=True, keep_alive=75),
'0.0.0.0', '8080')
srv = loop.run_until_complete(f)
print('serving on', srv.sockets[0].getsockname())
try:
loop.run_forever()
except KeyboardInterrupt:
pass
Headers
-------
Data is passed to the handler in the ``message``, while request body is
passed in ``payload`` param. HTTP headers are accessed through
``headers`` member of the message. To check what the current method of
the request is use the ``method`` member of the ``message``. It should be one
of ``GET``, ``POST``, ``PUT`` or ``DELETE`` strings.
Handling GET params
-------------------
Currently aiohttp does not provide automatic parsing of incoming GET
params. However aiohttp does provide a nice
:class:`MulitiDict` wrapper for already parsed params.
.. code-block:: python
from urllib.parse import urlparse, parse_qsl
from aiohttp.multidict import MultiDict
class HttpRequestHandler(aiohttp.server.ServerHttpProtocol):
@asyncio.coroutine
def handle_request(self, message, payload):
response = aiohttp.Response(
self.writer, 200, http_version=message.version
)
get_params = MultiDict(parse_qsl(urlparse(message.path).query))
print("Passed in GET", get_params)
Handling POST data
------------------
POST data is accessed through the ``payload.read()`` generator method.
If you have form data in the request body, you can parse it in the same way as
GET params.
.. code-block:: python
from urllib.parse import urlparse, parse_qsl
from aiohttp.multidict import MultiDict
class HttpRequestHandler(aiohttp.server.ServerHttpProtocol):
@asyncio.coroutine
def handle_request(self, message, payload):
response = aiohttp.Response(
self.writer, 200, http_version=message.version
)
data = yield from payload.read()
post_params = MultiDict(parse_qsl(data))
print("Passed in POST", post_params)
SSL
---
To use asyncio's SSL support, just pass an SSLContext object to the
:meth:`asyncio.BaseEventLoop.create_server` method of the loop.
.. code-block:: python
import ssl
sslcontext = ssl.SSLContext(ssl.PROTOCOL_SSLv23)
sslcontext.load_cert_chain('sample.crt', 'sample.key')
loop = asyncio.get_event_loop()
loop.create_server(lambda: handler, "0.0.0.0", "8080", ssl=sslcontext)
Reference
---------
.. automodule:: aiohttp.server
:members:
:undoc-members:
:show-inheritance:
.. disqus::
|