Skip to content
/ http Public

Custom HTTP/1.1 server implementation built directly on top of TCP sockets, following RFC 9110 and RFC 9112

License

Notifications You must be signed in to change notification settings

sjdonado/http

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

34 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Custom HTTP/1.1 server implementation built directly on top of TCP sockets, following RFC 9110 and RFC 9112. From scratch without using Go's net/http package.

Example Endpoints

Run the server:

go run cmd/httpserver/main.go

GET / - HTML Response

Serves assets/httpbin.html with Content-Length encoding.

curl http://localhost:42069/

POST /json - JSON Response

Returns a JSON response with Content-Length.

curl -X POST http://localhost:42069/json

GET /error - Error Handling

Demonstrates 500 Internal Server Error response.

curl http://localhost:42069/error

GET /streaming - Chunked Video Streaming

Streams assets/Big_Buck_Bunny_1080_10s_5MB.mp4 using chunked transfer encoding with trailers.

curl http://localhost:42069/streaming --output video.mp4

View trailers:

curl --raw http://localhost:42069/streaming 2>&1 | tail -5

Architecture

  • internal/server - TCP listener and connection handling
  • internal/request - HTTP request parser
  • internal/response - HTTP response writer with state machine
  • internal/headers - HTTP header management
  • cmd/httpserver - Main server application with example endpoints
  • cmd/tcplistener - Early debugging tool for raw TCP inspection

Message Structure (RFC 9112 Section 2.1)

All HTTP messages follow this structure:

HTTP-message   = start-line CRLF
                 *( field-line CRLF )
                 CRLF
                 [ message-body ]

Request start-line (RFC 9112 Section 3):

GET /path HTTP/1.1

Response start-line (RFC 9112 Section 4):

HTTP/1.1 200 OK

Content-Length Messages (RFC 9112 Section 6)

Standard HTTP response with known body length:

HTTP/1.1 200 OK
Content-Type: text/html
Content-Length: 13
Connection: close

Hello, World!

Chunked Transfer Encoding (RFC 9112 Section 7.1)

For streaming data when the total size is unknown upfront:

HTTP/1.1 200 OK
Content-Type: video/mp4
Transfer-Encoding: chunked
Trailer: X-Content-Length

2000\r\n
<8192 bytes of data>\r\n
2000\r\n
<8192 bytes of data>\r\n
... repeat ...
0\r\n
X-Content-Length: 5238714\r\n
\r\n

Key components:

  • Each chunk starts with size in hexadecimal + CRLF
  • Followed by chunk data + CRLF
  • Final chunk is 0\r\n
  • Optional trailers can follow (RFC 9110 Section 6.5)
  • Ends with final CRLF

Implementation Details

Response State Machine

The response.Writer implements a state machine to ensure proper HTTP message construction:

  1. stateInit → Write status line
  2. stateStatus → Write headers
  3. stateHeaders → Write body (chunked or content-length)
  4. stateBody → Optionally write trailers (chunked only)
  5. stateTrailers / stateDone → Complete

This enforces the correct order defined in RFC 9112 Section 2.1.

Request Parsing

The request parser handles:

  • Request line parsing (RFC 9112 Section 3): Method, request-target, HTTP version
  • Header field parsing (RFC 9110 Section 5): Field name, field value
  • Message body handling (RFC 9110 Section 6): Based on Content-Length or Transfer-Encoding

References

  • RFC 9110 - HTTP Semantics
    • Section 6.5: Trailers
  • RFC 9112 - HTTP/1.1
    • Section 2.1: Message Format
    • Section 3: Request Line
    • Section 4: Status Line
    • Section 6: Message Body (Content-Length)
    • Section 7.1: Chunked Transfer Coding

About

Custom HTTP/1.1 server implementation built directly on top of TCP sockets, following RFC 9110 and RFC 9112

Resources

License

Stars

Watchers

Forks