|
1 | 1 | # RawHTTP |
2 | | -HTTP 1.1 server from scratch |
| 2 | +A from-scratch HTTP/1.1 server implementation in Go, built directly on TCP sockets. |
3 | 3 |
|
4 | | -## HTTP Message Structure |
| 4 | +## Project Overview |
5 | 5 |
|
6 | | -According to RFC 7230, HTTP messages follow this structure: |
| 6 | +RawHTTP is an HTTP/1.1 server implementation that demonstrates low-level network programming concepts by building a complete HTTP server from first principles. Unlike frameworks that abstract away protocol details, this implementation provides direct insight into: |
| 7 | + |
| 8 | +- Raw TCP socket handling |
| 9 | +- HTTP message parsing and generation |
| 10 | +- State machine-based request processing |
| 11 | +- Buffer management and streaming |
| 12 | + |
| 13 | +explore how web servers work at the protocol level. |
| 14 | + |
| 15 | +## HTTP Protocol Deep Dive |
| 16 | + |
| 17 | +### HTTP Message Structure |
| 18 | + |
| 19 | +According to RFC 7230, HTTP messages follow this precise structure: |
7 | 20 |
|
8 | 21 | ``` |
9 | 22 | start-line CRLF |
10 | 23 | *( field-line CRLF ) |
11 | | -*( field-line CRLF ) |
12 | | -... |
13 | 24 | CRLF |
14 | 25 | [ message-body ] |
15 | 26 | ``` |
16 | 27 |
|
17 | 28 | Where: |
18 | 29 | - **start-line**: Request line (method, URI, version) or status line |
19 | | -- **field-line**: HTTP headers (key-value pairs) (The RFC uses the term) |
20 | | -- **CRLF**: Carriage return + line feed (`\r\n`) |
21 | | -- **message-body**: Optional request/response body |
| 30 | +- **field-line**: HTTP headers (key-value pairs) |
| 31 | +- **CRLF**: Carriage return + line feed (`\r\n`) - critical for protocol compliance |
| 32 | +- **message-body**: Optional request/response body |
| 33 | + |
| 34 | +### Request Message Anatomy |
| 35 | + |
| 36 | +``` |
| 37 | +GET /api/users HTTP/1.1\r\n ← Request Line |
| 38 | +Host: example.com\r\n ← Header Field |
| 39 | +User-Agent: RawHTTP/1.0\r\n ← Header Field |
| 40 | +Accept: application/json\r\n ← Header Field |
| 41 | +\r\n ← Header/Body Separator |
| 42 | +[optional message body] ← Body (for POST, PUT, etc.) |
| 43 | +``` |
| 44 | + |
| 45 | +#### Request Line Components |
| 46 | + |
| 47 | +1. **HTTP Method**: Defines the action to be performed |
| 48 | + - `GET`: Retrieve data |
| 49 | + - `POST`: Submit data |
| 50 | + - `PUT`: Update/create resource |
| 51 | + - `DELETE`: Remove resource |
| 52 | + |
| 53 | +2. **Request Target**: Identifies the resource |
| 54 | + - **origin-form**: `/path/to/resource?query=value` |
| 55 | + - **absolute-form**: `http://example.com/path` |
| 56 | + - **authority-form**: `example.com:80` (CONNECT only) |
| 57 | + - **asterisk-form**: `*` (OPTIONS only) |
| 58 | + |
| 59 | +3. **HTTP Version**: Currently `HTTP/1.1` |
| 60 | + |
| 61 | +### Response Message Anatomy |
| 62 | + |
| 63 | +``` |
| 64 | +HTTP/1.1 200 OK\r\n ← Status Line |
| 65 | +Content-Type: text/html\r\n ← Header Field |
| 66 | +Content-Length: 1234\r\n ← Header Field |
| 67 | +Connection: close\r\n ← Header Field |
| 68 | +\r\n ← Header/Body Separator |
| 69 | +<html>...</html> ← Body |
| 70 | +``` |
| 71 | + |
| 72 | + |
| 73 | +### Header Field Theory |
| 74 | + |
| 75 | +#### Field Name Constraints |
| 76 | +- **tchar**: `!#$%&'*+-.^_`|~` plus ALPHA and DIGIT |
| 77 | +- Case-insensitive (normalized to lowercase in our implementation) |
| 78 | +- No whitespace between field-name and colon |
| 79 | + |
| 80 | +#### Field Value Processing |
| 81 | +- Leading/trailing whitespace is removed |
| 82 | +- Multiple values can be comma-separated |
| 83 | + |
| 84 | +#### Critical Headers |
| 85 | +- **Host**: Required in HTTP/1.1, enables virtual hosting |
| 86 | +- **Content-Length**: **Byte count of message body** |
| 87 | + |
| 88 | +## Running the Server |
| 89 | + |
| 90 | +### Quick Start |
| 91 | +```bash |
| 92 | +# Clone the repository |
| 93 | +git clone https://github.com/arkahood/RawHTTP.git |
| 94 | +cd RawHTTP |
| 95 | + |
| 96 | +# Run the HTTP server |
| 97 | +go run ./cmd/httpserver/main.go |
| 98 | + |
| 99 | +# Server starts on port 8080 |
| 100 | +# Visit http://localhost:8080 in your browser |
| 101 | +``` |
| 102 | + |
| 103 | +### Testing with curl |
| 104 | +```bash |
| 105 | +# Basic GET request |
| 106 | +curl -v http://localhost:8080/ |
| 107 | +``` |
| 108 | + |
| 109 | +### Development Commands |
| 110 | +```bash |
| 111 | +# Run tests |
| 112 | +go test ./... |
| 113 | + |
| 114 | +# Build binary |
| 115 | +go build -o httpserver cmd/httpserver/main.go |
| 116 | + |
| 117 | +# View test coverage |
| 118 | +go test -cover ./... |
| 119 | +``` |
0 commit comments