zoukankan      html  css  js  c++  java
  • python简易web服务器学习笔记(二)

    import BaseHTTPServer
    
    #-------------------------------------------------------------------------------
    
    class RequestHandler(BaseHTTPServer.BaseHTTPRequestHandler):
        '''Respond to HTTP requests with info about the request.'''
    
        # Template for page to send back.
        Page = '''
    <html>
    <body>
    <table>
    <tr>  <td>Header</td>         <td>Value</td>          </tr>
    <tr>  <td>Date and time</td>  <td>{date_time}</td>    </tr>
    <tr>  <td>Client host</td>    <td>{client_host}</td>  </tr>
    <tr>  <td>Client port</td>    <td>{client_port}s</td> </tr>
    <tr>  <td>Command</td>        <td>{command}</td>      </tr>
    <tr>  <td>Path</td>           <td>{path}</td>         </tr>
    </table>
    </body>
    </html>
    '''
    
        # Handle a request by constructing an HTML page that echoes the
        # request back to the caller.
        def do_GET(self):
            page = self.create_page()
            self.send_page(page)
    
        # Create an information page to send.
        def create_page(self):
            values = {
                'date_time'   : self.date_time_string(),
                'client_host' : self.client_address[0],
                'client_port' : self.client_address[1],
                'command'     : self.command,
                'path'        : self.path
            }
            page = self.Page.format(**values)
            return page
    
        # Send the created page.
        def send_page(self, page):
            self.send_response(200)
            self.send_header("Content-type", "text/html")
            self.send_header("Content-Length", str(len(page)))
            self.end_headers()
            self.wfile.write(page)
    
    #-------------------------------------------------------------------------------
    
    if __name__ == '__main__':
        serverAddress = ('', 8080)
        server = BaseHTTPServer.HTTPServer(serverAddress, RequestHandler)
        server.serve_forever()
    

    上述代码可以输出调试信息。

    下一步我们需要让服务器能够提供静态文件。首先我们要做的,是异常处理

    import sys, os, BaseHTTPServer
    
    #-------------------------------------------------------------------------------
    
    class ServerException(Exception):
        '''For internal error reporting.'''
        pass
    
    #-------------------------------------------------------------------------------
    
    class RequestHandler(BaseHTTPServer.BaseHTTPRequestHandler):
        '''
        If the requested path maps to a file, that file is served.
        If anything goes wrong, an error page is constructed.
        '''
    
        # How to display an error.
        Error_Page = """
            <html>
            <body>
            <h1>Error accessing {path}</h1>
            <p>{msg}</p>
            </body>
            </html>
            """
    
        # Classify and handle request.
        def do_GET(self):
            try:
    
                # Figure out what exactly is being requested.
                full_path = os.getcwd() + self.path
    
                # It doesn't exist...
                if not os.path.exists(full_path):
                    raise ServerException("'{0}' not found".format(self.path))
    
                # ...it's a file...
                elif os.path.isfile(full_path):
                    self.handle_file(full_path)
    
                # ...it's something we don't handle.
                else:
                    raise ServerException("Unknown object '{0}'".format(self.path))
    
            # Handle errors.
            except Exception as msg:
                self.handle_error(msg)
    
        def handle_file(self, full_path):
            try:
                with open(full_path, 'rb') as reader:
                    content = reader.read()
                self.send_content(content)
            except IOError as msg:
                msg = "'{0}' cannot be read: {1}".format(self.path, msg)
                self.handle_error(msg)
    
        # Handle unknown objects.
        def handle_error(self, msg):
            content = self.Error_Page.format(path=self.path, msg=msg)
            self.send_content(content, 404)
    
        # Send actual content.
        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 = BaseHTTPServer.HTTPServer(serverAddress, RequestHandler)
        server.serve_forever()
    

     假设程序允许使用该目录下的任何文件提供服务,它会结合url提供的路径(以'/'开始,BaseHTTPServer会自动将它放入self.path),以获取用户想要的文件路径。若文件不存在,或者路径并不指向文件,上述方法将通过获取并抛出异常来报告错误。若匹配到文件,do_GET方法将调用handfile来读取并返回内容,然后调用send_content将文件内容返回给客户端。哇,显然我们是以二进制方式打开的文件(由'rb'和‘b'标识),并把整个文件读到中的呢,所以这样的方法不能处理大型程序喔

    其中的细节在于,其中的hand_error,如果我们直接send_content(content)一个错误页面,则返回码是200。这样的错误信息不好判别:hand_error处理的是页面找不到的情况,这个错误是由于用户输入的文件本身就不存在造成的。应该返回404才对。

    os是python的基础模块,上述代码中用来获取文件路径。raise就是用抛出异常的。具体用发是和try,except配合使用。若print一些调试信息,就能清楚的看到它的过程了

     __name__和__main__是什么东西啊,类似于入口吧。。放在这里不太好理解啊,下篇将会探究它

  • 相关阅读:
    云时代架构阅读笔记一——架构师必备最全SQL优化方案
    虚拟机VMware安装Ubuntuix
    假期周总结八
    虚拟机VMware安装Kali Linux
    codeforces 401D (数位DP)
    2014 多校联合训练赛6 Fighting the Landlords
    lightoj 1224
    lightoj 1020 (博弈)
    lightoj 1019
    lightoj 1018 (状态压缩DP)
  • 原文地址:https://www.cnblogs.com/bitch1319453/p/6579574.html
Copyright © 2011-2022 走看看