BaseHTTPServer与CGIHTTPServer学习札记

今天学习了《Python核心编程》中Web服务器相关章节。于是走读了一下python的源码。

本人电脑上安装的是python2.6,相应的源码文件存放在 /usr/lib/python2.6/ 路径下。

1 BaseHTTPServer浅析

打开 /usr/lib/python2.6/BaseHTTPServer.py 文件。

1.1 HTTPServer类

最上面定义了类 HTTPServer,继承于 SocketServer.TCPServer,它不断接收数据,并将接收到的数据交给 RequestHandler 处理。

技术分享

它没有在TCPServer的基础上添加大量的功能,只加了一个server_bind()成员函数。


1.2 BaseHTTPRequestHandler类

看到类 BaseHTTPRequestHandler,这个类负责处理接收到的HTTP请求,如POST,GET之类的。

技术分享

看到它的成员函数 handle()

技术分享

请求处理就是调用handle()函数进行的。首先,它将类成员变量close_connection置为1,如果在handle_one_request()执行中没有将其置为0,那么handle()就返回了。

那在什么情况下close_connection会被置为0呢?如果请求的header里有 Connection:keep-alive时会被清0。见parse_request()中:

技术分享

从上面的while循环可以看到,如果close_connection为0,那么就继续执行handle_one_request(),直到close_connection为1为至。


那么 handle_one_request() 又在干什么呢?顾名思义,就是处理一个请求。

技术分享

L312:从rfile读取请求的数据,也就是HTTP报文数据。

L313~L315:如果读失败退出。

L316~L317:调用parse_request()对HTTP报文header进行解析,如果失败则退出。

L318:根据command,生成处理函数名,如GET命令生成的是do_GET。

L319~L323:检查当前类是否有 do_XXX() 成员函数,如果存在 do_XXX() 这个成员函数。


再看一下 parse_request() 是如何分析HTTP header的。主要分两步:

(1)读对报文数据的第一行,格式是:<命名> <路径> <HTTP版本>,通常是:“GET / HTTP/1.1”。

        分析版号是否正确,并解析出command, path, version,并保存到对应的成员变量中。

(2)检查headers是中的Connection,如果是keep-alive,那么就得将close_connection置为0,以保存连接。

技术分享


从对BaseHTTPRequestHandler的分析可以得知,如果我们要响应POST,GET命令,那必须得继承于BaseHTTPRequestHandler,并定义好do_GET()与do_POST()函数。

除了上述的三个重要的函数外,BaseHTTPRequestHandler 还提供了很多有用的成员函数:

send_error(code, message=None)

send_respond(code, message=None)

send_header(keyword, value)

end_headers()

...


2 CGIHTTPServer浅析

打开 /usr/lib/python2.6/CGIHTTPServer.py 文件。文件里只定义了一个 CGIHTTPRequestHandler 类,继承于 SimpleHTTPServerHandler。

其实 SimpleHTTPRequestHandler 是继承于 BaseHTTPRequestHandler 的。

技术分享

它实现了 do_POST() 函数:

技术分享

意思很简单,如果是CGI,那么就执行CGI,否则报错。

那怎么才算是CGI呢?我们跟踪一下 is_cgi() 函数:

技术分享

看起来很简单,也就是在目录 cgi_directories 下的文件,认为是cgi文件。在L89定义了 cgi_directories,也就是在 /cgi-bin 或 /htbin 目录下的都认为是 cgi。

_url_collapse_path_split(path) 函数是用于规整路径的,防止路径中出现过多 ./ 或 .. / 出现的防问漏洞。


那么怎么执行cgi的呢?我们一起跟一下 run_cgi() 函数。

待续……





















郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。