Python标准库源码分析:BaseHTTPServer.py
从SocketServer.py分析中可以知道其设计思想是将socket编程的监听循环和客户端处理划分成Server类和RequestHandler类,而BaseHTTPServer是基于SocketServer基础之上的,因此可以知道BaseHTTPServer就是分别扩展Server类和RequestHandler类。BaseHTTPServer实现了一个简单的HTTP Server,可以知道主要工作应该是扩展RequestHandler的功能,处理客户端的HTTP请求,具体包括HTTP协议解析,给客户端返回HTTP响应,日志记录等功能。
1.HTTPServer
该类只是简单包装了SocketServer中的TCPServer类
2.BaseHTTPRequestHandler
类定义
class BaseHTTPRequestHandler(SocketServer.StreamRequestHandler):
扩展RequestHandler需要覆盖一个接口handler(),定义如下:
def handle(self):
"""Handle multiple requests if necessary."""
self.close_connection = 1
self.handle_one_request()
while not self.close_connection:
self.handle_one_request()
主要处理的是HTTP是否保持连接的问题,如果保持连接就持续处理客户请求,否则就结束了。
handle_one_request()比较重要语句:
self.raw_requestline = self.rfile.readline(65537)
self.parse_request()
mname = 'do_' + self.command
if not hasattr(self, mname)
self.send_error(501, "Unsupported method (%r)" % self.command)
return
method = getattr(self, mname)
method() ###调用do_GET do_post
self.wfile.flush() #actually send the response if not already done.
读取第一行raw_requestline,一般格式应该是:COMMAND PATH VERSION\r\n
;解析请求,下面具体分析;后面几行代码意思是根据HTTP方法获取对应处理函数,其实就是根据GET或POST请求调用对应的do_GET()或do_POST()方法,然后刷新输出。
parse_request()主要的代码都在处理raw_requestline,最终得到self.command, self.path, self.request_version几个变量,然后就是利用mimetools.Message解析头部。
至此主体流程就结束了。
下面还有几个的函数,功能都比较简单:
def send_error(self, code, message=None):
def send_response(self, code, message=None):
def send_header(self, keyword, value):
def end_headers(self):
def log_request(self, code='-', size='-'):
def log_error(self, format, *args):
def log_message(self, format, *args):
总结:可以看到,BaseHTTPRequestHandler主要实现了客户端HTTP请求解析,以及一些辅助功能,如日志记录、错误处理、发送响应代码等。但是还没有实现如何执行HTTP请求,简单来说就是还需要实现诸如do_GET(),do_POST()等函数,具体执行对应的HTTP命令。
CODE:
===========================================================
from http.server import HTTPServer, BaseHTTPRequestHandler
class RequestHandler(BaseHTTPRequestHandler):
def _header(self):
self.send_response(200)
self.send_header("Content-type", "text/html")
self.end_headers()
def do_HEAD(self):
self._header()
def do_GET(self):
self._header()
self.wfile.write('test')
server = HTTPServer(('localhost', 80), RequestHandler)
server.serve_forever()
===========================================================
ERROR:
===========================================================
localhost - - [13/Jun/2009 14:00:13] "GET / HTTP/1.1" 200 -
----------------------------------------
Exception happened during processing of request from ('127.0.0.1', 1907)
Traceback (most recent call last):
File "C:\Python30\lib\socketserver.py", line 281, in
_handle_request_noblock
self.process_request(request, client_address)
File "C:\Python30\lib\socketserver.py", line 307, in process_request
self.finish_request(request, client_address)
File "C:\Python30\lib\socketserver.py", line 320, in finish_request
self.RequestHandlerClass(request, client_address, self)
File "C:\Python30\lib\socketserver.py", line 614, in __init__
self.handle()
File "C:\Python30\lib\http\server.py", line 363, in handle
self.handle_one_request()
File "C:\Python30\lib\http\server.py", line 357, in handle_one_request
method()
File "C:\Documents and Settings\User\Desktop\mHome\webserver.py",
line 18, in
do_GET
self.wfile.write('human')
File "C:\Python30\lib\socket.py", line 219, in write
return self._sock.send(b)
TypeError: send() argument 1 must be bytes or buffer, not str
=========================================================== |
msg89395 - (view) | Author: Amaury Forgeot d'Arc (amaury.forgeotdarc) * | Date: 2009-06-15 07:38 |
---|
the HTTP response should be a bytes string:
self.wfile.write(b'test') |