最近使用python+apache搭建服务器,发现一个问题:对于POST请求+application/octet-stream的Content-Type,服务器总是返回501错误。
后来查看了mod_python/util.py脚本,发现设置的PythonHandler是mod_python.publisher,对于POST请求,其Content-Type有约束条件:
109 if req.method != "POST": 110 return 111 112 try: 113 clen = int(req.headers_in["content-length"]) 114 except (KeyError, ValueError): 115 # absent content-length is not acceptable 116 raise apache.SERVER_RETURN, apache.HTTP_LENGTH_REQUIRED 117 118 if not req.headers_in.has_key("content-type"): 119 ctype = "application/x-www-form-urlencoded" 120 else: 121 ctype = req.headers_in["content-type"] 122 123 if ctype.startswith("application/x-www-form-urlencoded"): 124 pairs = parse_qsl(req.read(clen), keep_blank_values) 125 for pair in pairs: 126 # TODO : isn't this a bit heavyweight just for form fields ? 127 file = cStringIO.StringIO(pair[1]) 128 self.list.append(Field(pair[0], file, "text/plain", {}, None, {})) 129 return 130 131 if not ctype.startswith("multipart/"): 132 # we don't understand this content-type 133 raise apache.SERVER_RETURN, apache.HTTP_NOT_IMPLEMENTED
看来不能采用mod_python.publisher来作为PythonHandler了!
于是使用自定义的handler来作为PythonHandler,遇到另一个问题:
任何的请求都会使用这个handler来处理,导致不能使用多个不同的python脚本服务不同的请求。
思来想去,做了个迂回的方式:使用这个handler来做总控,每个不同的请求根据uri动态设置其PythonHandler
index.py脚本如下:
import os; from mod_python import apache def handler(req): handler = req.uri[1:]; if handler[-3:] == ".py" : handler = handler[0:-3]; if not handler == "index" : req.add_handler("PythonHandler", handler); return apache.OK;
AddDefaultCharset GBK Listen 8080 <VirtualHost *:8080> # AddType application/x-http-python .py DocumentRoot /usr/htdocs <IfModule alias_module> Alias /index /usr/htdocs/index.py </IfModule> <Directory "/usr/htdocs"> AllowOverride FileInfo SetHandler mod_python #PythonHandler mod_python.publisher PythonHandler index PythonDebug On Order allow,deny Allow from all </Directory> </VirtualHost>
关于apache+python中使用logging模块的问题,在我另一篇博客中有提及:
http://blog.csdn.net/hqin6/article/details/6729341