So I was bored on the bus trip to work this morning. Back in Uni I’d thought about whether it would be possible to write an HTTP server as a shell script for bash. So I did it! Presenting bashttpd.
- Processes a single request at a time.
- While processing that request any new connections will be refused.
- Supports index.html or index.txt.
- Checks that files are inside the server root before serving.
- Returns 404, 405 and 400 response codes with HTML.
How does it work?
Bash coprocesses are really neat. You can spawn one subprocess and Bash gives you easy access to the stdin, stdout file descriptors as well as the PID. The script spawns a netcat listener as a coprocess. There’s a very simple state machine based on function pointers. Each function reads one or more lines from the request file descriptor until we’ve calculated the REQUEST_FILE which we’re going to serve to the client. Then we write the HTTP response status, headers and body to the response file descriptor. Finally we kill the netcat coprocess and go back to the top of the loop!