一个微型HTTP服务器

决定听取朋友建议找个小的web项目做做。嗯,确实是比较简单。

建立连接过程:

1. Client start TCP request; -> 2. Server accept.->

3. Client sends HTTP request containing URL. -> 4. Server receives request and sends response. ->

5. Client receives and parses response; finds links to 4 images. -> Server closes.

6. Client makes TCP to server. -> 7. Server accepts. ->

8. Client send HTTP request containing URL of first images -> ...

一个微型HTTP服务器_第1张图片


HTTP协议需要注意的两个点:

1.Stateless: use cookie;

2.URL can be supplemented with parameters.


服务器工作流程:

1. Wait for connection and send an HTTP request;

2. Parse HTTP request;

3. Figure out what it's asking for;

4. Fetch that data;

5. Format it as HTML;

6. Send it back.


处理GET请求:

常见的请求处理有显示值、返回一个静态页面、列出目录等(CGI后面单独讲)。

可行的处理方式为:

1. 显示值 -> HTML模板;

2. 返回静态页面 -> 文件读取;

3. 列出目录 -> os库。

下面是一个HTTP返回的封装过程。

    # Handle a GET request.
    def do_GET(self):
        self.send_response(200)
        self.send_header("Content-Type", "text/html")
        self.send_header("Content-Length", str(len(self.Page)))
        self.end_headers()
        self.wfile.write(self.Page)


CGI协议(使后台运行一个简单的python文件,将结果输出到网站):
    def run_cgi(self, full_path):
        cmd = "python " + full_path
        child_stdin, child_stdout = os.popen2(cmd)
        child_stdin.close()
        data = child_stdout.read()
        child_stdout.close()
        self.send_content(data)

class case_cgi_file(object):
    '''Something runnable.'''

    def test(self, handler):
        return os.path.isfile(handler.full_path) and \
               handler.full_path.endswith('.py')

    def act(self, handler):
        handler.run_cgi(handler.full_path)


重构:

重构前的代码如链接。

可以观察到,testact函数都是各个case通用的,因此从代码结构上考虑,可以抽象出一个父类。

class base_case(object):
    '''Parent for case handlers.'''

    def handle_file(self, handler, full_path):
        try:
            with open(full_path, 'rb') as reader:
                content = reader.read()
            handler.send_content(content)
        except IOError as msg:
            msg = "'{0}' cannot be read: {1}".format(full_path, msg)
            handler.handle_error(msg)

    def index_path(self, handler):
        return os.path.join(handler.full_path, 'index.html')

    def test(self, handler):
        assert False, 'Not implemented.'

    def act(self, handler):
        assert False, 'Not implemented.'

重构后的代码结构如链接。

如果你用的是python3,需要改动以下两点:

    1. 把源码中的BaseHTTPServer换成http.server;

    2. self.wfile.write(self.Page)改成self.wfile.write(self.Page.encode())

你可能感兴趣的:(一个微型HTTP服务器)