首页->正文

编写web服务器学Python之Fastcgi

2011-07-05 -Web开发 标签: python fastcgi

本节概要
1.通过fastcgi方式增加对php文件的解析
2.socket基础知识介绍
3.GET和POST方式的数据读取、上传文件、cookie支持

到目前为止我们的web服务器只能满足对静态文件的读取,而真正的web服务器还可以提供对动态语言的支持,如apache可以通过加载模块的方式来解析php文件,nginx可通过fastcgi方式支持。以模块方式加载的方式和要解析的语言相关比较紧密,而fastcgi方式只是实现了协议本身,对后端语言则不做要求。所以这节我们主要实现对fastcgi的支持,通过fastcgi来和php交互(php的php-fpm扩展已提供了factcgi功能,我们要做的只是在web端发送相关信息并解析返回数据即可)

一、fastcgi模块主要功能为组装请求fastcgi的数据并解析返回的数据
1 组织请求数据
首先说下最关键的SCRIPT_FILENAME,当访问http://localhost/a.php时,假设php文件放置在/data/www/script/目录下,因此请求a.php完整的文件路径为/data/www/script/a.php,把此路径通过类似key-value形式(fastcgi中称name-value pairs,可以看做是程序本身的环境变量)发送给后端的fastcgi服务(php-fpm),fastcgi服务会根据此信息再调用对应的php文件,并把输出信息返回给请求方。其他一些必要的环境变量,如REMOTE_ADDR即客户端的IP地址,REQUEST_METHOD即http的请求方式(如GET、POST)等,想想平时开发中如何获取GET、POST变量,客户端ip,客户浏览器标识,Referer……也就是说这些信息都是通过web服务器从http的header信息中读取后,再加上服务器自身的一些信息组装好并通过fastcgi协议传递给后端fastcgi服务器的。
2 返回数据
fastcgi的返回数据主要为stdout(输出,例如后端程序输出的html信息)和stderr(错误,例如语法错误,方法不存在等语言本身引起的错误),当然也可能是后端fastcgi服务器无响应或者链接超时等,这种错误需要在web服务器端进行控制。

二、socket基础知识介绍
socket可以理解为通过一种特定方式建立链接后,读取对方的信息(好像是废话……)。过程好比打电话,首先通过拨特定的号码(ip),再转分机(端口),建立通话,之后双方开始对话,说(send)或者听(recv),最后挂电话(close)
当然对话中还可以设置一些条件,例如振铃n次了,对方还不接听,或者接通后你喂了半天,对方5分钟都没回应(timeout),这时你可以直接挂电话,无需再等下去。
具体的代码很简单,相信自己一看就知道了:)
详细介绍见http://docs.python.org/library/socket.html

三、GET和POST方式的数据读取、上传文件、cookie支持
GET(REQUEST_METHOD=GET)除了url本身,还有类似a.php?a=1&b=2等类似的地址,这时候把?之后的部分定义为query_string,即以HTTP_STRING环境变量的方式传递给后端;

POST(REQUEST_METHOD=POST)时要增加header之外的body部分,即post给服务器的数据,同时告知post数据的编码方式application/x-www-form-urlencoded或者multipart/form-data; boundary=----...
其中application/x-www-form-urlencoded为默认的post数据编码方式,即数据通过a=(urlencode(1))&b=urlencode(2)方式传递。另外一个编码方式为上传文件时的,具体的规则有点复杂,感兴趣的看下这里(http://www.w3.org/TR/html4/interact/forms.html#h-17.13.4.2)。总之如果你不更改这些信息就不用太注意了,因为浏览器都会帮我们编码好了,只要读取http header中的Content-Type和发送的body即可,至于解析上后端的php也都帮我们做好了(太简单了……)

再说下“神秘的”cookie,查看http的请求header就全明白了
GET /form.html HTTP/1.1 
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:5.0) Gecko/20100101 Firefox/5.0 
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8 
Accept-Language: zh-cn,zh;q=0.5 
Accept-Encoding: gzip, deflate 
Accept-Charset: GB2312,utf-8;q=0.7,*;q=0.7 
Connection: keep-alive 
Cookie: cookienameis=cookievalueishere

可以看到cookie一项,这就是客户端的cookie,当然你只能读取所属域名下的cookie,而cookie的设置也同样位于cookie字段中,只不过这时是服务器发送给浏览器的,如
Set-Cookie: cookienameis=cookievalueishere; expires=Mon, 04-Jul-2011 16:58:20 GMT; path=/html/

相当于告诉浏览器设置一个cookie,名称是cookienameis,值为cookievalueishere,在Mon, 04-Jul-2011 16:58:20失效,且只有在/html/及下属路径下才可以访问,更详细的cookie介绍可以看这里(http://hi.baidu.com/zzcqh/blog/item/d13627607c1128d68db10dae.html或者http://www.ietf.org/rfc/rfc2109.txt

OK,一切尽在代码中,点这里下载!

注意
.split的使用注意:第二个参数为分割次数,不同于php中explode的limit元素个数参数
例如:
s = '1|2|3|4|5'
print s.split('|', 2)
#['1', '2', '3|4|5']

而php中则返回
print_r(explode('|', '1|2|3|4|5', 2));
/*
Array
(
   [0] => 1
   [1] => 2|3|4|5
)
*/


相关链接
.factcgi的协议说明见http://www.fastcgi.com/devkit/doc/fcgi-spec.html,或者参考下之前写的关于fastcgi协议解析
.推荐一个根据实例学习Python模块的网站http://www.doughellmann.com/PyMOTW/,同时提供了离线的html和PDF格式下载,以及纸质版的书(The Python Standard Library By Example)。

下一篇 Varnish3.0中对gzip的支持

上一篇 Fastcgi协议定义解释与说明

相关文章

编写web服务器学Python之一

编写web服务器学Python之二

编写web服务器学Python之三

Fastcgi协议定义解释与说明

文章分类

开发小提示

  • 1:Mongodb中通过db.yourCollectionName. dataSize()查看某个文档的大小
  • 2:linux下用reset命令恢复查看二进制文件导致的命令行乱码
  • 3:查看MySQL表的索引情况show index from tableName
  • 更多...

交流

  • wangnow(a)126.com