zoukankan      html  css  js  c++  java
  • 1、实现简单的web服务器

    1、web-server文件下有index.html,plain.html,server.py,time.py文件

    from http.server import BaseHTTPRequestHandler, HTTPServer
    import subprocess, os
    
    
    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.send_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 ServerException(Exception):
        '''服务器内部错误'''
        pass
    
    class case_directory_index_file(base_case):
        '''条件处理类'''
        # 判断目标路径是否是目录&&目录下是否有index.html
        def test(self, handler):
            return os.path.isdir(handler.full_path) and os.path.isfile(self.index_path(handler))
    
        # 响应index.html的内容
        def act(self, handler):
            self.handle_file(handler, self.index_path(handler))
    
    class case_no_flie(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_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_always_fail(base_case):
        '''所有情况都不符合时的默认处理类'''
        def test(self, handler):
            return True
    
        def act(self, handler):
            raise ServerException("Unknown object '{0}'".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 RequestHandler(BaseHTTPRequestHandler):
        '''处理请求并返回页面'''
        # 错误页面模板
        Error_Page = """
            <html>
            <body>
            <h1>Error accessing {path}</h1>
            <p>{msg}</p>
            </body>
            </html>
            """
    
        # 所有可能的情况
        # 注意这里的顺序, 需要先判断是否是需要执行的脚本文件,再判断是否是普通文件
        Cases = [case_no_flie(), case_cgi_file(), case_existing_file(), case_directory_index_file(), case_always_fail()]
        # 处理一个get请求
        def do_GET(self):
            try:
                # 文件完整路径
                self.full_path = os.getcwd() + self.path
    
                # 遍历所有可能情况
                for case in self.Cases:
                    if case.test(self):
                        # 调用相应的act函数
                        case.act(self)
                        break
            # 处理异常
            except Exception as msg:
                self.handle_error(msg)
    
        # 返回内容给客户端
        def send_content(self, page, status=200):
            self.send_response(status)
            self.send_header('Content-Type', 'text/html')
            self.send_header('Content-Length', str(len(page)))
            self.end_headers()
            self.wfile.write(page)
    
        # 错误处理函数
        def handle_error(self, msg):
            content = self.Error_Page.format(path=self.path, msg=msg)
            self.send_content(content.encode('utf-8'), 404)
    
    
    
    if __name__ == '__main__':
        serverAddress = ('127.0.0.1', 8080)
        server = HTTPServer(serverAddress, RequestHandler)
        server.serve_forever()
  • 相关阅读:
    RedHat Linux-配置YUM仓库
    04、管道符、重定向与环境变量
    03、新手必须掌握的Linux命令
    size_t
    decltype关键字
    python numpy使用笔记
    Huffman编码
    动态规划(dynamic programming)
    Prim算法
    Kruskal算法
  • 原文地址:https://www.cnblogs.com/jp-mao/p/9233629.html
Copyright © 2011-2022 走看看