2024-07-12
한어Русский языкEnglishFrançaisIndonesianSanskrit日本語DeutschPortuguêsΕλληνικάespañolItalianoSuomalainenLatina
start_response
MenetelmäanalyysiTässä artikkelissa analysoimme yksityiskohtaisesti WSGI-palvelinta start_response
menetelmä.Tämä menetelmä vastaa HTTP-vastauksen tilakoodin ja vastausotsikoiden käsittelystä ja awrite
Toiminto, jota käytetään vastaustietojen lähettämiseen. Selitämme rivi riviltä, kuinka menetelmä toimii, ja tarjoamme taustaa, joka auttaa ymmärtämään sen ominaisuuksia.
WSGI (Web Server Gateway Interface) on vakiokäyttöliittymä, jota käytetään yhdistämään verkkopalvelin verkkosovellukseen tai -kehykseen. WSGI:n kautta voit kommunikoida palvelimen ja sovelluksen välillä sekä käsitellä HTTP-pyyntöjä ja vastauksia.
Kun otat WSGI-palvelimen käyttöön,start_response
Menetelmä on keskeinen osa, jota WSGI-sovellus kutsuu asettamaan HTTP-vastauksen tilan ja vastausotsikot, ja palauttaa funktion vastaustietojen kirjoittamista varten.
start_response
Menetelmän toteutusSeuraava on tyypillinen start_response
Menetelmän toteutus:
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
parametriif exc_info:
try:
if headers_sent:
reraise(*exc_info)
finally:
exc_info = None
exc_info
Argumentti sisältää tavallisesti poikkeustuplen muodossa(type, value, traceback)
, käytetään poikkeusten käsittelyyn.josexc_info
Ei vartenNone
, mikä osoittaa, että on olemassa poikkeus, joka on käsiteltävä.try
Blockin sisäiset tarkastuksetheaders_sent
Onko vastauksen otsikko lähetetty.Jos vastausotsikot on lähetetty, soitareraise(*exc_info)
Peruuta poikkeus.finally
esto varmistaa, että poikkeuksen käsittelyn jälkeenexc_info
asetettuNone
päällekkäisen käsittelyn välttämiseksi.elif headers_set:
raise AssertionError("Headers already set")
headers_set
Listassa on jo arvoja (eli vastauksen otsikko on asetettu), korotuksiaAssertionError
epänormaalia.Tämä tarkistus varmistaastart_response
Voidaan kutsua vain kerran vastausotsikoiden asettamiseksi.headers_set[:] = [status, response_headers]
status
jaresponse_headers
määritettyheaders_set
lista.Tämän tarkoituksena on säilyttääheaders_set
viittaus, mutta päivittää sen sisältöä.status
on merkkijono, joka edustaa esimerkiksi HTTP-vastauksen tilakoodia ja viestiä"200 OK"
。response_headers
on luettelo, joka sisältää monikot, jokainen monikko edustaa avainarvoparia vastauksen otsikossa, esim.[("Content-Type", "text/html"), ("Content-Length", "123")]
。write
toimintoreturn write
start_response
Menetelmä palauttaa awrite
toiminto. WSGI-sovellus kutsuu tätä toimintoa lähettämään vastausdataa.Tässä on täydellinen esimerkki, joka osoittaa kuinka käyttää start_response
Menetelmät WSGI-vastausten käsittelyyn:
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()
Tämän opetusohjelman avulla analysoimme yksityiskohtaisesti WSGI-palvelinta start_response
Menetelmä, joka selittää, kuinka se käsittelee HTTP-vastauksen tilakoodia ja vastausotsikoita, ja palauttaa funktion vastaustietojen kirjoittamista varten. Tämän sisällön ymmärtäminen auttaa sinua ymmärtämään paremmin WSGI-spesifikaatioita ja toteuttamaan mukautetun WSGI-palvelimen. Toivottavasti tämä opetusohjelma on hyödyllinen sinulle.Katso lisätietoja ja esimerkkejäVirallinen dokumentaatio。