Skip to content

Instantly share code, notes, and snippets.

@dergachev
Created October 17, 2013 17:07
Show Gist options
  • Save dergachev/7028596 to your computer and use it in GitHub Desktop.
Save dergachev/7028596 to your computer and use it in GitHub Desktop.
# taken from http://www.piware.de/2011/01/creating-an-https-server-in-python/
# generate server.xml with the following command:
# openssl req -new -x509 -keyout server.pem -out server.pem -days 365 -nodes
# run as follows:
# python simple-https-server.py
# then in your browser, visit:
# https://localhost:4443
import BaseHTTPServer, SimpleHTTPServer
import ssl
httpd = BaseHTTPServer.HTTPServer(('localhost', 4443), SimpleHTTPServer.SimpleHTTPRequestHandler)
httpd.socket = ssl.wrap_socket (httpd.socket, certfile='./server.pem', server_side=True)
httpd.serve_forever()
@akhiljalagam
Copy link

authentication is possible?

@miqmago
Copy link

miqmago commented Jan 23, 2020

Serve another folder and public in your network

#!/usr/bin/python
# taken from http://www.piware.de/2011/01/creating-an-https-server-in-python/
# generate server.xml with the following command:
#    openssl req -new -x509 -keyout server.pem -out server.pem -days 365 -nodes
# run as follows:
#    python simple-https-server.py
# then in your browser, visit:
#    https://localhost:4443
#
# openssl req -new -x509 -keyout server.pem -out server.pem -days 365 -nodes

import sys
import BaseHTTPServer, SimpleHTTPServer
import ssl
import os

httpd = BaseHTTPServer.HTTPServer(('127.0.0.1', 4443), SimpleHTTPServer.SimpleHTTPRequestHandler)
httpd.socket = ssl.wrap_socket(httpd.socket, certfile='server.pem', server_side=True)

if len(sys.argv) > 1:
    os.chdir(sys.argv[1])

httpd.serve_forever()

@abinhho
Copy link

abinhho commented Mar 31, 2020

Got error?
ssl.SSLError: [SSL] PEM lib (_ssl.c:3833)

@oleksandrkuzmin
Copy link

Hello, does anybody know how to serve both http and https?

@abinhho
Copy link

abinhho commented Apr 1, 2020

If you dont care env, you can use nodejs to create https locally
https://github.com/abinhho/https-locally-nodejs

@VaradLanke
Copy link

VaradLanke commented Jun 24, 2020

Hello,

  • I implemented better solution.
  • It generates certificate for you automatically.
  • Only one command to start your https-file-server with automatically generated certificates.
  • Here is code : code

@JayHoltslander
Copy link

@VaradLanke
Copy link

VaradLanke commented Jun 29, 2020

@VaradLanke

404 Not found

Sorry for bad link, i have updated the link now. - Link

@ingnelson
Copy link

How to add a CONNECT method support and the server send back to the client this response : HTTP/1.1 200 Connection established\r\n\r\n

@andressalinero
Copy link

Great help! Thank you!

@devhigh29
Copy link

So i created this server, works perfectly!
Now i have multiple processes accessing this server and downloading files from it, i want to print the amount of data being downloaded from this server, need help!

@bradtem
Copy link

bradtem commented Sep 13, 2020

Works as advertised, but when I change to use http.server.CGIHTTPRequestHandler)
instead of the Simple one, it is supposed to drop-in replace, but any attempt to get a CGI says:

Exception happened during processing of request from ('127.0.0.1', 48852)
Traceback (most recent call last):
File "/usr/lib/python3.8/socketserver.py", line 316, in _handle_request_noblock
self.process_request(request, client_address)
File "/usr/lib/python3.8/socketserver.py", line 347, in process_request
self.finish_request(request, client_address)
File "/usr/lib/python3.8/socketserver.py", line 360, in finish_request
self.RequestHandlerClass(request, client_address, self)
File "/usr/lib/python3.8/http/server.py", line 647, in init
super().init(*args, **kwargs)
File "/usr/lib/python3.8/socketserver.py", line 720, in init
self.handle()
File "/usr/lib/python3.8/http/server.py", line 427, in handle
self.handle_one_request()
File "/usr/lib/python3.8/http/server.py", line 415, in handle_one_request
method()
File "/usr/lib/python3.8/http/server.py", line 651, in do_GET
f = self.send_head()
File "/usr/lib/python3.8/http/server.py", line 997, in send_head
return self.run_cgi()
File "/usr/lib/python3.8/http/server.py", line 1166, in run_cgi
if not self.rfile.read(1):
File "/usr/lib/python3.8/socket.py", line 669, in readinto
return self._sock.recv_into(b)
File "/usr/lib/python3.8/ssl.py", line 1241, in recv_into
return self.read(nbytes, buffer)
File "/usr/lib/python3.8/ssl.py", line 1099, in read
return self._sslobj.read(len, buffer)
ssl.SSLError: [SSL: TLSV1_ALERT_PROTOCOL_VERSION] tlsv1 alert protocol version (_ssl.c:2607)

