2024-07-12
한어Русский языкEnglishFrançaisIndonesianSanskrit日本語DeutschPortuguêsΕλληνικάespañolItalianoSuomalainenLatina
start_response
MethodenanalyseIn diesem Artikel analysieren wir einen WSGI-Server im Detail start_response
Methode.Diese Methode ist dafür verantwortlich, den Statuscode und die Antwortheader der HTTP-Antwort zu verarbeiten und eine zurückzugebenwrite
Funktion zum Senden von Antwortdaten. Wir erklären Zeile für Zeile, wie die Methode funktioniert, und geben einige Hintergrundinformationen, um ihre Fähigkeiten zu verstehen.
WSGI (Web Server Gateway Interface) ist eine Standardschnittstelle, die zum Verbinden eines Webservers mit einer Webanwendung oder einem Framework verwendet wird. Über WSGI können Sie zwischen dem Server und der Anwendung kommunizieren und HTTP-Anfragen und -Antworten verarbeiten.
Bei der Implementierung eines WSGI-Serversstart_response
Die Methode ist ein Schlüsselbestandteil, der von der WSGI-Anwendung aufgerufen wird, um den HTTP-Antwortstatus und die Antwortheader festzulegen, und eine Funktion zum Schreiben der Antwortdaten zurückgibt.
start_response
MethodenimplementierungDas Folgende ist ein typisches Beispiel start_response
Methodenimplementierung:
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
Parameterif exc_info:
try:
if headers_sent:
reraise(*exc_info)
finally:
exc_info = None
exc_info
Das Argument enthält normalerweise ein Ausnahmetupel im Format(type, value, traceback)
, wird für die Ausnahmebehandlung verwendet.Wennexc_info
Nicht fürNone
, was darauf hinweist, dass eine Ausnahme vorliegt, die behandelt werden muss.try
Blockinterne Kontrollenheaders_sent
Ob der Antwortheader gesendet wurde.Wenn die Antwortheader gesendet wurden, rufen Sie anreraise(*exc_info)
Die Ausnahme erneut auslösen.finally
Der Block stellt sicher, dass nach der Behandlung der Ausnahme dieexc_info
einstellenNone
um eine Doppelverarbeitung zu vermeiden.elif headers_set:
raise AssertionError("Headers already set")
headers_set
Die Liste enthält bereits Werte (d. h. der Antwortheader wurde gesetzt), löst ausAssertionError
abnormal.Diese Prüfung stellt sicherstart_response
Kann nur einmal aufgerufen werden, um Antwortheader festzulegen.headers_set[:] = [status, response_headers]
status
Undresponse_headers
Zugewiesen anheaders_set
Liste.Der Zweck hiervon ist die Aufbewahrungheaders_set
Verweis, aktualisiert aber seinen Inhalt.status
ist eine Zeichenfolge, die beispielsweise den Statuscode und die Nachricht der HTTP-Antwort darstellt"200 OK"
。response_headers
ist eine Liste mit Tupeln. Jedes Tupel stellt beispielsweise ein Schlüssel-Wert-Paar eines Antwortheaders dar[("Content-Type", "text/html"), ("Content-Length", "123")]
。write
Funktionreturn write
start_response
Die Methode gibt a zurückwrite
Funktion. Diese Funktion wird von der WSGI-Anwendung aufgerufen, um Antwortdaten zu senden.Hier ist ein vollständiges Beispiel, das die Verwendung zeigt start_response
Methoden zur Verarbeitung von WSGI-Antworten:
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()
In diesem Tutorial haben wir einen WSGI-Server im Detail analysiert start_response
Methode, die erklärt, wie sie mit dem Statuscode und den Antwortheadern einer HTTP-Antwort umgeht, und eine Funktion zum Schreiben der Antwortdaten zurückgibt. Das Verständnis dieser Inhalte wird Ihnen helfen, die WSGI-Spezifikation besser zu verstehen und einen angepassten WSGI-Server zu implementieren. Ich hoffe, dieses Tutorial ist hilfreich für Sie.Weitere Einzelheiten und Beispiele finden Sie unterOffizielle Dokumentation。