diff --git a/gunicorn/workers/_gaiohttp.py b/gunicorn/workers/_gaiohttp.py index df59c9c0..b3ebc0f4 100644 --- a/gunicorn/workers/_gaiohttp.py +++ b/gunicorn/workers/_gaiohttp.py @@ -7,6 +7,12 @@ import asyncio import functools import logging import os + +try: + import ssl +except ImportError: + ssl = None + import gunicorn.workers.base as base from aiohttp.wsgi import WSGIServerHttpProtocol @@ -16,7 +22,11 @@ class AiohttpWorker(base.Worker): def __init__(self, *args, **kw): # pragma: no cover super().__init__(*args, **kw) - + cfg = self.cfg + if cfg.is_ssl: + self.ssl_context = self._create_ssl_context(cfg) + else: + self.ssl_context = None self.servers = [] self.connections = {} @@ -74,7 +84,7 @@ class AiohttpWorker(base.Worker): for sock in self.sockets: factory = self.get_factory(sock.sock, sock.cfg_addr) self.servers.append( - (yield from self.loop.create_server(factory, sock=sock.sock))) + (yield from self._create_server(factory, sock))) # If our parent changed then we shut down. pid = os.getpid() @@ -112,6 +122,26 @@ class AiohttpWorker(base.Worker): yield from self.close() + @asyncio.coroutine + def _create_server(self, factory, sock): + return self.loop.create_server(factory, sock=sock.sock, + ssl=self.ssl_context) + + @staticmethod + def _create_ssl_context(cfg): + """ Creates SSLContext instance for usage in asyncio.create_server. + + See ssl.SSLSocket.__init__ for more details. + """ + ctx = ssl.SSLContext(cfg.ssl_version) + ctx.load_cert_chain(cfg.certfile, cfg.keyfile) + ctx.verify_mode = cfg.cert_reqs + if cfg.ca_certs: + ctx.load_verify_locations(cfg.ca_certs) + if cfg.ciphers: + ctx.set_ciphers(cfg.ciphers) + return ctx + class _wrp: