Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
# 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()
@guyo13
Copy link

guyo13 commented Nov 11, 2018

Hello
I made a modification of this so that the private key is not saved in the same file as the certificate.
You can view it here: https://gist.github.com/guyo13/9f3955de7fb20927d8e9218c1dcd2691

The modified openssl command:
openssl req -new -x509 -keyout key.pem -out server.pem -days 365 -nodes

And in the python code you have to specify the key using the keyword argument 'keyfile':

httpd.socket = ssl.wrap_socket (httpd.socket, keyfile='./key.pem', certfile='./server.pem', server_side=True)

@angeloped
Copy link

angeloped commented Dec 15, 2018

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?

@jakesylvestre
Copy link

jakesylvestre commented Dec 24, 2018

If you want it on another machine, I'd take a look at ngrok

@DannyHinshaw
Copy link

DannyHinshaw commented Mar 7, 2019

Here's a Python3 version for those interested. Forked from @guyo13 's fork with separate key/cert files.

https://gist.github.com/DannyHinshaw/a3ac5991d66a2fe6d97a569c6cdac534

@dshah323
Copy link

dshah323 commented Jul 25, 2019

Can it be configured to return 200 OK to every request ?

@sagiii
Copy link

sagiii commented Nov 13, 2019

Thanks!!

@evandrix
Copy link

evandrix commented Nov 25, 2019

server.xml server.pem

@modenero
Copy link

modenero commented Jan 2, 2020

Thank you!

@akhiljalagam
Copy link

akhiljalagam commented Jan 20, 2020

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

oleksandrkuzmin commented Mar 31, 2020

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

JayHoltslander commented Jun 29, 2020

@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

ingnelson commented Jul 2, 2020

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

andressalinero commented Jul 6, 2020

Great help! Thank you!

@devhigh29
Copy link

devhigh29 commented Sep 3, 2020

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

rojenzaman commented Jan 25, 2021

It's so helped, thanks.

@VaniChinchakhandi
Copy link

VaniChinchakhandi commented Feb 5, 2021

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

@W01fw00d
Copy link

W01fw00d commented Feb 24, 2021

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" (telmo.trooper@gmail.com)
# 
# 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" (telmo.trooper@gmail.com)
#
# 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

OriKovacsiKatz commented Jul 27, 2022

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

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