Python 服务器图片 python 简单服务器
Python运行环境:Ubuntu Ubuntu 18.04.1 LTS
本文仅用于记录学习和分析Python的过程,Python还有很多搭建web服务器的框架本文都不涉及。
最简单的方式
执行命令:
$ python -m SimpleHTTPServer //如果不指定端口,默认使用8000然后在浏览器上输入:
http://localhost:8000/ //把localhost改成Linux主机ip然后Duang~~~
网页上显示出这个,那个A_File是我在Linux下运行Python文件里面的一个文件。
什么,就这么简单?好吧,作为一个Linux C程序员,不得不说,我得研究一下源码。
SimpleHTTPServer
网页哪来的?
最基本的理解是,有网页就得有html文件,而且很显而易见的是,这个网页看上去是调整过格式的。
开始的想法
一开始想到就是在我的Linux环境里是有一个这样的html文件存在的,在使用SimpleHTTPServer模块时会找到它,并且推给前端。然后就在Python安装路径和系统里找这个文件,最后都把以前玩过的Apache和Tomcat里面的html都翻出来了也没对上号。。。
换个思路
先考虑两点:
1. 打开网页时HTTP Server会有这样的信息:“GET / HTTP/1.1” 200 -。说明打开网页的时候执行的是GET请求(这个好像是理所当然的)。
2. 从浏览器上查看网页源码:
接下来从源码的角度分析一下:
在我的Linux系统中找到SimpleHTTPServer模块源码(感兴趣的源码自行查找),查看do_GET() 方法:
这么一看应该是要看一下send_head() 方法做了什么,里面有这样一段代码:
path = self.translate_path(self.path) f = None if os.path.isdir(path): parts = urlparse.urlsplit(self.path) if not parts.path.endswith('/'): # redirect browser - doing basically what apache does self.send_response(301) new_parts = (parts[0], parts[1], parts[2] + '/', parts[3], parts[4]) new_url = urlparse.urlunsplit(new_parts) self.send_header("Location", new_url) self.end_headers() return None for index in "index.html", "index.htm": index = os.path.join(path, index) if os.path.exists(index): path = index break else: return self.list_directory(path)主要看一下for循环的作用,实际上是在当前路径下查找index.html, index.htm 如果没找到就return到 list_directory() 方法,紧接着就在list_directory() 方法里看到这样的代码:
f.write('<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">') f.write("<html>\n<title>Directory listing for %s</title>\n" % displaypath) f.write("<body>\n<h2>Directory listing for %s</h2>\n" % displaypath) f.write("<hr>\n<ul>\n") for name in list: fullname = os.path.join(path, name) displayname = linkname = name # Append / for directories or @ for symbolic links if os.path.isdir(fullname): displayname = name + "/" linkname = name + "/" if os.path.islink(fullname): displayname = name + "@" # Note: a link to a directory displays with @ and links with / f.write('<li><a href="%s">%s</a>\n' % (urllib.quote(linkname), cgi.escape(displayname))) f.write("</ul>\n<hr>\n</body>\n</html>\n")很显然,这个段代码刚好对应到了上面贴的网页源码。现在真相大白了,在打开网页时do_GET() 方法会调用 list_directory() 创建一个html出来给前端显示。
验证一下
虽然从代码的逻辑上分析完了,但是总觉得怪怪的,还是要自己跑一下代码才放心啊。
使用Python的好处就是可以方便的进行验证,这一点就比C方便的多。
首先把SimpleHTTPServer.py从源码路径里copy出来放到与A_File同一路径下,然后执行命令:
然后用服务器ip打开网页会看到:
网页可以正常打开,显示的也正是预期的结果,说明刚刚的操作是正确的。
这也正是用Python的优势所在,这个源码文件其实是需要BaseHTTPServer 等模块支持的,但是我并没有把这个模块copy过来。当然也是因为在Linux环境下安装Python的时候就已经配置好环境变量了。当然也可以类比Shell。根据上面的分析,如果再当前路径下有html文件会怎么样呢?
创建一个index.html文件,里面加上一句"Hello World!",然后启动脚本在打开网页会显示如下:
(万年的Hello World???)
这说明之前对那个for 循环部分的代码分析是没错的。同样的可以把list_directory() 方法里面的StringIO 打印出来也会对上面的介绍进行验证。
至于在GET请求时 “GET / HTTP/1.1” 200 - 这个信息打印是怎么打印出来的呢,可以把BaseHTTPServer 模块源码copy过来做一下验证,里面有个log_message() 方法,具体代码逻辑就不在这里分析了。
也就是说,所有的现象只要仔细分析一下源码都能找到根源。
为什么要用Python搭建,因为如果单纯的想要从服务器上下载文件,用Python 的SimpleHTTPServer 模块搭建一个服务器要比搭建ftp或者是tftp简单的多。
但是这个单纯的执行一下 命令python -m SimpleHTTPServer,只能实现文件的下载功能,如果想要实现文件上传功能可以参考:https:///tualatrix/tools/blob/master/SimpleHTTPServerWithUpload.py 这里面实现了POST请求功能。