I found here a (apparently-)working HTTPS server for python 2: http://code.activestate.com/recipes/442473-simple-http-server-supporting-ssl-secure-communica/?c=15536
I'm trying to port it in python3 but I have no good results. This is my code:
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()
When I run it I get no errors, but when I connect to localhost:1443 (with https) I get no response and the print('get recieved!');
is't triggered.
Note: If you are using this to serve web traffic, you will need to use '0.0. 0.0' in place of 'localhost' to bind to all interfaces, change the port to 443 (the standard port for HTTPS), and run with superuser privileges in order to have the permission to bind to a well-known port.
Socket creation The helper functions create_default_context() returns a new context with secure default settings. The old wrap_socket() function is deprecated since it is both inefficient and has no support for server name indication (SNI) and hostname matching.
Do_handshake() Method Of SSLSocket Class In Python The method do_handshake() does the TLS handshaking with the peer. While the TLS handshaking can be done as part of connecting with the peer, it can also be opted for later by calling the do_handshake() explicitly.
ssl() support for TLS over sockets is being superseded in Python 2.6 by a new 'ssl' module. This package brings that module to older Python releases, 2.3. 5 and up (it may also work on older versions of 2.3, but we haven't tried it).
From Python 3.7 ssl.wrap_socket is deprecated, use SSLContext.wrap_socket instead:
check: 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()
I found another (simpler) solution here: http://www.piware.de/2011/01/creating-an-https-server-in-python/
This is my working porting to 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()
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With