Why does Python lock the port? And can this be safely used for simple proof of concept live app

254 Views Asked by At

This is interesting. I did a simple script to bind and serve http but I hadn't done this in Python3. I can write a simple server:

import http.server
import socketserver

PORT = 8002

Handler = http.server.SimpleHTTPRequestHandler
#https://docs.python.org/3/library/http.server.html
class MyHandler(http.server.SimpleHTTPRequestHandler):
    def __init__(self, request, client_addr, server):
        super().__init__(request, client_addr, server)
    def do_GET(self, ):
        self.send_response(200)
        self.send_header("Content-type", "text/html")
        self.wfile.write('Hey!'.encode())

httpd = socketserver.TCPServer(("0.0.0.0", PORT), MyHandler)

print("serving at port", PORT)
httpd.serve_forever()

but when I run it, then Ctrl+c, then run it again it says:

OSError: [Errno 98] Address already in use

Why is that if I kill the previous process?

Also, is there any reason other than that that this couldn't be used as a simple, testing webapp for a test server at IP:port/somesamplewebapp - They say "http.server is not recommended for production. It only implements basic security checks." but if it does not need https or extra security... what are the risks?

1

There are 1 best solutions below

0
Keith On

The operating system prevents, by default, the reuse of an address by a different PID. You can defeat that with the socket option SO_REUSEADDR. However, since you are using the TCPServer class and it has it's own, different, way of specifying that. You can use this code.


import http.server
import socketserver

PORT = 8002

Handler = http.server.SimpleHTTPRequestHandler

#https://docs.python.org/3/library/http.server.html

class MyHandler(http.server.SimpleHTTPRequestHandler):
    def __init__(self, request, client_addr, server):
        super().__init__(request, client_addr, server)

    def do_GET(self):
        self.send_response(200)
        self.send_header("Content-type", "text/html")
        self.wfile.write('Hey!'.encode())


class MyServer(socketserver.TCPServer):
    allow_reuse_address = True  # <-- This is what you need


httpd = MyServer(("0.0.0.0", PORT), MyHandler)

print("serving at port", PORT)

httpd.serve_forever()