最近使用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 return111 112 try:113 clen = int(req.headers_in["content-length"])114 except (KeyError, ValueError):115 # absent content-length is not acceptable116 raise apache.SERVER_RETURN, apache.HTTP_LENGTH_REQUIRED117 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 return130 131 if not ctype.startswith("multipart/"):132 # we don't understand this content-type133 raise apache.SERVER_RETURN, apache.HTTP_NOT_IMPLEMENTED
其中的HTTP_NOT_IMPLEMENTED就是伺服器返回的501錯誤。
看來不能採用mod_python.publisher來作為PythonHandler了!
於是使用自訂的handler來作為PythonHandler,遇到另一個問題:
任何的請求都會使用這個handler來處理,導致不能使用多個不同的python指令碼服務不同的請求。
思來想去,做了個迂迴的方式:使用這個handler來做總控,每個不同的請求根據uri動態設定其PythonHandler
index.py指令碼如下:
import os;from mod_python import apachedef 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;
這樣配合下面的設定檔,一切就都ok了!
AddDefaultCharset GBKListen 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