Python HTTP server
References
Example
$ cat http-server.py
#!/usr/bin/env python3
from os import getenv
from json import dumps as json_dumps, loads as json_loads
from http.server import HTTPServer, BaseHTTPRequestHandler
from http import HTTPStatus
HTTP_PORT = 4444
class MyHTTPServer(HTTPServer):
def server_bind(self):
print("MyHTTPServer.server_bind()",self.server_address)
return HTTPServer.server_bind(self)
class MyHTTPRequestHandler(BaseHTTPRequestHandler):
def __init__(self,request,client_address,server):
print("MyHTTPRequestHandler.__init__()",request,client_address,server)
BaseHTTPRequestHandler.__init__(self,request,client_address,server)
def __send_reply(self,http_code,js):
js['headers'] = str(self.headers).replace("\n","|")
js['path'] = self.path
buf = json_dumps(js,sort_keys=True,indent=2) + "\n"
self.send_response(http_code)
self.send_header("Content-type","application/json")
self.end_headers()
self.wfile.write(buf.encode().decode('unicode-escape').encode('UTF-8'))
def do_GET(self):
self.__send_reply(HTTPStatus.METHOD_NOT_ALLOWED,dict(error="method not allowed"))
def do_POST(self):
length = int(self.headers.get('Content-Length', 0))
body_buf = self.rfile.read(length)
body_js = json_loads(body_buf)
js = dict(res="ok",len=length,body=body_js)
self.__send_reply(HTTPStatus.OK,js)
def http_server(server_class=HTTPServer, handler_class=BaseHTTPRequestHandler):
server_address = ('', HTTP_PORT)
httpd = server_class(server_address, handler_class)
httpd.serve_forever() # lo para el handler con 'shutdown()'
if __name__ == "__main__":
if getenv("SIMPLE") == "1":
http_server()
else:
http_server(MyHTTPServer,MyHTTPRequestHandler)
Execution
$ python3 http-server.py
Example: GET
$ curl -v http://127.0.0.1:4444/get-file.txt
* Trying 127.0.0.1:4444...
* Connected to 127.0.0.1 (127.0.0.1) port 4444 (#0)
> GET /get-file.txt HTTP/1.1
> Host: 127.0.0.1:4444
> User-Agent: curl/7.81.0
> Accept: */*
>
* Mark bundle as not supporting multiuse
* HTTP 1.0, assume close after body
< HTTP/1.0 405 Method Not Allowed
< Server: BaseHTTP/0.6 Python/3.10.12
< Date: Mon, 14 Oct 2024 15:05:25 GMT
< Content-type: application/json
<
{
"error": "method not allowed",
"headers": "Host: 127.0.0.1:4444|User-Agent: curl/7.81.0|Accept: */*||",
"path": "/get-file.txt"
}
* Closing connection 0
Example: POST
$ curl -v -d '{"req":"request"}' -H Content-Type:application/json http://127.0.0.1:4444/post-file.txt
* Trying 127.0.0.1:4444...
* Connected to 127.0.0.1 (127.0.0.1) port 4444 (#0)
> POST /post-file.txt HTTP/1.1
> Host: 127.0.0.1:4444
> User-Agent: curl/7.81.0
> Accept: */*
> Content-Type:application/json
> Content-Length: 17
>
* Mark bundle as not supporting multiuse
* HTTP 1.0, assume close after body
< HTTP/1.0 200 OK
< Server: BaseHTTP/0.6 Python/3.10.12
< Date: Mon, 14 Oct 2024 15:05:47 GMT
< Content-type: application/json
<
{
"body": {
"req": "request"
},
"headers": "Host: 127.0.0.1:4444|User-Agent: curl/7.81.0|Accept: */*|Content-Type: application/json|Content-Length: 17||",
"len": 17,
"path": "/post-file.txt",
"res": "ok"
}
* Closing connection 0
Alternatives
From https://docs.python.org/3/library/http.server.html:
import http.server
import socketserver
PORT = 8000
Handler = http.server.SimpleHTTPRequestHandler
with socketserver.TCPServer(("", PORT), Handler) as httpd:
print("serving at port", PORT)
httpd.serve_forever()
python -m http.server
python -m http.server 9000
python -m http.server --bind 127.0.0.1
python -m http.server --directory /tmp/
python -m http.server --protocol HTTP/1.1