don't understand the cause for a protocol version problem. This is a recent Ubuntu 20.04 system with Python 3.8.2 and a recent chrome browser.

@rojenzaman
Copy link

It's so helped, thanks.

@VaniChinchakhandi
Copy link

Is there a way to configure the username/password for the authentication of the server.

@W01fw00d
Copy link

This just made my day, thank you!

@Honghe
Copy link

Honghe commented Mar 21, 2021

❤️ ❤️ ❤️ ❤️ ❤️ ❤️ ❤️ ❤️ ❤️ ❤️

I'd like to access it by another machine. here's solution based on @telmotrooper 's code

#!/usr/bin/env python3

# Ported to Python 3 by Telmo "Trooper" ([email protected])
# 
# Original code from:
# http://www.piware.de/2011/01/creating-an-https-server-in-python/
# https://gist.github.com/dergachev/7028596
# 
# To generate a certificate use:
# openssl req -new -x509 -keyout server.pem -out server.pem -days 365 -nodes

from http.server import HTTPServer, SimpleHTTPRequestHandler
import ssl

separator = "-" * 80
port = 4443
httpd = HTTPServer(("", port), SimpleHTTPRequestHandler)
httpd.socket = ssl.wrap_socket(httpd.socket, certfile="/home/dshwang/bin/https/server.pem", server_side=True)

print(separator)
print("Server running on https://localhost:" + str(port))
print(separator)

httpd.serve_forever()

This is my modified version.

#!/usr/bin/env python3

# by Honghe
# Ported to Python 3 by Telmo "Trooper" ([email protected])
#
# Original code from:
# http://www.piware.de/2011/01/creating-an-https-server-in-python/
# https://gist.github.com/dergachev/7028596
#
# To generate a certificate use:
# openssl req -newkey rsa:4096 -nodes -keyout key.pem -x509 -days 365 -out cert.pem

from http.server import HTTPServer, SimpleHTTPRequestHandler
import ssl

port = 4443
httpd = HTTPServer(('0.0.0.0', port), SimpleHTTPRequestHandler)
httpd.socket = ssl.wrap_socket(httpd.socket, keyfile='key.pem', certfile="cert.pem", server_side=True)

print("Server running on https://0.0.0.0:" + str(port))

httpd.serve_forever()

@1kastner
Copy link

1kastner commented Apr 16, 2021

Thank you @Honghe for sharing this updated version! I have just made some minor modifications I thought maybe others could like too.

from http.server import HTTPServer, SimpleHTTPRequestHandler
import ssl, os
os.system("openssl req -nodes -x509 -newkey rsa:4096 -keyout key.pem -out cert.pem -days 365 -subj '/CN=mylocalhost'")
port = 443
httpd = HTTPServer(('0.0.0.0', port), SimpleHTTPRequestHandler)
httpd.socket = ssl.wrap_socket(httpd.socket, keyfile='key.pem', certfile="cert.pem", server_side=True)
print(f"Server running on https://0.0.0.0:{port}")
httpd.serve_forever()

@jcPOLO
Copy link

jcPOLO commented Apr 26, 2021

Thank you @Honghe for sharing this updated version! I have just made some minor modifications I thought maybe others could like too.

from http.server import HTTPServer, SimpleHTTPRequestHandler
import ssl, os
os.system("openssl req -nodes -x509 -newkey rsa:4096 -keyout key.pem -out cert.pem -days 365 -subj '/CN=mylocalhost'")
port = 443
httpd = HTTPServer(('0.0.0.0', port), SimpleHTTPRequestHandler)
httpd.socket = ssl.wrap_socket(httpd.socket, keyfile='key.pem', certfile="cert.pem", server_side=True)
print(f"Server running on https://0.0.0.0:{port}")
httpd.serve_forever()

thanks man!

