Il seguente, parziale, esempio mostra come richieste HTTP possano essere lette con async_chat. Un server web deve creare un oggetto http_request_handler per ogni connessione client in arrivo. Notare che inizialmente la stringa di conclusione del canale viene impostato per verificare la riga vuota alla fine delle intestazioni HTTP, ed un'opzione indica che le intestazioni sono in fase di lettura.
Quando le intestazioni sono state lette, se la richiesta è di tipo
POST (indicante che successivi dati sono presenti nel flusso in
ingresso), l'intestazione Content-Length:
viene usata per
impostare una stringa di conclusione numerica per leggere il giusto
quantitativo di dati in arrivo dal canale.
Il metodo handle_request() viene chiamato una sola volta
quando tutti gli input rilevanti sono stati serializzati, subito dopo
aver impostato la stringa di conclusione del canale a None
per
assicurarsi che ogni dato estraneo inviato dal cliente web sia
ignorato.
class http_request_handler(asynchat.async_chat): def __init__(self, conn, addr, sessions, log): asynchat.async_chat.__init__(self, conn=conn) self.addr = addr self.sessions = sessions self.ibuffer = [] self.obuffer = "" self.set_terminator("\r\n\r\n") self.reading_headers = True self.handling = False self.cgi_data = None self.log = log def collect_incoming_data(self, data): """Il buffer dei dati""" self.ibuffer.append(data) def found_terminator(self): if self.reading_headers: self.reading_headers = False self.parse_headers("".join(self.ibuffer)) self.ibuffer = [] if self.op.upper() == "POST": clen = self.headers.getheader("content-length") self.set_terminator(int(clen)) else: self.handling = True self.set_terminator(None) self.handle_request() elif not self.handling: self.set_terminator(None) # browsers sometimes over-send self.cgi_data = parse(self.headers, "".join(self.ibuffer)) self.handling = True self.ibuffer = [] self.handle_request()
Vedete Circa questo documento... per informazioni su modifiche e suggerimenti.