11.24.2 Esempi asynchat

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.