美文网首页实验报告
Python 《Python 实现简单 Web 服务器》实验报告

Python 《Python 实现简单 Web 服务器》实验报告

作者: Yohann丶blog | 来源:发表于2020-08-13 14:43 被阅读0次
    WechatIMG62.jpeg

    环境

    • macOS 10.14.6

    • Python 3.7.7

    • httpie

    httpie 是一个命令行 HTTP 客户端。

    安装httpie

    • 安装
    $ brew install httpie
    

    这里使用 homebrew 安装 httpie。

    • 查看版本
    $ http --version
    2.2.0
    

    代码

    #-*- coding:utf-8 -*-
    
    import sys, os, urllib, subprocess
    import urllib.parse
    import urllib.request
    from http.server import BaseHTTPRequestHandler,HTTPServer
    #-------------------------------------------------------------------------------
    
    class ServerException(Exception):
        '''服务器内部错误'''
        pass
    
    #-------------------------------------------------------------------------------
    
    class base_case(object):
        '''条件处理基类'''
    
        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.'
    
    #-------------------------------------------------------------------------------
    
    class case_no_file(base_case):
        '''文件或目录不存在'''
    
        def test(self, handler):
            return not os.path.exists(handler.full_path)
    
        def act(self, handler):
            raise ServerException("'{0}' not found".format(handler.path))
    
    #-------------------------------------------------------------------------------
    
    class case_cgi_file(base_case):
        '''可执行脚本'''
    
        def run_cgi(self, handler):
            data = subprocess.check_output(["python3", handler.full_path],shell=False)
            handler.send_content(data)
    
        def test(self, handler):
            return os.path.isfile(handler.full_path) and \
                   handler.full_path.endswith('.py')
    
        def act(self, handler):
            self.run_cgi(handler)
    
    #-------------------------------------------------------------------------------
    
    class case_existing_file(base_case):
        '''文件存在的情况'''
    
        def test(self, handler):
            return os.path.isfile(handler.full_path)
    
        def act(self, handler):
            self.handle_file(handler, handler.full_path)
    
    #-------------------------------------------------------------------------------
    
    class case_directory_index_file(base_case):
        '''在根路径下返回主页文件'''
    
        def test(self, handler):
            return os.path.isdir(handler.full_path) and \
                   os.path.isfile(self.index_path(handler))
    
        def act(self, handler):
            self.handle_file(handler, self.index_path(handler))
    
    #-------------------------------------------------------------------------------
    
    class case_always_fail(base_case):
        '''默认处理'''
    
        def test(self, handler):
            return True
    
        def act(self, handler):
            raise ServerException("Unknown object '{0}'".format(handler.path))
    
    #-------------------------------------------------------------------------------
    
    class RequestHandler(BaseHTTPRequestHandler):
        '''
        请求路径合法则返回相应处理
        否则返回错误页面
        '''
    
        Cases = [case_no_file(),
                 case_cgi_file(),
                 case_existing_file(),
                 case_directory_index_file(),
                 case_always_fail()]
    
        # 错误页面模板
        Error_Page = """\
            <html>
            <body>
            <h1>Error accessing {path}</h1>
            <p>{msg}</p>
            </body>
            </html>
            """
    
        # 处理get请求
        def do_GET(self):
            try:
    
                # 得到完整的请求路径
                self.full_path = os.getcwd() + self.path
                # 遍历所有的情况并处理
                for case in self.Cases:
                    if case.test(self):
                        case.act(self)
                        break
    
            # 处理异常
            except Exception as msg:
                self.handle_error(msg)
    
        # 处理post请求
        def do_POST(self):
            datas = self.rfile.read(int(self.headers['content-length']))
            self.send_content(datas)
    
        # 处理异常
        def handle_error(self, msg):
            content = self.Error_Page.format(path=self.path, msg=msg)
            self.send_content(content.encode("utf-8"), 404)
    
        # 发送数据到客户端
        def send_content(self, content, status=200):
            self.send_response(status)
            self.send_header("Content-type", "text/html")
            self.send_header("Content-Length", str(len(content)))
            self.end_headers()
            self.wfile.write(content)
    
    #-------------------------------------------------------------------------------
    
    if __name__ == '__main__':
        serverAddress = ('', 8080)
        server = HTTPServer(serverAddress, RequestHandler)
        server.serve_forever()
    

    创建 server.py,内容如上。

    运行

    • 启动服务器
    $ python server.py &
    

    &表示将这个任务放到后台去执行。

    • get 请求
    $ http 0.0.0.0:8080/home.html
    HTTP/1.0 404 Not Found
    Content-Length: 152
    Content-type: text/html
    Date: Thu, 13 Aug 2020 06:22:48 GMT
    Server: BaseHTTP/0.6 Python/3.7.7
    
    <html>
            <body>
            <h1>Error accessing /home.html</h1>
            <p>'/home.html' not found</p>
            </body>
            </html>
    
    • post 请求
    $ http 0.0.0.0:8080 hello=world
    HTTP/1.0 200 OK
    Content-Length: 18
    Content-type: text/html
    Date: Thu, 13 Aug 2020 06:07:27 GMT
    Server: BaseHTTP/0.6 Python/3.7.7
    
    {
        "hello": "world"
    }
    

    相关文章

      网友评论

        本文标题:Python 《Python 实现简单 Web 服务器》实验报告

        本文链接:https://www.haomeiwen.com/subject/njgbdktx.html