Skip to content

Commit 5c80eaa

Browse files
authored
Added comprehensive README.MD (#67)
* Added comprehensive README.MD * Added formatting recommendations, clearer info
1 parent d4e7481 commit 5c80eaa

1 file changed

Lines changed: 349 additions & 26 deletions

File tree

README.md

Lines changed: 349 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1,49 +1,372 @@
1-
# 🚀 Create Your First Java Program
1+
# ⚡ HTTP Web Server ⚡
2+
### **Class JUV25G** | Lightweight • Configurable • Secure
23

3-
Java has evolved to become more beginner-friendly. This guide walks you through creating a simple program that prints “Hello World,” using both the classic syntax and the new streamlined approach introduced in Java 21.
4+
<div align="center">
5+
6+
![Java](https://img.shields.io/badge/Java-21+-orange?style=for-the-badge&logo=openjdk)
7+
![HTTP](https://img.shields.io/badge/HTTP-1.1-blue?style=for-the-badge)
8+
![Status](https://img.shields.io/badge/Status-Active-success?style=for-the-badge)
9+
10+
*A modern, high-performance HTTP web server built from scratch in Java*
11+
12+
[Features](#features)[Quick Start](#quick-start)[Configuration](#configuration)
413

514
---
615

7-
## ✨ Classic Java Approach
16+
</div>
817

9-
Traditionally, Java requires a class with a `main` method as the entry point:
18+
## ✨ Features
1019

11-
```java
12-
public class Main {
13-
public static void main(String[] args) {
14-
System.out.println("Hello World");
15-
}
16-
}
20+
- 🚀 **High Performance** - Virtual threads for handling thousands of concurrent connections
21+
- 📁 **Static File Serving** - HTML, CSS, JavaScript, images, PDFs, fonts, and more
22+
- 🎨 **Smart MIME Detection** - Automatic Content-Type headers for 20+ file types
23+
- ⚙️ **Flexible Configuration** - YAML or JSON config files with sensible defaults
24+
- 🔒 **Security First** - Path traversal protection and input validation
25+
- 🐳 **Docker Ready** - Multi-stage Dockerfile for easy deployment
26+
-**HTTP/1.1 Compliant** - Proper status codes, headers, and responses
27+
- 🎯 **Custom Error Pages** - Branded 404 pages and error handling
28+
29+
## 📋 Requirements
30+
31+
| Tool | Version | Purpose |
32+
|------|---------|---------|
33+
|**Java** | 21+ | Runtime environment |
34+
| 📦 **Maven** | 3.6+ | Build tool |
35+
| 🐳 **Docker** | Latest | Optional - for containerization |
36+
37+
## Quick Start
38+
39+
```
40+
┌─────────────────────────────────────────────┐
41+
│ Ready to launch your web server? │
42+
│ Follow these simple steps! │
43+
└─────────────────────────────────────────────┘
1744
```
1845

19-
This works across all Java versions and forms the foundation of most Java programs.
46+
### 1. Clone the repository
47+
```bash
48+
git clone git clone https://github.com/ithsjava25/project-webserver-juv25g.git
49+
cd project-webserver
50+
```
2051

21-
---
52+
### 2. Build the project
53+
```bash
54+
mvn clean compile
55+
```
56+
57+
### 3. Run the server
58+
59+
**Option A: Run directly with Maven (recommended for development)**
60+
```bash
61+
mvn exec:java@run
62+
```
63+
64+
**Option B: Run compiled classes directly**
65+
```bash
66+
mvn clean compile
67+
java -cp target/classes org.example.App
68+
```
69+
70+
**Option C: Using Docker**
71+
```bash
72+
docker build -t webserver .
73+
docker run -p 8080:8080 -v $(pwd)/www:/www webserver
74+
```
75+
76+
The server will start on the default port **8080** and serve files from the `www/` directory.
77+
78+
### 4. Access in browser
79+
Open your browser and navigate to:
80+
```
81+
http://localhost:8080
82+
```
2283

23-
## 🆕 Java 25: Unnamed Class with Instance Main Method
84+
## Configuration
2485

25-
In newer versions like **Java 25**, you can use **Unnamed Classes** and an **Instance Main Method**, which allows for a much cleaner syntax:
86+
The server can be configured using a YAML or JSON configuration file located at:
87+
```
88+
src/main/resources/application.yml
89+
```
90+
91+
### Configuration File Format (YAML)
92+
93+
```yaml
94+
server:
95+
port: 8080
96+
rootDir: "./www"
97+
98+
logging:
99+
level: "INFO"
100+
```
101+
102+
### Configuration File Format (JSON)
26103
27-
```java
28-
void main() {
29-
System.out.println("Hello World");
104+
```json
105+
{
106+
"server": {
107+
"port": 8080,
108+
"rootDir": "./www"
109+
},
110+
"logging": {
111+
"level": "INFO"
112+
}
30113
}
31114
```
32115

33-
### 💡 Why is this cool?
116+
### Configuration Options
117+
118+
| Property | Type | Default | Description |
119+
|----------|------|---------|-------------|
120+
| `server.port` | Integer | `8080` | Port number the server listens on (1-65535) |
121+
| `server.rootDir` | String | `"./www"` | Root directory for serving static files |
122+
| `logging.level` | String | `"INFO"` | Logging level (INFO, DEBUG, WARN, ERROR) |
123+
124+
### Default Values
125+
126+
If no configuration file is provided or values are missing, the following defaults are used:
127+
128+
- **Port:** 8080
129+
- **Root Directory:** ./www
130+
- **Logging Level:** INFO
131+
132+
## Directory Structure
133+
134+
```
135+
project-webserver/
136+
├── src/
137+
│ ├── main/
138+
│ │ ├── java/
139+
│ │ │ └── org/example/
140+
│ │ │ ├── App.java # Main entry point
141+
│ │ │ ├── TcpServer.java # TCP server implementation
142+
│ │ │ ├── ConnectionHandler.java # HTTP request handler
143+
│ │ │ ├── StaticFileHandler.java # Static file server
144+
│ │ │ ├── config/ # Configuration classes
145+
│ │ │ ├── http/ # HTTP response builder & MIME detection
146+
│ │ │ ├── httpparser/ # HTTP request parser
147+
│ │ │ └── filter/ # Filter chain (future feature)
148+
│ │ └── resources/
149+
│ │ └── application.yml # Configuration file
150+
│ └── test/ # Unit tests
151+
├── www/ # Web root (static files)
152+
│ ├── index.html
153+
│ ├── pageNotFound.html # Custom 404 page
154+
│ └── ... # Other static files
155+
├── pom.xml
156+
└── README.md
157+
```
158+
159+
## Serving Static Files
160+
161+
Place your static files in the `www/` directory (or the directory specified in `server.rootDir`).
162+
163+
### Supported File Types
164+
165+
The server automatically detects and serves the correct `Content-Type` for:
166+
167+
**Text & Markup:**
168+
- HTML (`.html`, `.htm`)
169+
- CSS (`.css`)
170+
- JavaScript (`.js`)
171+
- JSON (`.json`)
172+
- XML (`.xml`)
173+
- Plain text (`.txt`)
174+
175+
**Images:**
176+
- PNG (`.png`)
177+
- JPEG (`.jpg`, `.jpeg`)
178+
- GIF (`.gif`)
179+
- SVG (`.svg`)
180+
- WebP (`.webp`)
181+
- ICO (`.ico`)
182+
183+
**Documents:**
184+
- PDF (`.pdf`)
185+
186+
**Fonts:**
187+
- WOFF (`.woff`)
188+
- WOFF2 (`.woff2`)
189+
- TrueType (`.ttf`)
190+
- OpenType (`.otf`)
191+
192+
**Media:**
193+
- MP4 video (`.mp4`)
194+
- WebM video (`.webm`)
195+
- MP3 audio (`.mp3`)
196+
- WAV audio (`.wav`)
197+
198+
Unknown file types are served as `application/octet-stream`.
199+
200+
## URL Handling
201+
202+
The server applies the following URL transformations:
203+
204+
| Request URL | Resolved File |
205+
|-------------|---------------|
206+
| `/` | `index.html` |
207+
| `/about` | `about.html` |
208+
| `/contact` | `contact.html` |
209+
| `/styles.css` | `styles.css` |
210+
| `/page.html` | `page.html` |
211+
212+
**Note:** URLs ending with `/` are resolved to `index.html`, and URLs without an extension get `.html` appended automatically.
213+
214+
## Error Pages
215+
216+
### 404 Not Found
217+
218+
If a requested file doesn't exist, the server returns:
219+
1. `pageNotFound.html` (if it exists in the web root)
220+
2. Otherwise: Plain text "404 Not Found"
221+
222+
To customize your 404 page, create `www/pageNotFound.html`.
223+
224+
### 403 Forbidden
225+
226+
Returned when a path traversal attack is detected (e.g., `GET /../../etc/passwd`).
227+
228+
## Security Features
229+
230+
### Path Traversal Protection
231+
232+
The server validates all file paths to prevent directory traversal attacks:
233+
234+
```
235+
✅ Allowed: /index.html
236+
✅ Allowed: /docs/guide.pdf
237+
❌ Blocked: /../../../etc/passwd
238+
❌ Blocked: /www/../../../secret.txt
239+
```
240+
241+
All blocked requests return `403 Forbidden`.
34242

35-
- ✅ No need for a `public class` declaration
36-
- ✅ No `static` keyword required
37-
- ✅ Great for quick scripts and learning
243+
## Running Tests
38244

39-
To compile and run this, use:
245+
```bash
246+
mvn test
247+
```
248+
249+
Test coverage includes:
250+
- HTTP request parsing
251+
- Response building
252+
- MIME type detection
253+
- Configuration loading
254+
- Static file serving
255+
- Path traversal security
256+
257+
## Building for Production
258+
259+
### Using Docker (recommended)
40260

41261
```bash
42-
java --source 25 HelloWorld.java
262+
docker build -t webserver .
263+
docker run -d -p 8080:8080 -v $(pwd)/www:/www --name my-webserver webserver
43264
```
44265

45-
---
266+
### Running on a server
267+
268+
```bash
269+
# Compile the project
270+
mvn clean compile
271+
272+
# Run with nohup for background execution
273+
nohup java -cp target/classes org.example.App > server.log 2>&1 &
274+
275+
# Or use systemd (create /etc/systemd/system/webserver.service)
276+
```
277+
278+
## Examples
279+
280+
### Example 1: Serving a Simple Website
281+
282+
**Directory structure:**
283+
```
284+
www/
285+
├── index.html
286+
├── styles.css
287+
├── app.js
288+
└── images/
289+
└── logo.png
290+
```
291+
292+
**Access:**
293+
- Homepage: `http://localhost:8080/`
294+
- Stylesheet: `http://localhost:8080/styles.css`
295+
- Logo: `http://localhost:8080/images/logo.png`
296+
297+
### Example 2: Custom Port
298+
299+
**application.yml:**
300+
```yaml
301+
server:
302+
port: 3000
303+
rootDir: "./public"
304+
```
305+
306+
Access at: `http://localhost:3000/`
307+
308+
### Example 3: Different Web Root
309+
310+
**application.yml:**
311+
```yaml
312+
server:
313+
rootDir: "./dist"
314+
```
315+
316+
Server will serve files from `dist/` instead of `www/`.
317+
318+
## Architecture
319+
320+
### Request Flow
321+
322+
1. **TcpServer** accepts incoming TCP connections
323+
2. **ConnectionHandler** creates a virtual thread for each request
324+
3. **HttpParser** parses the HTTP request line and headers
325+
4. **StaticFileHandler** resolves the file path and reads the file
326+
5. **HttpResponseBuilder** constructs the HTTP response with correct headers
327+
6. Response is written to the client socket
328+
329+
### Filter Chain (Future Feature)
330+
331+
The project includes a filter chain interface for future extensibility:
332+
- Request/response filtering
333+
- Authentication
334+
- Logging
335+
- Compression
336+
337+
## Troubleshooting
338+
339+
### Port already in use
340+
```
341+
Error: Address already in use
342+
```
343+
**Solution:** Change the port in `application.yml` or kill the process using port 8080:
344+
```bash
345+
# Linux/Mac
346+
lsof -ti:8080 | xargs kill -9
347+
348+
# Windows
349+
netstat -ano | findstr :8080
350+
taskkill /PID <PID> /F
351+
```
352+
353+
### File not found but file exists
354+
**Solution:** Check that the file is in the correct directory (`www/` by default) and that the filename matches exactly (case-sensitive on Linux/Mac).
355+
356+
### Binary files (images/PDFs) are corrupted
357+
**Solution:** This should not happen with the current implementation. The server uses `byte[]` internally to preserve binary data. If you see this issue, please report it as a bug.
358+
359+
## Contributing
360+
361+
1. Fork the repository
362+
2. Create a feature branch (`git checkout -b feature/new-feature`)
363+
3. Commit your changes (`git commit -m 'Add new feature'`)
364+
4. Push to the branch (`git push origin feature/new-feature`)
365+
5. Open a Pull Request
366+
367+
<div align="center">
46368

47-
## 📚 Learn More
369+
### 👨‍💻 Built by Class JUV25G
48370

49-
This feature is part of Java’s ongoing effort to streamline syntax. You can explore deeper in [Baeldung’s guide to Unnamed Classes and Instance Main Methods](https://www.baeldung.com/java-21-unnamed-class-instance-main).
371+
**Made with ❤️ and ☕ in Sweden**
372+
</div>

0 commit comments

Comments
 (0)