J'ai mis en place un simple serveur HTTPS pour pratiquer le module asyncio pour les boucles d'événements et uvloop. uvloop est un module basé sur asyncio et libuv. Depuis 2016, de nouveaux micro-cadres tels que Sanic et japronto avec uvloop ont vu le jour.
En supposant Python 3.6. Dans Python 3.6, la valeur par défaut de SSLContext du module ssl a été modifiée et les constantes ont été consolidées.
uvloop implémente ʻasyncio.AbstractEventLoop` et fournit une API compatible avec uvloop. En raison des contraintes de libuv, uvloop ne prend pas en charge Windows, donc asyncio est responsable du repli uvloop.
Vous pouvez créer un certificat auto-signé avec le one-liner suivant.
# https://stackoverflow.com/a/41366949/531320
openssl req -x509 -newkey rsa:4096 -sha256 \
-nodes -keyout server.key -out server.crt \
-subj "/CN=example.com" -days 3650
Configurons un serveur d'écho qui renvoie une chaîne quelle que soit la méthode HTTP.
server.py
import asyncio
import ssl
async def request_handler(reader, writer):
msg = (
'HTTP/1.1 200 OK\r\n'
'Content-Type: text/plain; charset=utf-8\r\n'
'\r\n'
'hello\r\n'
)
writer.write(msg.encode())
await writer.drain()
writer.close()
host = '127.0.0.1'
port = 8000
ctx = ssl.create_default_context(ssl.Purpose.CLIENT_AUTH)
ctx.load_cert_chain('server.crt', keyfile='server.key')
ctx.options |= ssl.OP_NO_TLSv1 | ssl.OP_NO_TLSv1_1
loop = asyncio.get_event_loop()
coro = asyncio.start_server(
request_handler,
host, port, ssl=ctx, loop=loop
)
server = loop.run_until_complete(coro)
print('Serving on {}'.format(server.sockets[0].getsockname()))
try:
loop.run_forever()
except KeyboardInterrupt:
pass
server.close()
loop.run_until_complete(server.wait_closed())
loop.close()
Créons maintenant un client HTTPS.
client.py
import asyncio
import ssl
async def http_client(host, port, msg, ctx, loop):
reader, writer = await asyncio.open_connection(
host, port, ssl=ctx, loop=loop
)
writer.write(msg.encode())
data = await reader.read()
print("Received: %r" % data.decode())
writer.close()
host = '127.0.0.1'
port = 8000
msg = (
'GET / HTTP/1.1\r\n'
'Host: localhost:8000\r\n'
'\r\n'
'\r\n'
)
ctx = ssl.create_default_context()
ctx.options |= ssl.OP_NO_TLSv1 | ssl.OP_NO_TLSv1_1
ctx.check_hostname = False
ctx.verify_mode = ssl.CERT_NONE
loop = asyncio.get_event_loop()
loop.run_until_complete(http_client(host, port, msg, ctx, loop))
loop.close()
aiohttp
aiohttp est un module HTTP développé basé sur asyncio, et est également livré avec des fonctions de développement d'applications. L'installation est la suivante:
pip3 install aiohttp
Configurons un serveur pour afficher les fichiers HTML.
server.py
from aiohttp import web
from pathlib import Path
import ssl
host='localhost'
port=8000
ctx = ssl.create_default_context(ssl.Purpose.CLIENT_AUTH)
ctx.load_cert_chain('server.crt', keyfile='server.key')
ctx.options |= ssl.OP_NO_TLSv1 | ssl.OP_NO_TLSv1_1
app = web.Application()
app.router.add_static('/static', path=str(Path.cwd().joinpath('static')), show_index=True)
web.run_app(app, host=host, port=port, ssl_context=ctx)
Recommended Posts