Project 10: HTTP Server
Build a minimal HTTP/1.1 server that serves static files and handles basic requests.
Quick Reference
| Attribute | Value |
|---|---|
| Difficulty | Advanced |
| Time Estimate | 2-3 weeks |
| Language | C |
| Prerequisites | Sockets, I/O, parsing |
| Key Topics | TCP, HTTP, concurrency basics |
1. Learning Objectives
By completing this project, you will:
- Build a TCP server that accepts connections.
- Parse HTTP request lines and headers.
- Serve files with correct status codes.
- Implement basic logging and error handling.
2. Theoretical Foundation
2.1 Core Concepts
- TCP sockets: Accept and handle client connections.
- HTTP protocol: Request line, headers, body.
- Status codes: 200, 404, 500 indicate response state.
2.2 Why This Matters
HTTP servers are a classic systems programming project. It teaches networking, parsing, and I/O efficiency in one integrated system.
2.3 Historical Context / Background
HTTP/1.1 remains a dominant protocol for web services. Implementing it shows how a text-based protocol maps to sockets.
2.4 Common Misconceptions
- “HTTP is just text”: It is text over a stream that can be partial.
- “One read gets the whole request”: It often does not.
3. Project Specification
3.1 What You Will Build
A server that:
- Listens on a port
- Handles
GET /pathrequests - Serves static files from a document root
- Returns 404 on missing files
3.2 Functional Requirements
- Parse request line and headers.
- Map URL paths to filesystem paths safely.
- Send correct HTTP response headers.
- Serve file contents with proper length.
3.3 Non-Functional Requirements
- Security: Prevent path traversal (
..). - Reliability: Handle malformed requests gracefully.
- Performance: Stream file output without loading whole file.
3.4 Example Usage / Output
$ ./httpd 8080 ./www
[listen] 0.0.0.0:8080
[request] GET /index.html
[response] 200 512 bytes
3.5 Real World Outcome
You can open a browser at http://localhost:8080/ and see your static HTML served by your C server. Requests and responses are visible in your logs.
4. Solution Architecture
4.1 High-Level Design
accept -> read request -> parse -> open file -> respond
4.2 Key Components
| Component | Responsibility | Key Decisions |
|---|---|---|
| Listener | Accept sockets | socket/bind/listen |
| Parser | Extract method/path | Basic HTTP/1.1 |
| File server | Read and send file | Use sendfile or read/write |
| Logger | Log request/response | Simple stderr logging |
4.3 Data Structures
typedef struct {
char method[8];
char path[256];
char version[16];
} HttpRequest;
4.4 Algorithm Overview
Key Algorithm: Request handling
- Read from socket until
\r\n\r\n. - Parse request line and headers.
- Map path to file; reject
... - Send headers and file content.
Complexity Analysis:
- Time: O(n) per request
- Space: O(1) streaming
5. Implementation Guide
5.1 Development Environment Setup
cc -Wall -Wextra -O2 -g -o httpd httpd.c
5.2 Project Structure
httpd/
├── src/
│ └── httpd.c
├── tests/
│ └── test_httpd.sh
└── README.md
5.3 The Core Question You’re Answering
“How does an HTTP request become a file response over a TCP stream?”
5.4 Concepts You Must Understand First
Stop and research these before coding:
- Sockets
- What is a listening socket vs client socket?
- HTTP framing
- How do you know where headers end?
- Path safety
- How do you prevent
../traversal?
- How do you prevent
5.5 Questions to Guide Your Design
Before implementing, think through these:
- Will you handle keep-alive or close after response?
- How will you set MIME types?
- How will you handle large files?
5.6 Thinking Exercise
Partial Reads
If the request line arrives in two TCP packets, how does your parser handle it?
5.7 The Interview Questions They’ll Ask
Prepare to answer these:
- “How do you implement a TCP server?”
- “How do you parse HTTP requests safely?”
- “How do you prevent directory traversal?”
5.8 Hints in Layers
Hint 1: Serve only one file Start with a fixed response.
Hint 2: Parse request line
Handle GET /path HTTP/1.1.
Hint 3: Stream file Use a buffer loop to send file content.
5.9 Books That Will Help
| Topic | Book | Chapter |
|---|---|---|
| Sockets | “UNIX Network Programming” | Ch. 4-6 |
| HTTP basics | “HTTP: The Definitive Guide” | Ch. 1-3 |
5.10 Implementation Phases
Phase 1: Foundation (4-6 days)
Goals:
- Basic TCP server
Tasks:
- Accept a connection.
- Read and print request.
Checkpoint: Server receives requests.
Phase 2: Core Functionality (5-7 days)
Goals:
- Parse and serve files
Tasks:
- Parse request line.
- Map path and send file.
Checkpoint: Browser loads static file.
Phase 3: Polish & Edge Cases (4-6 days)
Goals:
- Errors and security
Tasks:
- Return 404/400.
- Prevent traversal and handle large files.
Checkpoint: Invalid requests return errors.
5.11 Key Implementation Decisions
| Decision | Options | Recommendation | Rationale |
|---|---|---|---|
| Concurrency | Single-threaded vs threaded | Single-threaded | Simpler for learning |
| File send | read/write vs sendfile |
read/write |
Portable baseline |
6. Testing Strategy
6.1 Test Categories
| Category | Purpose | Examples |
|---|---|---|
| Unit Tests | Parser logic | Request line parsing |
| Integration Tests | HTTP responses | curl requests |
| Security Tests | Path traversal | /../etc/passwd |
6.2 Critical Test Cases
- GET existing file: 200 response.
- GET missing file: 404 response.
- Bad request: 400 response.
6.3 Test Data
www/index.html
www/style.css
7. Common Pitfalls & Debugging
7.1 Frequent Mistakes
| Pitfall | Symptom | Solution |
|---|---|---|
| Partial reads | Truncated headers | Read until \r\n\r\n |
| Path traversal | Security hole | Normalize path |
| Missing Content-Length | Browser hangs | Include correct header |
7.2 Debugging Strategies
- Use
curl -vto inspect responses. - Log request parsing results.
7.3 Performance Traps
Reading one byte at a time is slow. Use a buffer of 4 KB or more.
8. Extensions & Challenges
8.1 Beginner Extensions
- Add directory index listing.
- Add MIME type detection.
8.2 Intermediate Extensions
- Support keep-alive connections.
- Add simple thread pool.
8.3 Advanced Extensions
- Implement HTTP/1.1 chunked responses.
- Add TLS termination (OpenSSL).
9. Real-World Connections
9.1 Industry Applications
- Web servers: nginx, Apache use the same basics.
- Embedded: Minimal HTTP servers for devices.
9.2 Related Open Source Projects
- lighttpd: Small-footprint server.
9.3 Interview Relevance
Networking and protocol parsing are common in systems interviews.
10. Resources
10.1 Essential Reading
- “UNIX Network Programming” - Ch. 4-6
- “HTTP: The Definitive Guide” - Ch. 1-3
10.2 Video Resources
- Socket programming lectures
10.3 Tools & Documentation
man 2 socket,man 2 bind,man 2 listen
10.4 Related Projects in This Series
- Unix Shell: Networking commands and exec behavior.
- Database Engine: Use HTTP for simple APIs.
11. Self-Assessment Checklist
11.1 Understanding
- I can explain socket lifecycle.
- I can parse HTTP request lines.
- I can handle partial reads.
11.2 Implementation
- Server responds to GET requests.
- Correct status codes are returned.
- Path traversal is blocked.
11.3 Growth
- I can add concurrency.
- I can explain this project in an interview.
12. Submission / Completion Criteria
Minimum Viable Completion:
- Serves one static file.
Full Completion:
- Serves arbitrary files under document root.
Excellence (Going Above & Beyond):
- Keep-alive and chunked responses.
This guide was generated from C_PROGRAMMING_COMPLETE_MASTERY.md. For the complete learning path, see the parent directory.