τα στοιχεία επικοινωνίας μου
Ταχυδρομείο[email protected]
2024-07-12
한어Русский языкEnglishFrançaisIndonesianSanskrit日本語DeutschPortuguêsΕλληνικάespañolItalianoSuomalainenLatina
start_response
Ανάλυση μεθόδουΣε αυτό το άρθρο, θα αναλύσουμε λεπτομερώς έναν διακομιστή WSGI start_response
μέθοδος.Αυτή η μέθοδος είναι υπεύθυνη για την επεξεργασία του κωδικού κατάστασης και των κεφαλίδων απόκρισης της απόκρισης HTTP και την επιστροφή του αwrite
Λειτουργία που χρησιμοποιείται για την αποστολή δεδομένων απόκρισης. Θα εξηγήσουμε πώς λειτουργεί η μέθοδος γραμμή προς γραμμή και θα παρέχουμε κάποιο υπόβαθρο για να κατανοήσουμε τις δυνατότητές της.
Το WSGI (Διασύνδεση Πύλης Διακομιστή Ιστού) είναι μια τυπική διεπαφή που χρησιμοποιείται για τη σύνδεση ενός διακομιστή ιστού με μια εφαρμογή ή πλαίσιο Ιστού. Μέσω του WSGI, μπορείτε να επικοινωνείτε μεταξύ του διακομιστή και της εφαρμογής και να χειρίζεστε αιτήματα και απαντήσεις HTTP.
Κατά την υλοποίηση ενός διακομιστή WSGI,start_response
Η μέθοδος είναι ένα βασικό τμήμα που καλείται από την εφαρμογή WSGI για να ορίσει την κατάσταση απόκρισης HTTP και τις κεφαλίδες απόκρισης και επιστρέφει μια συνάρτηση για την εγγραφή των δεδομένων απόκρισης.
start_response
Υλοποίηση μεθόδουΤο παρακάτω είναι χαρακτηριστικό start_response
Υλοποίηση μεθόδου:
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
παράμετροςif exc_info:
try:
if headers_sent:
reraise(*exc_info)
finally:
exc_info = None
exc_info
Το όρισμα συνήθως περιέχει μια πλειάδα εξαίρεσης στη μορφή(type, value, traceback)
, χρησιμοποιείται για χειρισμό εξαιρέσεων.ανexc_info
Οχι γιαNone
, υποδεικνύοντας ότι υπάρχει μια εξαίρεση που πρέπει να αντιμετωπιστεί.try
Έλεγχοι εντός μπλοκheaders_sent
Εάν η κεφαλίδα της απάντησης έχει σταλεί.Εάν έχουν σταλεί οι κεφαλίδες των απαντήσεων, καλέστεreraise(*exc_info)
Επαναφέρετε την εξαίρεση.finally
Το μπλοκ διασφαλίζει ότι μετά τον χειρισμό της εξαίρεσης, τοexc_info
οριστεί σεNone
για να αποφευχθεί η διπλή επεξεργασία.elif headers_set:
raise AssertionError("Headers already set")
headers_set
Η λίστα περιέχει ήδη τιμές (δηλαδή έχει οριστεί η κεφαλίδα απόκρισης), αυξήσειςAssertionError
ασυνήθιστος.Αυτός ο έλεγχος διασφαλίζειstart_response
Μπορεί να κληθεί μόνο μία φορά για να ορίσετε κεφαλίδες απόκρισης.headers_set[:] = [status, response_headers]
status
καιresponse_headers
ανατεθείheaders_set
λίστα.Σκοπός αυτού είναι η διατήρησηheaders_set
αναφορά, αλλά ενημερώνει το περιεχόμενό του.status
είναι μια συμβολοσειρά που αντιπροσωπεύει τον κωδικό κατάστασης απόκρισης HTTP και το μήνυμα, για παράδειγμα"200 OK"
。response_headers
είναι μια λίστα που περιέχει πλειάδες, κάθε πλειάδα αντιπροσωπεύει ένα ζεύγος κλειδιού-τιμής μιας κεφαλίδας απόκρισης, για παράδειγμα[("Content-Type", "text/html"), ("Content-Length", "123")]
。write
λειτουργίαreturn write
start_response
Η μέθοδος επιστρέφει awrite
λειτουργία. Αυτή η λειτουργία καλείται από την εφαρμογή WSGI για αποστολή δεδομένων απόκρισης.Ακολουθεί ένα πλήρες παράδειγμα που δείχνει πώς να το χρησιμοποιήσετε start_response
Μέθοδοι χειρισμού απαντήσεων 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()
Μέσα από αυτό το σεμινάριο, αναλύσαμε λεπτομερώς έναν διακομιστή WSGI start_response
Μέθοδος που εξηγεί πώς χειρίζεται τον κωδικό κατάστασης και τις κεφαλίδες απόκρισης μιας απόκρισης HTTP και επιστρέφει μια συνάρτηση για την εγγραφή των δεδομένων απόκρισης. Η κατανόηση αυτών των περιεχομένων θα σας βοηθήσει να κατανοήσετε καλύτερα τις προδιαγραφές WSGI και να εφαρμόσετε έναν προσαρμοσμένο διακομιστή WSGI. Ελπίζω ότι αυτό το σεμινάριο είναι χρήσιμο για εσάς.Για περισσότερες λεπτομέρειες και παραδείγματα, ανατρέξτε στοΕπίσημη τεκμηρίωση。