Help us measure site usage?

With your permission, we use self-hosted analytics to understand page usage. It is optional and does not affect the Service. Learn more.

BashintermediatebackendAI generated

Minimal Static File HTTP Server

Build a tiny web server written entirely in Bash, which serves the files in a folder to a web browser. It listens for connections with socat (or netcat), reads the raw HTTP request text line by line, finds the file that was asked for, and writes back a correct HTTP response with headers and the file content. It returns 404 for missing files and blocks attempts to escape the folder with ../. It's not meant for real use, but it shows exactly what happens under the hood of every website. Run it only on your own machine. You'll learn the HTTP protocol, how sockets connect programs, handling input safely in shell scripts, MIME types, and logging.

Estimate
~9.5h
Steps
6
Completed by
0
Proposed by
codeseed.app

netcat · socat · mimetype detection

Project roadmap

  1. 01

    Read a raw HTTP request

    ~1.5h

    Write handler.sh, which reads the request from standard input: the request line (method, path, version), then header lines until an empty line. Remove the carriage returns at the end of each line (HTTP lines end with \r\n). Start it for each connection with socat TCP-LISTEN:8080,reuseaddr,fork EXEC:./handler.sh, listening on 127.0.0.1 only. Log the request line to stderr. Done when: opening http://localhost:8080/ in a browser logs the request line.

  2. 02

    Find the file and its type

    ~1.5h

    Take the path, decode %20 and other percent-encoded characters, and remove the query string. Map / to index.html. Build the full path under the document root, and choose the Content-Type from the extension with a case statement (html, css, js, png, jpg, svg and txt, with application/octet-stream as the default), or with file --mime-type. Done when: the handler logs the right file and type for several requests.

  3. 03

    Send a valid response

    ~1.5h

    Write the status line HTTP/1.1 200 OK, then the Content-Type, Content-Length (from stat or wc -c), Connection: close and an empty line, all with \r\n line endings, then send the file with cat so binary files like images arrive intact. Support HEAD requests (headers only). Done when: a browser shows an HTML page with its CSS and images.

  4. 04

    Handle errors safely

    ~2h

    Return 404 with a small HTML page for missing files, 405 for methods other than GET and HEAD, and 400 for malformed request lines. Resolve the real path with realpath and return 403 when it's outside the document root, which blocks /../../etc/passwd, including encoded forms such as %2e%2e. Never pass request text to eval or unquoted commands. Done when: curl --path-as-is http://localhost:8080/../../etc/passwd gets 403.

  5. 05

    Add options and logging

    ~1.5h

    Write server.sh, which takes the port and document root as options, checks that the folder exists, and starts socat. Log each request in a common log format (time, client address from the SOCAT_PEERADDR variable, request line, status and size) to a file. Stop cleanly on Ctrl+C. Done when: every request appears in the log with the right status.

  6. 06

    Test it

    ~1.5h

    Write tests with bats-core that start the server on a free port with a test folder and use curl to check: correct content and headers for HTML and an image, 404, 403 for traversal attempts, 405, HEAD requests and URL-encoded names. Run shellcheck on the scripts. Done when: the tests pass, and shellcheck reports no warnings.

Ready to build this?

Get a GitHub repo and start building. Your AI reviewer checks each step as you go.

~9.5h · 6 steps

Tech stack

netcatsocatmimetype detection