2024-07-12
한어Русский языкEnglishFrançaisIndonesianSanskrit日本語DeutschPortuguêsΕλληνικάespañolItalianoSuomalainenLatina
start_response
Analyse de la méthodeDans cet article, nous analyserons en détail un serveur WSGI start_response
méthode.Cette méthode est chargée de traiter le code d'état et les en-têtes de réponse de la réponse HTTP et de renvoyer unwrite
Fonction utilisée pour envoyer des données de réponse. Nous expliquerons le fonctionnement de la méthode ligne par ligne et fournirons quelques informations générales pour vous aider à comprendre ses capacités.
WSGI (Web Server Gateway Interface) est une interface standard utilisée pour connecter un serveur Web à une application ou un framework Web. Grâce à WSGI, vous pouvez communiquer entre le serveur et l'application et gérer les requêtes et réponses HTTP.
Lors de la mise en œuvre d'un serveur WSGI,start_response
La méthode est un élément clé appelé par l'application WSGI pour définir l'état de la réponse HTTP et les en-têtes de réponse, et renvoie une fonction pour écrire les données de réponse.
start_response
Implémentation de la méthodeCe qui suit est un exemple typique start_response
Mise en œuvre de la méthode :
def start_response(status, response_headers, exc_info=None):
if exc_info:
try:
if headers_sent:
reraise(*exc_info)
finally:
exc_info = None
elif headers_set:
raise AssertionError("Headers already set")
headers_set[:] = [status, response_headers]
return write
exc_info
paramètreif exc_info:
try:
if headers_sent:
reraise(*exc_info)
finally:
exc_info = None
exc_info
L'argument contient généralement un tuple d'exception au format(type, value, traceback)
, utilisé pour la gestion des exceptions.siexc_info
Pas pourNone
, indiquant qu'il existe une exception qui doit être gérée.try
Contrôles en blocheaders_sent
Si l'en-tête de réponse a été envoyé.Si les en-têtes de réponse ont été envoyés, appelezreraise(*exc_info)
Renvoyez l'exception.finally
block garantit qu'après avoir traité l'exception, leexc_info
mis àNone
pour éviter la duplication du traitement.elif headers_set:
raise AssertionError("Headers already set")
headers_set
La liste contient déjà des valeurs (c'est-à-dire que l'en-tête de réponse a été défini), soulèveAssertionError
anormal.Ce contrôle garantitstart_response
Ne peut être appelé qu’une seule fois pour définir les en-têtes de réponse.headers_set[:] = [status, response_headers]
status
etresponse_headers
assigné àheaders_set
liste.Le but est de retenirheaders_set
référence, mais met à jour son contenu.status
est une chaîne représentant le code d'état et le message de la réponse HTTP, par exemple"200 OK"
。response_headers
est une liste contenant des tuples, chaque tuple représente une paire clé-valeur d'un en-tête de réponse, par exemple[("Content-Type", "text/html"), ("Content-Length", "123")]
。write
fonctionreturn write
start_response
La méthode renvoie unwrite
fonction. Cette fonction est appelée par l'application WSGI pour envoyer des données de réponse.Voici un exemple complet montrant comment utiliser start_response
Méthodes pour gérer les réponses WSGI :
import socketserver
class MyTCPHandler(socketserver.BaseRequestHandler):
def handle(self):
self.headers_set = []
self.headers_sent = []
def start_response(status, response_headers, exc_info=None):
if exc_info:
try:
if self.headers_sent:
raise exc_info[1]
finally:
exc_info = None
elif self.headers_set:
raise AssertionError("Headers already set")
self.headers_set[:] = [status, response_headers]
return self.write
def write(data):
assert self.headers_set, "write() before start_response"
if not self.headers_sent:
status, response_headers = self.headers_sent[:] = self.headers_set
try:
code, msg = status.split(None, 1)
except ValueError:
code, msg = status, ""
code = int(code)
self.send_response(code, msg)
header_keys = set()
for key, value in response_headers:
self.send_header(key, value)
key = key.lower()
header_keys.add(key)
if not (
"content-length" in header_keys
or self.environ["REQUEST_METHOD"] == "HEAD"
or code < 200
or code in (204, 304)
):
self.close_connection = True
self.send_header("Connection", "close")
if "server" not in header_keys:
self.send_header("Server", self.version_string())
if "date" not in header_keys:
self.send_header("Date", self.date_time_string())
self.end_headers()
assert isinstance(data, bytes), "applications must write bytes"
self.wfile.write(data)
self.wfile.flush()
self.write = write
self.environ = self.make_environ()
try:
result = self.server.app(self.environ, start_response)
try:
for data in result:
write(data)
if not self.headers_sent:
write(b"")
finally:
if hasattr(result, "close"):
result.close()
except Exception as e:
self.send_error(500, str(e))
if __name__ == "__main__":
HOST, PORT = "localhost", 9999
with socketserver.TCPServer((HOST, PORT), MyTCPHandler) as server:
print("Server started at {}:{}".format(HOST, PORT))
server.serve_forever()
A travers ce tutoriel, nous avons analysé en détail un serveur WSGI start_response
Méthode qui explique comment elle gère le code d'état et les en-têtes de réponse d'une réponse HTTP, et renvoie une fonction pour écrire les données de réponse. Comprendre ces contenus vous aidera à mieux comprendre la spécification WSGI et à implémenter un serveur WSGI personnalisé. J'espère que ce tutoriel vous sera utile.Pour plus de détails et d'exemples, veuillez vous référer àDocumentation officielle。