Last active
January 25, 2022 14:29
-
-
Save tomazas/af5b47bbf334b6502f8a0c94069a6540 to your computer and use it in GitHub Desktop.
Python 3 multi-threaded HTTPS server implementing GET & POST on port 443
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# Python 3 multi-threaded HTTPS server implementing GET & POST on port 443 | |
# Tested using Python 3.10.1 | |
# can be used with a generated self-signed certificate using bash command: | |
# openssl req -x509 -nodes -newkey rsa:4096 -keyout key.pem -out cert.pem -sha256 -days 365 | |
# run using below run.sh bash script: | |
''' | |
#!/bin/bash | |
nohup /usr/bin/python -u http_ssl_server.py > server.log 2>&1 & | |
echo $! > pid | |
''' | |
# stop using below stop.sh bash script: | |
''' | |
#!/bin/bash | |
kill -9 `cat pid` | |
rm pid | |
''' | |
import http.server | |
import socketserver | |
import sys | |
import ssl | |
import socket | |
# config | |
hostName = "0.0.0.0" | |
serverPort = 443 | |
socket_timeout = 2 | |
payload = "<html><head></head><body><h2>%s<br/>SSL node reached successfully</h2></body></html>" | |
class Handler(http.server.BaseHTTPRequestHandler): | |
def respond(self, title): | |
self.sys_version = "1.0" | |
self.server_version = "HTTPS Server" # prevent leaking python version | |
self.close_connection = True # ensure threads close the socket | |
self.send_response(200) | |
self.send_header('Content-type', 'text/html') | |
self.end_headers() | |
self.wfile.write(str.encode(payload%title)) | |
def do_GET(self): | |
self.respond("HTTP GET") | |
def do_POST(self): | |
content_len = int(self.headers.get('Content-Length', 0)) | |
if content_len > 0: | |
post_body = self.rfile.read(content_len) | |
self.respond("HTTP POST") | |
# patch for Python3 issue #46518 | |
old_accept = socket.socket.accept | |
def patch_accept(self): | |
newsock, addr = old_accept(self) | |
newsock.settimeout(socket_timeout) | |
return newsock, addr | |
socket.socket.accept = patch_accept | |
print("starting %s:%d"%(hostName, serverPort)) | |
httpd = http.server.ThreadingHTTPServer((hostName, serverPort), Handler) | |
ctx = ssl.SSLContext(ssl.PROTOCOL_TLS_SERVER) | |
ctx.verify_mode = ssl.CERT_OPTIONAL # client is not required to provide certificate | |
ctx.check_hostname = False # server hostname not validated agains certificate | |
ctx.load_default_certs() | |
ctx.load_cert_chain(certfile='./cert.pem', keyfile='./key.pem', password=None) | |
httpd.socket = ctx.wrap_socket(httpd.socket,server_side=True) | |
httpd.serve_forever() | |
print("done") |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment