一、简介
这是一个简单的多线程https server。
版本:python3.7
前期工作:
python提供的http.server包能够帮助我们很方便的创建http(s) server。在这里我们准备创建的是https server,所以需要提前准备自己的密钥文件和证书文件。
- 密钥文件:privkey.pem
- 证书文件:certificate.pem
没有密钥文件和证书文件的同学可以参考creating self-signed SSL certificates with OpenSSL创建。这篇文章将使用openssl创建自签名证书过程写的很详细,推荐阅读。
我们可以将https server理解为在http server上包装一层ssl加密,这个过程并不复杂,只是在创建了http server之后,用ssl.wrap_socket()将其包装起来即可。
而创建http server也很简单,只要调用http.server中的BaseHTTPRequestHandler, HTTPServer。
那么多线程如何操作呢,调用ThreadingMixIn类就可以,甚至连类主体都不用写,简单到难以想象。
接下来看看完整的程序代码:一个简单的多线程https server。
二、完整程序
# A multithreaded https server in python3.7
from http.server import BaseHTTPRequestHandler, HTTPServer
from socketserver import ThreadingMixIn
import threading
import ssl
hostName = "localhost"
serverPort = 8080
class MyServer(BaseHTTPRequestHandler):
def do_GET(self):
self.send_response(200)
self.send_header("Content-type", "text/html")
self.end_headers()
self.wfile.write(bytes("<html><head><title>https://pythonbasics.org</title></head>", "utf-8"))
self.wfile.write(bytes("<p>Root Directory: %s</p>" % self.path, "utf-8"))
self.wfile.write(bytes("<p>Thread: %s</p>" % threading.currentThread().getName(), "utf-8"))
self.wfile.write(bytes("<p>Thread Count: %s</p>" % threading.active_count(), "utf-8"))
self.wfile.write(bytes("<body>", "utf-8"))
self.wfile.write(bytes("<p>This is an multithreaded web server.</p>", "utf-8"))
self.wfile.write(bytes("</body></html>", "utf-8"))
class ThreadingSimpleServer(ThreadingMixIn,HTTPServer):
pass
if __name__ == "__main__":
webServer = ThreadingSimpleServer((hostName, serverPort), MyServer)
webServer.socket = ssl.wrap_socket(webServer.socket, keyfile='./privkey.pem',certfile='./certificate.pem', server_side=True)
print("Server started http://%s:%s" % (hostName, serverPort))
try:
webServer.serve_forever()
except KeyboardInterrupt:
pass
webServer.server_close()
print("Server stopped.")
程序解读:
1. 程序的运行入口在if语句中:首先创建一个多线程服务器:
webServer = ThreadingSimpleServer((hostName, serverPort), MyServer)
hostName='localhost' 也就是‘127.0.0.1’;端口号设定为8080:serverPort='8080'。
当程序运行时,在浏览器中输入“https://localhost:8080”进行测试。
Myserver是我们定义的服务器类,继承了http.server中的BaseHTTPRequestHandler。重写的部分是Get函数,其中的self.wfile.write中的内容会在测试网页上显示,显示的内容包括服务器运行的路径、当前的线程名字、活跃的线程个数。
2. 将创建的服务器webserver用ssl加密包装起来:
webServer.socket = ssl.wrap_socket(webServer.socket, keyfile='./privkey.pem',certfile='./certificate.pem', server_side=True)
在这里用到了准备好的密钥文件和证书文件,注意server_side设定为True。
3. 启动webserver。
webServer.serve_forever()
4. 运行结果:
运行时控制台显示:
在浏览器打开“https://localhost:8080”:
第一次打开网页会提示不安全,这是因为我们用的是自签名证书,不具有第三方认证权威效力,我们做实验时用自签名证书已经足够,点击继续前往。如果是做网站最好是用第三方认证的证书。
返回看控制台显示信息:
多刷新几次网页:
停止运行:
【参考资料】
https://docs.python.org/3/library/http.server.html
https://blog.anvileight.com/posts/simple-python-http-server/#twiseted-as-a-simple-web-http-s-server
https://www.techbeamers.com/python-tutorial-write-multithreaded-python-server/