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一些调试信息,就能清楚的看到它的过程了

时间: 2024-12-09 07:19:45

python简易web服务器学习笔记(二)的相关文章

python简易web服务器学习笔记(三)

import sys, os, BaseHTTPServer #------------------------------------------------------------------------------- class ServerException(Exception): '''For internal error reporting.''' pass #--------------------------------------------------------------

python之数据类型(学习笔记二)

python之数据类型(学习笔记二) 在Python中,能够直接处理的数据类型有以下几种: (1)整数 Python可以处理任意大小的整数,当然包括负整数,在程序中的表示方法和数学上的写法一模一样,例 如: 1 , 100 , ‐8080 , 0 ,等等. 计算机由于使用二进制,所以,有时候用十六进制表示整数比较方便,十六进制用 0x 前缀和0-9,a-f表示,例 如: 0xff00 , 0xa5b4c3d2 ,等等. (2)浮点数 浮点数也就是小数,之所以称为浮点数,是因为按照科学记数法表示时

python web 服务器学习笔记(四)

在开始新内容之前,我们先解决socket error 98:Address already in use问题 很容易发现可能是由于端口被占用导致的,端口被占用又有很多可能,比如说的关闭你挂上去的服务器,然后又秒开,你会发现这个错误. 此时似乎是由于tcp本身的特性,端口未来得及释放导致的 我们可以通过以下命令查看端口的使用情况,并试着处理它 kill -9 [进程id] 杀死该进程 lsof -i:[端口号]查看端口属于哪个程序 netstrat tln | grep [端口号]查看端口使用情况

Kestrel Web 服务器学习笔记

前言: ASP.NET Core 已经不是啥新鲜的东西,很多新启的项目都会首选 Core 做开发: 而 Kestrel 可以说是微软推出的唯一真正实现跨平台的 Web 服务器了: Kestrel 利用一个名为 KestrelEngine 的网络引擎实现对请求的监听.接收和响应: Ketrel 之所以具有跨平台的特质,源于 KestrelEngine 是在一个名为 libuv 的跨平台网络库上开发的: Kestrel is a cross-platform web server for ASP.N

Servlet一(web基础学习笔记二十)

一.Servlet简介 Servlet是sun公司提供的一门用于开发动态web资源的技术. Sun公司在其API中提供了一个servlet接口,用户若想用发一个动态web资源(即开发一个Java程序向浏览器输出数据),需要完成以下2个步骤: 1.编写一个Java类,实现servlet接口. 2.把开发好的Java类部署到web服务器中. 按照一种约定俗成的称呼习惯,通常我们也把实现了servlet接口的java程序,称之为Servlet 二.ServletAPI 三.Servlet的方法 四.S

python web服务器学习笔记(五) 并发尝试之popen原理探究

使用popen新开进程能实现并发吗?像这样的cgi处理程序 def run_cgi(self,handler): cmd = "python" +handler.full_path child_stdin,child_stdout=os.popen2(cmd) child_stdin.close() data=child_stdout.read() child_stdout.close() handler.send_content(data) 我让它跑 for i in range(1

WEB前端学习笔记 二

1.4  JavaScript和Jquery能做什么? JavaScript是Netscape公司开发的一种基于对象和事件驱动的脚本语言 ,并且可在所有主要的浏览器中运行 IE.Firefox.Chorme.Opera ,JavaScript 可用来向 HTML 页面添加交互行为,如表单数据合法性验证.网页特效.动画效果.数值计算,例如你现在浏览的网知博学的首页面上的图片循环播放和导航分类,淘宝和京东的商品分类菜单等.JavaScript 是一种弱类型语言,无需编译,可由浏览器直接解释运行 特点

使用JSP实现输出(web基础学习笔记二)

Jsp:Java Server Page 服务器端的Java页面,动态网页技术 jsp注释 显式注释:这种注释客户端是允许看见的;<!--html注释--> 隐式注释:这种注释客户端是看不到的 注释:格式一://注释,单行注释 格式二:/*多行注释*/ 格式三:<%--注释--%>jsp注释 <!-- 这个注释客户端可以可见 --> <%--这个注释客户端看不到 --%> <% out.println("学习jsp输出"); //输

监听器(web基础学习笔记二十二)

一.监听器 监听器是一个专门用于对其他对象身上发生的事件或状态改变进行监听和相应处理的对象,当被监视的对象发生情况时,立即采取相应的行动.监听器其实就是一个实现特定接口的普通java程序,这个程序专门用于监听另一个java对象的方法调用或属性改变,当被监听对象发生上述事件后,监听器某个方法立即被执行. 二.监听器统计在线人数--HttpSessionListener实现 package com.pb.news.listenter; public class OnlineCounter { pub