python-simplehttp_python内置HTTP服务SimpleHTTPServer
python simplehttp_python内置HTTP服务(SimpleHTTPServer)
我们可以很简单的使用SimpleHTTPServer快速搭建一个http服务,提供一个文件浏览的web服务,首先进入一个目录,之后再该目录中按如下操作即可创建http服务:
一、python2.x环境
a、no ssl
python -m SimpleHTTPServer 80(自定义端口)
说明:
– 只能接受端口作为参数绑定地址参数不可用Python 2.x文档
– 如果目录下有index.html或者(index.htm),那么index.html文件会被视为默认主页;如果不存在index.html文件,那么就会显示整个目录列表
b、with ssl
创建server.py
import BaseHTTPServer, SimpleHTTPServer
import ssl
class MyRequestHandler(SimpleHTTPServer.SimpleHTTPRequestHandler):
def translate_path(self, path):
index = path.find(’/’, 2)
return SimpleHTTPServer.SimpleHTTPRequestHandler.translate_path(self,"/index.html")
httpd = BaseHTTPServer.HTTPServer((’’, 443), MyRequestHandler)
httpd = BaseHTTPServer.HTTPServer((’’, 8444), SimpleHTTPServer.SimpleHTTPRequestHandler)
httpd.socket = ssl.wrap_socket(httpd.socket, certfile=‘localhost.pem’, server_side=True)
httpd.socket = ssl.wrap_socket(httpd.socket,keyfile="./3064079_myclusterbox.com.key", certfile=’./3064079_myclusterbox.com.pem’, server_side=True)
httpd.serve_forever()
运行python server.py以启动服务器
可能遇到如下问题:
二、python3.x环境
a、no ssl
python3 -m http.server 8000 –bind 127.0.0.1
说明:
– 端口和绑定地址都是可选的。有关更多详细信息,请阅读官方文档。
b、with ssl
from http.server import HTTPServer, BaseHTTPRequestHandler
import ssl
httpd = HTTPServer((’localhost’, 4443), BaseHTTPRequestHandler)
httpd.socket = ssl.wrap_socket (httpd.socket,
keyfile=“path/to/key.pem”,
certfile=‘path/to/cert.pem’, server_side=True)
httpd.serve_forever()
c、Do_GET请求示例
from http.server import HTTPServer, BaseHTTPRequestHandler
class SimpleHTTPRequestHandler(BaseHTTPRequestHandler):
def do_GET(self):
self.send_response(200)
self.end_headers()
self.wfile.write(b’Hello, world!’)
httpd = HTTPServer((’localhost’, 8000), SimpleHTTPRequestHandler)
httpd.serve_forever()
这是一个非常简单的HTTP服务器,它可以响应Hello,世界!给请求者。请注意,这self.send_response(200)和 self.end_headers()是强制性的,否则不会响应被视为有效。我们可以通过使用HTTPie发送请求来检查它是否确实有效:
$ http http://127.0.0.1:8000
HTTP/1.0 200 OK
Date: Sun, 25 Feb 2018 17:26:20 GMT
Server: BaseHTTP/0.6 Python/3.6.1
Hello, world!
请注意,这self.wfile是一个类似对象的文件,因此希望该write函数使用类似字节的对象。喂的另一种方法wfile是使用BytesIO 对象(请参见下面的示例)。
d、Do_POST请求示例
from http.server import HTTPServer, BaseHTTPRequestHandler
from io import BytesIO
class SimpleHTTPRequestHandler(BaseHTTPRequestHandler):
def do_GET(self):
self.send_response(200)
self.end_headers()
self.wfile.write(b’Hello, world!’)
def do_POST(self):
content_length = int(self.headers[‘Content-Length’])
body = self.rfile.read(content_length)
self.send_response(200)
self.end_headers()
response = BytesIO()
response.write(b’This is POST request. ‘)
response.write(b’Received: ‘)
response.write(body)
self.wfile.write(response.getvalue())
httpd = HTTPServer((’localhost’, 8000), SimpleHTTPRequestHandler)
httpd.serve_forever()
可以通过访问请求正文self.rfile。它是一个BufferedReader, 因此read([size])应执行方法以获取内容。注意,size应该将其显式传递给函数,否则请求将挂起并且永不结束。这就是为什么content_length需要获取的原因。可以通过检索它self.headers并将其转换为整数。上面的示例只是打印出他收到的所有内容,如下所示:
http http://127.0.0.1:8000 key=value
HTTP/1.0 200 OK
Date: Sun, 25 Feb 2018 17:46:06 GMT
Server: BaseHTTP/0.6 Python/3.6.1
This is POST request. Received: {“key”: “value”}
如果愿意,您可以考虑解析JSON。
e、get请求访问index.html示例
import sys
from http.server import HTTPServer, BaseHTTPRequestHandler, SimpleHTTPRequestHandler
import ssl
import urllib
import os
class SimpleHTTPRequestHandler(SimpleHTTPRequestHandler):
def do_GET(self):
root = os.path.dirname(os.path.abspath(file))
filename = root + ‘/index.html’
self.send_response(200)
if filename[-4:] == ‘.css’:
self.send_header(‘Content-type’, ’text/css’)
elif filename[-5:] == ‘.json’:
self.send_header(‘Content-type’, ‘application/javascript’)
elif filename[-3:] == ‘.js’:
self.send_header(‘Content-type’, ‘application/javascript’)
elif filename[-4:] == ‘.ico’:
self.send_header(‘Content-type’, ‘image/x-icon’)
else:
self.send_header(‘Content-type’, ’text/html’)
self.end_headers()
with open(filename, ‘rb’) as fh:
html = fh.read()
self.wfile.write(html)
httpd = HTTPServer((’’, 443), SimpleHTTPRequestHandler)
httpd.socket = ssl.wrap_socket (httpd.socket,
keyfile="./3064079_myclusterbox.com.key",
certfile=’./3064079_myclusterbox.com.pem’, server_side=True)
httpd.serve_forever()
可能遇到如下问题:
附录一、生成自签名证书
需要确保“公用名”与服务器的名称相同,例如“ localhost”,如下
1、python2.x
openssl req -new -x509 -keyout localhost.pem -out localhost.pem -days 365 -nodes
2、python3.x
openssl req -x509 -newkey rsa:2048 -keyout key.pem -out cert.pem -days 365
注意:本文归作者所有,未经作者允许,不得转载