How to publish a Python based HTTP/HTTPS server on internet
In the last blog, we saw how you can publish a simple Python TCP server on your home machine such that it is available on the internet. You don’t buy any domain name or domain space or anything, just with an internet connection, you can publish your TCP server on the internet.
In this article, we are going to see how we can host an HTTP server on the internet. Such that an actual web page can be server to anyone trying to access your web server. We are going to do this in three steps:
1. Create a simple HTTP server in Python
2. Configure the home machine and home network so that the TCP port (which is same as HTTP port ) is published on internet
3. Run the HTTP server and access it over the internet.
- Create a simple HTTP server in Python
from http.server import BaseHTTPRequestHandler, HTTPServer
class SimpleHTTPRequestHandler(BaseHTTPRequestHandler):
def do_GET(self):
self.send_response(200)
self.end_headers()
self.wfile.write(b'Hello, World!')
def run(server_class=HTTPServer, handler_class=SimpleHTTPRequestHandler):
server_address = ('', 8585)
httpd = server_class(server_address, handler_class)
print(f'Starting httpd server on port 8585')
httpd.serve_forever()
if __name__ == '__main__':
run()
You can run this script, and then navigate to http://localhost:8585 in your web browser. You should see the message “Hello, World!”. But localhost is not going to work if you want to expose the HTTP page on the internet. So, run the command “ipconfig” and see what is the IPV4 address listed for your machine. Say it is 192.192.92.92, then you can navigate to http://192.192.92.92:8585.
This is just saying to ask for HTTP content from this domain at this port (8585)
Now ask your friend in a different city to go to the same page. You would expect them to see your Hello World web page. But they don’t see anything.
Why?
PORT FORWARDING. FIREWALL.
To make your simple Python HTTP server accessible over the internet, you’d have to:
1. Port Forwarding: Configure your home router to forward incoming requests to the local IP address of your machine. The exact steps to do this depend on the make and model of your router, but the basic idea is to go to your router’s settings page (usually accessible via a web browser), look for “Port Forwarding” or “Virtual Servers” section, and add a rule that forwards incoming connections on a specific port (in this case 8585) to the same port on your computer’s local IP address. Port Forwarding set up on TCP will also work for HTTP in most cases. Note that the default HTTP port is 80, but we are only using 8585 in this experiment setup.
2. Firewall Rules: Configure your computer’s firewall to allow incoming connections on the port your server is listening on. Here’s how to do it on Windows:
- Open Windows Defender Firewall.
— Click on Advanced settings.
— In the left pane, click on Inbound Rules.
— In the right pane, click on New Rule.
— In the Rule Type window, select Port and then click Next.
— In the Protocol and Ports window, select TCP. Enter the number of the port you want to open (in this case 8585), and then click Next.
— In the Action window, select Allow the connection and then click Next.
— In the Profile window, select when the rule should apply, and then click Next.
— In the Name window, give your rule a name (like “HTTP Server”), and then click Finish.
3. Public IP Address: Finally, you’ll need to give out your public IP address to anyone who wants to connect to your server. You can find your public IP address by visiting a website like https://www.whatismyip.com/ from a device on your home network. They would then connect to your server by entering your public IP address and the port number in their web browser, like so: http://<your-public-ip>:8585
Please remember that by making your server accessible over the internet, you’re exposing it to potential attacks. Make sure to follow good security practices, such as keeping your software up to date, using strong passwords, and so on. Also, this simple server isn’t designed for heavy traffic or for handling sensitive data. For a production environment, you should consider a more robust solution, like a dedicated web hosting service, a virtual private server (VPS), or a platform-as-a-service (PaaS) provider.
How does PORT FORWARDING work in this case?
Port forwarding enables your router to direct incoming traffic on a specific port to a specific machine on your local network. When you set up port forwarding on your router to forward traffic on a certain port (e.g., port 8585) to your machine, the router remembers this mapping.
When an external HTTP request arrives at your router destined for your public IP address on port 8585, the router checks its port forwarding rules. Seeing the rule you set up, it forwards the request to your machine on the same port (8585).
Now, if you have an HTTP server listening on port 8585 on your machine, it will receive this forwarded request. The server processes the request and sends a response back to the client.
The response goes back to the router, which uses Network Address Translation (NAT) to map the response back to your public IP address and the appropriate port. The response then gets sent over the internet back to the client who made the original request.
In summary, port forwarding allows external requests to reach your local HTTP server, and the server’s responses to reach back to the external client, all through your router’s handling of incoming and outgoing traffic according to its port forwarding and NAT rules.
Closing thoughts:
For more playground, it is always safe to quickly stop the HTTP server and instead use only HTTPS server. While it is a little harder to set up, once it is ready, it is safer, secure and allows richer and more realistic simulations of what you encounter on the internet.
To convert your HTTP server into an HTTPS server, you need to use SSL/TLS encryption. This requires a certificate and a private key. Python’s built-in http.server
module doesn't support HTTPS directly, but you can use the ssl
module to add HTTPS support.
Here is a basic example of how you might create an HTTPS server. This code assumes that you have a self-signed certificate cert.pem
and a private key key.pem
in the same directory as your server script. Please replace the paths as needed if your certificate and key are located elsewhere.
from http.server import HTTPServer, BaseHTTPRequestHandler
import ssl
class SimpleHTTPRequestHandler(BaseHTTPRequestHandler):
def do_GET(self):
self.send_response(200)
self.end_headers()
self.wfile.write(b'Hello, World!')
def run(server_class=HTTPServer, handler_class=SimpleHTTPRequestHandler):
server_address = ('', 8585)
httpd = server_class(server_address, handler_class)
httpd.socket = ssl.wrap_socket(httpd.socket,
server_side=True,
certfile='cert.pem',
keyfile='key.pem',
ssl_version=ssl.PROTOCOL_TLS)
print(f'Starting httpsd server on port 8585')
httpd.serve_forever()
if __name__ == '__main__':
run()
To generate a self signed certificate, you can use OpenSSL
openssl req -x509 -newkey rsa:4096 -nodes -out cert.pem -keyout key.pem -days 365
These two commands help you export the public certificate and private key from the self signed certificate.
openssl x509 -outform pem -in mycert.cer -out mycert.pem
openssl pkcs12 -in mycert.pfx -nocerts -out key.pem -nodes
Please replace mycert.cer
and mycert.pfx
with your actual certificate and private key file names.
In case you don’t have openssl installed and are not able to install it, you would need to use a different method to generate the certificate and key files, such as a third-party tool or a different language’s libraries.
Github repo link of the code: https://github.com/sidscrazy/PythonHttpServer