您的位置:首页 > 理论基础 > 计算机网络

代码阅读 - BaseHTTPServer.py

2007-04-05 09:48 405 查看

1.        BaseHTTPServer.py

平平无奇,看过SocketServer之后,只要了解HTTP协议就能看明白。

HTTPServer 继承自 SocketServer.TCPServer;

BaseHTTPRequestHandler 继承自 SocketServer.StreamRequestHandler。

1.1     HTTPServer

HTTP协议本身就是在TCP之上建立的应用层协议,所以不需要做太多的工作。这里的事项方法是将协议的解析等工作放到Handler类中,在Server类中仅仅覆盖了server_bind函数:

1.         首先调用TCPServer.server_bind;

2.         然后通过 socket. socket.getsockname 和 socket.getfqdn得到完整的主机名和端口。

1.2     HTTP协议回顾

HTTP请求数据流中的三个部分:

1.         第一行表示“请求的类型”和“路径”,格式为 <command> <path> [<version>];

2.         可选的HEADERS;HEADER之间用CRLF或LF分割;

3.         可选的数据部分;数据和HEADER之间由一个空行分割。

HTTP相应数据流中的三个部分:

1.         第一行表示响应代码,格式为 <version> <response_code> [<responsestring>];

2.         可选的HEADERS;

3.         数据部分;和HEADER之间由一个空行分割。

1.3     BaseHTTPRequestHandler

在SocketServer.BaseRequestHandler的构造函数中,调用了三个方法:setup, handle, finish。其中handler用来处理请求,而且被实现为空函数。

在 SocketServer.StreamRequestHandler中,并没有对handle进行覆盖,而是覆盖setup将socket构造为输入和输出文件 rfile 和 wfile。

所以在BaseHTTPRequestHandler中,只需要覆盖handle,对客户端的请求进行处理。

1.3.1              handle方法

self.close_connection = 1

 

self.handle_one_request()

     while not self.close_connection:

         self.handle_one_request()

这里的关键是close_connection。主要是为了区分http request header中的 keep-alive。

1.3.2              handle_one_request方法

从rfile中读出一行;这一行就是command + path行;

如果读取成功,调用parse_request解析客户端的请求;将请求的操作保存在self.command;判断类是否具有do_command(如do_POST)方法,如果没有,发送501错误;如果有则使用getattr魔法得到方法并调用。

1.3.3              parse_request方法

解析从rfile中得到的那个command + path,没什么难度。

需要注意的是如果解析成功的话,会调用mimetools.Message的构造函数,生成一个类实例。这个构造函数需要rfile作为参数。构造过程其实也就是HEADERS的解析过程。

要具体研究一下这个类。

1.3.4              其他方法

send_response,用来发送HTTP响应的第一行;

send_header,发送一个HEADER;

end_headers,发送一个空白行;

以及log函数和其它辅助函数。

1.4     总结

有了TCPServer和StreamRequestHandler两个构造的非常好的基类,处理简单的HTTP请求并做出响应并不是难事。

 

 
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息