armanchhetri / http-server

Http server built from scratch on go

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

progress-banner

This is a solution to "Build Your Own HTTP server" Challenge on codecrafters.io.

They have fun challenges to practice programming and software engineering.

As a solution to the HTTP server challenge, I tried to make a small version of the net/http package of the go standard library.

Along the way, I learned the following topics:

  • HTTP protocol in depth
  • Go language features
    • Interfaces
    • goroutines
    • synchronization
    • File handling
  • Web technology
    • The request-response flow
    • HTTP routes and route Multiplexer

It has 4 routes by default.

GET   /

Hello There!

GET   /user-agent

echoes back whatever is in user-agent headers

GET   /echo/message

echoes back the message part

GET   /files/filename

Gets the content of the file

POST   /files/filename

Writes the post data to the filename

USAGE

./your_server.sh --directory <path/to/a/directory>

--directory: Directory path for files/<filename> route

Output

INFO[0000] Registering route /                          
INFO[0000] Registering route /user-agent                
INFO[0000] Registering route /echo/<msg>                
INFO[0000] Registering route /files/<filename>          
INFO[0000] Serving at: 0.0.0.0:4221    

The server registers the routes and listens at 0.0.0.0:4221

One of the most challenging parts for me was to continue reading on the port with a fixed-sized buffer when further data is expected. It is especially relevant for POST methods that may include a body of size Content-Size as specified in the header. A fixed buffer may not be enough to accumulate the whole data. I used go routine to keep reading the data from the socket and append to the buffer until there is no data left or the connection was closed.

Another was a custom multiplexer for routes. Currently, the app accepts non-consecutive path parameters. For example /books/<id>, /countries/<id>/nepal/<state> are accepted but not /vehicles/<car>/<brand>. I have used a word-based Trie for the multiplexing algorithm(character-based would have been more efficient🤔)

About

Http server built from scratch on go


Languages

Language:Go 98.0%Language:Shell 1.5%Language:Makefile 0.5%