Le chapitre "Autoriser la livraison des fichiers HTML" a été mis à jour. ..
Si vous voulez en savoir plus, veuillez "aimer" ou "me suivre" dans Book ;-)
Ce qui suit est un extrait du contenu du livre.
Jusqu'au chapitre précédent, nous avons pu créer un serveur capable de renvoyer une réponse au format HTTP.
Cependant, il n'implémente aucun traitement pour interpréter la requête envoyée depuis le navigateur, donc le corps renvoie toujours «Cela fonctionne!
Cela ne suffit pas, alors préparez à l'avance un fichier HTML séparément du code source du programme afin que le fichier spécifié par le chemin de la requête puisse être renvoyé comme corps de la réponse.
Il s'agit d'une fonction dite de * distribution de fichier statique *.
Il n'est pas nécessaire de publier le code source du serveur via le serveur, alors ** placez les fichiers que vous souhaitez publier via le serveur dans le répertoire study / static /
**
Exemple) Le chemin de la requête est / index.html
=> Le contenu de study / static / index.html
est renvoyé sous forme de corps de réponse
Etc.
Il n'y a rien d'autre à expliquer, alors passons directement au code source.
Voici une version améliorée du fichier HTML préparée à l'avance afin qu'il puisse être renvoyé en tant que corps de réponse.
study/WebServer.py
import os
import socket
from datetime import datetime
class WebServer:
"""
Une classe qui représente un serveur Web
"""
#Répertoire avec fichiers exécutables
BASE_DIR = os.path.dirname(os.path.abspath(__file__))
#Répertoire pour placer les fichiers à livrer de manière statique
DOCUMENT_ROOT = os.path.join(BASE_DIR, "static")
def serve(self):
"""
Démarrez le serveur
"""
print("===Démarrez le serveur===")
try:
#Générer une socket
server_socket = socket.socket()
server_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
#Attribuez le socket au port 8080 de localhost
server_socket.bind(("localhost", 8080))
server_socket.listen(10)
#Attendez une connexion de l'extérieur et établissez une connexion s'il y a une connexion
print("===Attendez une connexion du client===")
(client_socket, address) = server_socket.accept()
print(f"===La connexion avec le client est complète à distance_address: {address} ===")
#Récupérez les données envoyées par le client
request = client_socket.recv(4096)
#Ecrire les données envoyées par le client dans un fichier
with open("server_recv.txt", "wb") as f:
f.write(request)
#La demande entière
# 1.Ligne de demande(La première ligne)
# 2.Demander un corps(2e ligne vierge)
# 3.Demander un corps(Ligne vide ~)
#Analyser
request_line, remain = request.split(b"\r\n", maxsplit=1)
request_headers, request_body = remain.split(b"\r\n\r\n", maxsplit=1)
#Analyser la ligne de demande
method, path, http_version = request_line.decode().split(" ")
#Au début du chemin/Et gardez-le comme un chemin relatif
relative_path = path.lstrip("/")
#Obtenez le chemin du fichier
static_file_path = os.path.join(self.DOCUMENT_ROOT, relative_path)
#Générer le corps de la réponse à partir du fichier
with open(static_file_path, "r") as f:
response_body = f.read()
#Générer une ligne de réponse
response_line = "HTTP/1.1 200 OK\r\n"
#Générer un en-tête de réponse
response_header = ""
response_header += f"Date: {datetime.utcnow().strftime('%a, %d %b %Y %H:%M:%S GMT')}\r\n"
response_header += "Host: HenaServer/0.1\r\n"
response_header += f"Content-Length: {len(response_body.encode())}\r\n"
response_header += "Connection: Close\r\n"
response_header += "Content-Type: text/html\r\n"
#Générer la réponse entière
response = (response_line + response_header + "\r\n" + response_body).encode()
#Envoyer une réponse au client
client_socket.send(response)
#Mettre fin à la communication
client_socket.close()
finally:
print("===Arrêtez le serveur.===")
if __name__ == '__main__':
server = WebServer()
server.serve()
https://github.com/bigen1925/introduction-to-web-application-with-python/blob/main/codes/chapter11/WebServer.py
De plus, pour vérifier si le programme fonctionne correctement, vous devez préparer un fichier HTML séparément, alors créez-le également.
Créez un nouveau répertoire static
directement sous le répertoire study
et créez-y un index.html
.
Comme c'est un gros problème, je l'ai changé pour quelque chose qui n'est pas la rondelle d'Apache. Vous pouvez utiliser ce que vous voulez.
Cependant, si vous changez le nom de fichier, cela ne fonctionnera pas comme décrit dans ce manuel, laissez donc le nom de fichier comme index.html
.
study/static/index.html
<!doctype html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<title>HenaServer</title>
</head>
<body>
<h1>Welcome to HenaServer!</h1>
</body>
</html>
https://github.com/bigen1925/introduction-to-web-application-with-python/blob/main/codes/chapter11/static/index.html
Définit le répertoire dans lequel les fichiers HTML seront placés (appelé DOCUMENT_ROOT
).
#Répertoire avec fichiers exécutables
BASE_DIR = os.path.dirname(os.path.abspath(__file__))
#Répertoire pour placer les fichiers à livrer de manière statique
DOCUMENT_ROOT = os.path.join(BASE_DIR, "static")
Cela peut être difficile à lire si vous n'êtes pas familier avec les chemins de fichiers en python,
--BASE_DIR
: chemin absolu de study
vers le répertoire
--DOCUMENT_ROOT
: chemin absolu du répertoire study / static
Est stocké.
C'est le principal.
La requête HTTP est analysée (décomposée) et les informations de chemin sont extraites.
Après cela, le fichier est lu en fonction du chemin et le corps de la réponse est généré.
#La demande entière
# 1.Ligne de demande(La première ligne)
# 2.Demander un corps(2e ligne vierge)
# 3.Demander un corps(Ligne vide ~)
#Analyser
request_line, remain = request.split(b"\r\n", maxsplit=1)
request_headers, request_body = remain.split(b"\r\n\r\n", maxsplit=1)
#Analyser la ligne de demande
method, path, http_version = request_line.decode().split(" ")
#Au début du chemin/Et gardez-le comme un chemin relatif
relative_path = path.lstrip("/")
#Obtenez le chemin du fichier
static_file_path = os.path.join(self.DOCUMENT_ROOT, relative_path)
#Générer le corps de la réponse à partir du fichier
with open(static_file_path, "r") as f:
response_body = f.read()
Après avoir obtenu le chemin, je le combine avec DOCUMENT_ROOT
pour obtenir le static_file_path
, mais sachez que j'ai supprimé le premier/
avant cela.
C'est parce que la spécification os.path.join (base, path)
de python ignore le premier argument base
si le second argument path
reçoit un chemin absolu commençant par/
. est.
Si vous savez ce que vous voulez faire, le code source n'est pas difficile, alors déplaçons-le immédiatement.
Chapitre "Rendre les fichiers HTML disponibles"
Recommended Posts