Building an HTTP/1.1 server from scratch using raw TCP sockets. This is course code from Boot.dev, developed in WSL Alpine.
Instead of using Go's net/http package like a normal person, this project implements HTTP from the ground up. We're talking raw TCP connections, manually parsing request lines, headers, bodies - the whole thing. It's a great way to actually understand what's happening under the hood when you make an HTTP request.
cmd/
httpserver/ - The main HTTP server
tcplistener/ - Simple TCP listener for debugging requests
udplistener/ - UDP listener (because why not)
udpsender/ - UDP sender for testing
internal/
headers/ - HTTP header parsing and management
request/ - HTTP request parsing (state machine style)
response/ - HTTP response writing
server/ - TCP server with connection handling
Runs on port 42069 (obviously). Handles a few routes:
/- Returns a success page/yourproblem- Returns 400 Bad Request (your fault)/myproblem- Returns 500 Internal Server Error (my fault)/video- Servesassets/vim.mp4if it exists/httpbin/*- Proxies to httpbin.org with chunked transfer encoding and trailers
The proxy endpoint is the interesting one - it streams responses using chunked transfer encoding and adds SHA256 and content length trailers at the end.
The request parser is a state machine that processes incoming bytes:
- Parse the request line (method, target, HTTP version)
- Parse headers until we hit the empty line
- Read the body based on Content-Length
It handles partial reads and buffer management properly, so it works with real TCP connections where data arrives in chunks.
The response writer can:
- Write status lines (200, 400, 500)
- Write headers
- Write regular bodies
- Write chunked bodies (for streaming)
- Write trailers (metadata after the body)
Case-insensitive header storage with support for:
- Getting/setting/replacing/deleting headers
- Parsing raw header bytes
- Iterating over all headers
- Comma-separated values for duplicate headers
# Build and run the HTTP server
go run ./cmd/httpserver
# Test it
curl http://localhost:42069/
curl http://localhost:42069/yourproblem
curl http://localhost:42069/videoOr use netcat for raw requests:
echo -e "GET /httpbin/html HTTP/1.1\r\nHost: localhost\r\nConnection: close\r\n\r\n" | nc localhost 42069tcplistener - Just accepts TCP connections and prints the parsed HTTP request. Useful for debugging.
udplistener/udpsender - UDP tools for messing around with datagrams. Not really HTTP-related but they were part of the learning process.
- Go 1.22+
- testify (for tests)
This was built as a learning exercise. The error messages in the HTML responses are intentionally cheeky. The port number is also intentionally immature. It's fine.