[PYTHON] Configurer un serveur HTTPS simple avec asyncio

Aperçu

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.

supposition

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.

À propos d'uvloop

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.

Créer un certificat auto-signé

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

Configurer un serveur HTTPS

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éer un client HTTPS

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

Configurer un serveur HTTPS simple avec asyncio
Configurer un serveur HTTPS simple avec Python 3
[Vagrant] Configurer un serveur API simple avec python
Configurer un serveur Samba avec Docker
Configurer un serveur local avec le téléchargement Go-File-
Configurer un serveur local avec le téléchargement Go-File-
Configurer un serveur SMTP simple en Python
Configurer un serveur local simple sur votre Mac
Configurer un serveur Web avec CentOS7 + Anaconda + Django + Apache
Configurer un serveur de messagerie avec Twisted
Envoyez du courrier avec mailx à un serveur SMTP factice configuré avec python.
Démarrez un serveur Web Python simple avec Docker
Configurez un serveur SMTP de test en Python.
Configurer un serveur UDP en langage C
Configurer un proxy inverse vers le serveur https avec CentOS Linux 8 + Apache mod_ssl
Comment configurer un serveur de développement local
Introduction et utilisation de la bouteille Python ・ Essayez de configurer un serveur Web simple avec une fonction de connexion
Configurer un serveur de ressources Minecraft (Spigot) via docker (2)
Configurer un serveur de fichiers sur Ubuntu 20.04 à l'aide de Samba
Configurez un serveur gratuit sur AWS en 30 minutes
[Partie 1] Configurons un serveur Micra sur Linux
Configurer un serveur de ressources Minecraft (Spigot) via docker
Configurer un environnement de développement Python avec Sublime Text 2
Créer un serveur REST (simple)
Créer un serveur textlint simple
Configurer un environnement de développement Python avec Visual Studio Code
Recharger le serveur configuré avec gunicorn lors du changement de code
Comment configurer un serveur SMTP simple qui peut être testé localement en Python
Configurer la connexion sociale avec Django
Configurer pygit2 avec un lien statique
Créer un serveur Flask avec Docker
Ecrire un serveur TCP super simple
Créer un fichier power simple avec Python
Lecteur RSS simple réalisé avec Django
Construisez un serveur WebDAV simple sur Linux
Définissez la fonction Lambda et laissez-la fonctionner avec les événements S3!
Dessinez un ensemble de Mandelbrot avec Brainf * ck
Faisons un langage simple avec PLY 1
Créez une application Web simple avec Flask
Configurez un serveur Web local en 30 secondes en utilisant http.server en python 3
Configurer un serveur qui traite plusieurs connexions en même temps
J'ai fait un simple blackjack avec Python
Mettez Docker dans Windows Home et exécutez un serveur Web simple avec Python
Démarrez un serveur http temporaire localement avec Pytest
Créer un serveur local avec une commande sur une seule ligne [Mac]
Configurer Golang avec goenv sur GNU / Linux
Créez un simple générateur d'images par points avec Flask
Serveur de jeu avec deux PC
J'ai fait un simple portefeuille de Bitcoin avec pycoin
Lancer un serveur Web avec Python et Flask
Configurer un environnement de développement Python sur Marvericks
Liste de tâches simple créée avec Python + Django
Monter le répertoire d'un autre serveur avec sshfs
Créer un serveur "Hello World" (HTTP) dans Tornado
Comment préparer l'environnement pour Google Colab avec le cours avancé d'apprentissage automatique de Coursera
Configurer un serveur de fichiers en utilisant samba avec ZeroPi de Friendly Arm [installation du système d'exploitation]
[Mac] Je souhaite créer un serveur HTTP simple qui exécute CGI avec Python