##
11.24.2 asynchat 使用例

以下のサンプルは、`async_chat`でHTTPリクエストを読み込む処理の一部 です。Webサーバは、クライアントからの接続毎に `http_request_handler`オブジェクトを作成します。最初はチャネルの終 了条件に空行を指定してHTTPヘッダの末尾までを検出し、その後ヘッダ読み込み 済みを示すフラグを立てています。

ヘッダ読み込んだ後、リクエストの種類がPOSTであればデータが入力ストリーム に流れるため、`Content-Length:`ヘッダの値を数値として終了条件に指定 し、適切な長さのデータをチャネルから読み込みます。

必要な入力データを全て入手したら、チャネルの終了条件に`None`を指定 して残りのデータを無視するようにしています。この後、 `handle_request()`が呼び出されます。

    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):
            """Buffer the data"""
            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()