【问题标题】:SSL in python3 with HTTPServerpython3中的SSL与HTTPServer
【发布时间】:2014-03-15 20:58:07
【问题描述】:

我在这里找到了一个(显然)工作的用于 python 2 的 HTTPS 服务器:http://code.activestate.com/recipes/442473-simple-http-server-supporting-ssl-secure-communica/?c=15536

我正在尝试将其移植到 python3 中,但没有好的结果。这是我的代码:

from socketserver import BaseServer
import string,cgi,time
from os import curdir, sep
from http.server import SimpleHTTPRequestHandler, HTTPServer
import ssl
import os # os. path
import socket

class SecureHTTPServer(HTTPServer):
    def __init__(self, server_address, HandlerClass):
        BaseServer.__init__(self, server_address, HandlerClass)
        ctx = ssl.SSLContext(ssl.PROTOCOL_SSLv23)
        #server.pem's location (containing the server private key and
        #the server certificate).
        fpem = 'certificate1.pem'
        ctx.load_verify_locations(fpem)
        self.socket = ctx.wrap_socket(socket.socket(self.address_family,
                                                        self.socket_type))
        self.server_bind()
        self.server_activate()


class SecureHTTPRequestHandler(SimpleHTTPRequestHandler):
    def setup(self):
        self.connection = self.request
        self.rfile = socket._fileobject(self.request, "rb", self.rbufsize)
        self.wfile = socket._fileobject(self.request, "wb", self.wbufsize)
    def do_GET(self):
        print('get recieved!');
        self.send_error(404,'File Not Found: %s' % self.path)

def test(HandlerClass = SecureHTTPRequestHandler,
         ServerClass = SecureHTTPServer):
    server_address = ('', 1443) # (address, port)
    httpd = ServerClass(server_address, HandlerClass)
    sa = httpd.socket.getsockname()
    print ("Serving HTTPS on", sa[0], "port", sa[1], "...")
    httpd.serve_forever()


if __name__ == '__main__':
    test()

当我运行它时,我没有收到任何错误,但是当我连接到 localhost:1443(使用 https)时,我没有收到任何响应,并且 print('get recieved!'); 没有被触发。

【问题讨论】:

    标签: ssl python-3.x https


    【解决方案1】:

    我在这里找到了另一个(更简单的)解决方案:http://www.piware.de/2011/01/creating-an-https-server-in-python/

    这是我对python3的工作移植:

    from http.server import HTTPServer,SimpleHTTPRequestHandler
    from socketserver import BaseServer
    import ssl
    
    httpd = HTTPServer(('localhost', 1443), SimpleHTTPRequestHandler)
    httpd.socket = ssl.wrap_socket (httpd.socket, certfile='certificate.pem', server_side=True)
    httpd.serve_forever()
    

    【讨论】:

    • 我认为你不需要BaseServer。
    • 谢谢,这主要适用于我,但我必须在 wrap_socket 调用中添加我的私钥 (keyfile='private.pem') 的参数。
    【解决方案2】:

    从 Python 3.7 开始,ssl.wrap_socket 已弃用,请改用 SSLContext.wrap_socket:

    检查:https://docs.python.org/3.7/library/ssl.html#ssl.wrap_socket

    from http.server import HTTPServer,SimpleHTTPRequestHandler
    import ssl
    
    httpd = HTTPServer(('localhost', 1443), SimpleHTTPRequestHandler)
    sslctx = ssl.SSLContext()
    sslctx.check_hostname = False # If set to True, only the hostname that matches the certificate will be accepted
    sslctx.load_cert_chain(certfile='certificate.pem', keyfile="private.pem")
    httpd.socket = sslctx.wrap_socket(httpd.socket, server_side=True)
    httpd.serve_forever()
    

    【讨论】:

    • 谢谢!现在使用您的代码,我们可以使用 sslcontext。一个简单的修复:ssl_ctx.wrap_sockert -> sslctx.wrapsocket
    猜你喜欢
    • 1970-01-01
    • 2020-02-03
    • 2016-01-22
    • 1970-01-01
    • 2016-06-04
    • 2020-07-09
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多