.. _aiohttp-server: Low-level HTTP Server ===================== .. 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 import MultiDict import asyncio class HttpRequestHandler(aiohttp.server.ServerHttpProtocol): async 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'

It Works!

') await 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 import MultiDict class HttpRequestHandler(aiohttp.server.ServerHttpProtocol): async 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 import MultiDict class HttpRequestHandler(aiohttp.server.ServerHttpProtocol): async def handle_request(self, message, payload): response = aiohttp.Response( self.writer, 200, http_version=message.version ) data = await 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::