2014-05-07
笔者使用的python版本是2.7.6。
陈皓在非常简单的Python HTTP服务介绍了python自带的针对静态网站的http服务器,例如要以/home/www为http server的DocumentRoot,可以:
cd /home/www
python -m SimpleHTTPServer
之后在浏览器中访问http://127.0.0.1:8000
即可。
这种方法在我的Linux Mint下运行正常,也可以正确的处理中文路径。
但是在windows下遇到中文路径时候就出问题了,可能会显示404,例如本站当前使用的是静态博客系统hexo,我
cd hexo\public
python -m SimpleHTTPServer
然后访问 http://127.0.0.1:8000/2014/04/27/代码高亮之Prism/
,这个路径是确实存在的,但是却出现404错误:
有时候也会遇到列举目录内容的页面中的中文出现乱码的情况。
本文就试图解决这些情况。
分析问题
关于404
使用firebug分析访问http://127.0.0.1:8000/2014/04/27/代码高亮之Prism/
时出现了什么情况,
首先查看到的请求头中的第一行内容如下:
GET /2014/04/27/%E4%BB%A3%E7%A0%81%E9%AB%98%E4%BA%AE%E4%B9%8BPrism/
python -m SimpleHTTPServer
运行时会简要的显示部分工作过程 python server收到的请求如下以及发出的响应如下:
127.0.0.1 - - [07/May/2014 14:19:51] "GET /2014/04/27/%E4%BB%A3%E7%A0%81%E9%AB%98%E4%BA%AE%E4%B9%8BPrism/ HTTP/1.1" 404 -
客户端发送的请求路径和服务是相同的。本地文件系统中,2014/04/27/代码高亮之Prism/
目录下也确实存在index.html。
代码高亮之Prism使用utf8进行urlencode的结果也是%E4%BB%A3%E7%A0%81%E9%AB%98%E4%BA%AE%E4%B9%8BPrism
。 这说明SimpleHTTPServer没有正确将utf8编码的路径与windows系统下的相应文件对应起来。
也就是SimpleHTTPServer通过客户端请求的信息去打开本地的静态文件时,并没有正确的打开。如果相应的路径又确实存在的话,那么可能是SimpleHTTPServer直接
open('代码高亮之Prism/index.html')
,而非
open('代码高亮之Prism/index.html'.decode('utf-8'))
。
列举目录内容时候出现了什么情况
浏览器访问http://127.0.0.1:8000/2014/04/27/
,结果如下:
正常显示,但背后隐藏着问题。
首先使用firebug查看http响应头,
HTTP/1.0 200 OK
Server: SimpleHTTP/0.6 Python/2.7.6
Date: Wed, 07 May 2014 06:38:22 GMT
Content-Type: text/html; charset=mbcs
Content-Length: 272
其中比较奇怪的是charset指定的值是mbcs。(关于mbcs,请参考支持多字节字符集,其来源于python的SimpleHTTPServer模块,具体请查看源码,源码位置会在下文中提及。)
然后查看html源码:
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
<html>
<head>
<title>Directory listing for /2014/04/27/</title>
</head>
<body>
<h2>Directory listing for /2014/04/27/</h2>
<hr>
<ul>
<li>
<a href="%B4%FA%C2%EB%B8%DF%C1%C1%D6%AEPrism/">代码高亮之Prism/</a>
</li>
</ul>
<hr>
</body>
</html>
首先上面的源码中并未指定
<meta content="text/html; charset=UTF-8" http-equiv="Content-Type">
或者类似的内容。
另外,代码高亮之Prism
的url编码明显和之前的不一样。
%B4%FA%C2%EB%B8%DF%C1%C1%D6%AEPrism
需要使用GB2312进行解码;
%E4%BB%A3%E7%A0%81%E9%AB%98%E4%BA%AE%E4%B9%8BPrism
需要使用UTF8解码,两者的解码结果都是代码高亮之Prism
。
分析SimpleHTTPServer
命令python -m SimpleHTTPServer
中参数-m
在文档中解释如下:
-m mod : run library module as a script (terminates option list)
也就是说。SimpleHTTPServer
其实是一个模块。
以windows为例子,进入python安装路径,进入Lib目录,可以找到SimpleHTTPServer.py
,在该文件最后可以找到以下内容:
def test(HandlerClass = SimpleHTTPRequestHandler,
ServerClass = BaseHTTPServer.HTTPServer):
BaseHTTPServer.test(HandlerClass, ServerClass)
if __name__ == '__main__':
test()
这就是python -m SimpleHTTPServer
能够运行的原因。
SimpleHTTPServer中的类 SimpleHTTPRequestHandler是核心内容,内容较简单,此处不做分析。
改善SimpleHTTPServer
笔者对python自带的SimpleHTTPServer略作修改,使其能在linux和windows正常工作,代码见下面。如果有读者要用到它,建议将其保存为SimpleHTTPServer2.py并放到目录Lib
中,使用
python -m SimpleHTTPServer2
运行即可。 另外,若是需要改变监听端口、让SimpleHTTPServer/SimpleHTTPServer2只服务于本地环境,请参考非常简单的Python HTTP服务。
地址: https://github.com/letiantian/SimpleHTTPServer2