@Alexufo
Copy link

Alexufo commented Oct 29, 2021

I did update for python 3.10 + (ssl.wrap_socket() is deprecated)

https://gist.github.com/Alexufo/2303bff77f0a16ba83568f0260b8cf47

@fqqf
Copy link

fqqf commented Jan 10, 2022

Awesome!

@kashmax
Copy link

kashmax commented Apr 13, 2022

Hi,
Can anyone comment about the usage of this honeyhttpd?
Thank you

@OriKovacsiKatz
Copy link

hi @Honghe and @jcPOLO used this snippet of https on local host - there is an error message:
Can't open C:\Program Files\Common Files\ssl/openssl.cnf for reading, No such file or directoryCan't open C:\Program Files\Common Files\ssl/openssl.cnf for reading, No such file or directory

how can I generate this cnf file correctly?
thanks
Ori

@ciscohack
Copy link


Can you help me how to make this work?

#!/usr/bin/python
from BaseHTTPServer import BaseHTTPRequestHandler,HTTPServer
import ssl
import sys

PORT_NUMBER = int(sys.argv[1])

#This class will handles any incoming request from
#the browser 
class myHandler(BaseHTTPRequestHandler):
	#Handler for the GET requests
	def do_GET(self):
		print(self.requestline)
		#print(self.rfile.read(content_length))
		self.send_response(200)
		self.send_header('Content-type','text/html')
		self.end_headers()
		# Send the html message
		self.wfile.write("Hello World !".encode())
		return

try:
	#Create a web server and define the handler to manage the
	#incoming request
	server = HTTPServer(('', PORT_NUMBER), myHandler)
	server.socket = ssl.wrap_socket(server.socket, certfile='cert.pem',keyfile='key.pem',  server_side=True)
	print 'Started httpserver on port ' , PORT_NUMBER
	
	#Wait forever for incoming htto requests
	server.serve_forever()

except KeyboardInterrupt:
	print '^C received, shutting down the web server'
	server.socket.close()

When I run it and load it from the browser... It's only loading and never displaying the "Hello Word!" text. But it'll only show when I ctrl+c the server whilst loading. Can anyone tell me what's the solution for this?

openssl req -new -x509 -keyout key.pem -out server.pem -days 365 -nodes

#!/usr/bin/python
import http.server
import ssl
import sys

# Open SSL Certificate
# openssl req -new -x509 -keyout key.pem -out server.pem -days 365 -nodes

PORT_NUMBER = int(sys.argv[1])

# This class will handles any incoming request from
# the browser


class myHandler(http.server.SimpleHTTPRequestHandler):
    # Handler for the GET requests
    def do_GET(self):
        print(self.requestline)
        # print(self.rfile.read(content_length))
        self.send_response(200)
        self.send_header('Content-type', 'text/html')
        self.end_headers()
        # Send the html message
        self.wfile.write("Hello World !".encode())
        return


try:
    # Create a web server and define the handler to manage the
    # incoming request
    server = http.server.HTTPServer(('', PORT_NUMBER), myHandler)
    server.socket = ssl.wrap_socket(server.socket, certfile='cert.pem', keyfile='key.pem', server_side=True)
    print('Started httpserver on port ', PORT_NUMBER)

    # Wait forever for incoming htto requests
    server.serve_forever()

except KeyboardInterrupt:
    print('^C received, shutting down the web server')
    server.socket.close()

@Dragorn421
Copy link

Updated to Python 3.11.4 (http.server module changes, ssl module changes/deprecations)

from http.server import HTTPServer, SimpleHTTPRequestHandler
import ssl
from pathlib import Path

port = 4443

httpd = HTTPServer(("localhost", port), SimpleHTTPRequestHandler)
ssl_context = ssl.SSLContext(ssl.PROTOCOL_TLS_SERVER)
ssl_context.load_cert_chain(Path(__file__).parent / "server.pem")
httpd.socket = ssl_context.wrap_socket(
    httpd.socket,
    server_side=True,
)

print(f"Serving on https://localhost:{port}")
httpd.serve_forever()

@stephenlb
Copy link

Nice!

@ak64th
Copy link

ak64th commented May 7, 2024

Do you guys get it work on 443 port? It works on any other port on my laptop but 443. Though nmap and netstat -tulpn show the port is open, curl and openssl s_client always say connection refused.

@telmotrooper
Copy link

@Dragorn421 Thanks for the up-to-date version! 🙂️

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment