Building a Simple HTTP Server
The built-in http.server
Section titled “The built-in http.server”Python includes a simple HTTP server in the standard library.
Great for:
- local demos
- serving static files
Not ideal for production.
Serve a folder
Section titled “Serve a folder”If you run:
python -m http.server 8000Then open:
http://localhost:8000
Custom handler
Section titled “Custom handler”from http.server import BaseHTTPRequestHandler, HTTPServer
class Handler(BaseHTTPRequestHandler):
def do_GET(self):
self.send_response(200)
self.send_header("Content-Type", "text/plain")
self.end_headers()
self.wfile.write(b"Hello from Python HTTP server")
if __name__ == "__main__":
server = HTTPServer(("127.0.0.1", 8000), Handler)
print("Serving on http://127.0.0.1:8000")
server.serve_forever()What’s happening?
Section titled “What’s happening?”do_GEThandles HTTP GET requestssend_responsesets status code- headers must be sent before the body
flowchart TD
A["GET /hello.txt"] --> B{"does it exist under the CWD?"}
B -->|yes| C["200 + the file, Content-Type guessed from the suffix"]
B -->|no| D["404 File not found"]
E["GET /"] --> F["200 + a GENERATED directory listing"]
G["POST anything"] --> H["501 Unsupported method"]
C --> I["the document root is os.getcwd()"]
F --> I
I --> J["so it must never be exposed beyond localhost"]
Check yourself
Section titled “Check yourself”-
`python -m http.server` serves which directory?
Whatever folder you started it in. Run it in the wrong place and it will serve your source, your `.env` and anything else that is there.
pch.quizShowAnswer
B — The current working directory — Whatever folder you started it in. Run it in the wrong place and it will serve your source, your `.env` and anything else that is there.
-
What does a POST to the built-in handler return?
Verified. `SimpleHTTPRequestHandler` implements only GET and HEAD, so it is a file viewer rather than a framework — to handle POST you subclass it and write `do_POST`.
pch.quizShowAnswer
D — 501 Unsupported method — Verified. `SimpleHTTPRequestHandler` implements only GET and HEAD, so it is a file viewer rather than a framework — to handle POST you subclass it and write `do_POST`.
-
You request a path that is a directory. What comes back?
Measured: 200 with a 299-byte generated listing. If an `index.html` exists it is served instead, which is what makes this useful for previewing a static site.
pch.quizShowAnswer
C — 200 with a generated listing (or index.html if present) — Measured: 200 with a 299-byte generated listing. If an `index.html` exists it is served instead, which is what makes this useful for previewing a static site.
-
Why should this server never be exposed beyond localhost?
It also binds all interfaces by default, so on a shared network the whole directory is readable. Bind it to 127.0.0.1 and treat it as a local preview tool.
pch.quizShowAnswer
B — No authentication, no TLS, and its root is whatever directory you happened to be in — It also binds all interfaces by default, so on a shared network the whole directory is readable. Bind it to 127.0.0.1 and treat it as a local preview tool.
🧪 Try It Yourself
Section titled “🧪 Try It Yourself”Exercise 1 – HTTP GET with urllib
Section titled “Exercise 1 – HTTP GET with urllib”Exercise 2 – Socket Connection
Section titled “Exercise 2 – Socket Connection”Exercise 3 – Resolve a Hostname
Section titled “Exercise 3 – Resolve a Hostname”pch.coffeeTagline
pch.coffeeCtapch.feedbackHeading
pch.feedbackSubheading