猫型エンジニアのブログ

プログラム/ネットワーク系の技術関連をまとめたページです 

BaseHTTPServerの仕組み

 つぎはいよいよBaseHTTPServerです。ここがとても参考になります。

 TCPServerで、ソケット周りの基本的な機能はすでに実装がなされています。そのためHTTPServer自体はTCPServerを継承してserver_bindをオーバライドしたのみの、シンプルなクラスです。

class HTTPServer(SocketServer.TCPServer):

    allow_reuse_address = 1    # Seems to make sense in testing environment

    def server_bind(self):
        """Override server_bind to store the server name."""
        SocketServer.TCPServer.server_bind(self)
        host, port = self.socket.getsockname()
        self.server_name = socket.getfqdn(host)
        self.server_port = port

 ご覧のとおり、ここではユーザからのhttpリクエストに関する処理は一切おこなっていません。ユーザからのHTTPリクエストを処理するのはハンドラーのBaseHTTPRequestHandlerクラスになります。そのため、このクラスで実質的なHTTPサーバの処理を行います。

BaseHTTPRequestHandlerの中身

 このクラスはSocketServerのStreamRequestHandlerを継承したクラスです。BaseHTTPServerモジュールは、実質的にはこの実装がメインとなっています。StreamRequestHandlerクラスのsetupメソッドにて、ですでにrfileとwfileは作成済みの状態で始まります。以下の一部抜粋したソースコードをご覧下さい。

def handle(self):

        self.raw_requestline = self.rfile.readline()
        if not self.parse_request(): # An error code has been sent, just exit
            return
        mname = 'do_' + self.command
        if not hasattr(self, mname):
            self.send_error(501, "Unsupported method (%s)" % `self.command`)
            return
        method = getattr(self, mname)
        method()

 
 commandにはHTTPリクエストのメソッドを指しています。メソッドがGETの場合はmnameがdo_GETとなり、do_GETメソッドが実装されていれば呼び出されます。BaseHTTPRequestHandlerクラスは、HTTPリクエストを処理するクラスのインタフェースであり、それらは実装されていません。そのためユーザがBaseHTTPServerを継承したクラスを作成し、HTTPの各メソッドに対する処理を実装することになります。