A Java implementation of the Gemini-Lite protocol — a simplified, lightweight alternative to HTTP designed for minimal overhead and simplicity. This project includes a fully functional Client, Server, and Proxy, along with a benchmarking tool for performance analysis.
Built as part of the BCS2110 course at Maastricht University.
Gemini-Lite is a streamlined network protocol that operates over TCP. Unlike HTTP, it uses a single request/response per connection with a minimal header format:
- Request:
<absolute-URI>\r\n(max 1024 bytes) - Response:
<STATUS> <META>\r\n[<BODY>]- Status codes are 2 digits (10–59)
- Body is only present for
2x(Success) responses
Status Code Classes:
| Code | Meaning | Description |
|---|---|---|
| 1x | Input | Server requests additional input |
| 2x | Success | Response body follows |
| 3x | Redirect | META contains the redirect URL |
| 4x | Temporary Failure | Retry later |
| 5x | Permanent Failure | Do not retry |
- Fetches resources from Gemini-Lite servers
- Follows redirects (up to 5 hops)
- Handles input requests (status
1x) by prompting for user input - Implements exponential backoff for slowdown responses (status
44), capped at 60s - Streams lar3ge files efficiently without loading into memory
- Serves files from a configurable document root
- Automatic MIME type detection (
.gmi→text/gemini,.txt→text/plain) - Generates directory listings in Gemtext format
- Path traversal protection — prevents access outside the document root
- Proper error responses for missing files and server errors
- Transparent intermediary between clients and origin servers
- Follows redirects on behalf of the client
- Relay complete responses including bodies
- Enforces redirect limits to prevent infinite loops
- Measures p50 and p99 latencies across multiple file sizes (64B to 100MB)
- Reports throughput for large file transfers
- Runs 20 iterations per test for statistical reliability
- Language: Java 23+
- Build Tool: Maven
- Testing: JUnit 5
- Java JDK 23 or later
- Apache Maven 3.9+
mvn clean packageThis produces target/bcs2110-2025.jar.
java -cp target/bcs2110-2025.jar gemini_lite.Server [docRoot] [port]Example:
java -cp target/bcs2110-2025.jar gemini_lite.Server docroot 1958docRoot— directory to serve files from (default: current directory)port— port to listen on (default:1958)
java -cp target/bcs2110-2025.jar gemini_lite.Client <URL> [input]Example:
java -cp target/bcs2110-2025.jar gemini_lite.Client gemini-lite://localhost/index.gmijava -cp target/bcs2110-2025.jar gemini_lite.Proxy [port]Example:
java -cp target/bcs2110-2025.jar gemini_lite.Proxy 1959Then point the client through the proxy:
java -cp target/bcs2110-2025.jar gemini_lite.Client gemini-lite://localhost:1959/index.gmimvn testsrc/main/java/
├── gemini_lite/
│ ├── Client.java // CLI client entry point
│ ├── Server.java // CLI server entry point
│ └── Proxy.java // CLI proxy entry point
├── engine/
│ ├── ClientEngine.java // Core client logic (fetch, retry, redirect)
│ ├── ServerEngine.java // Core server logic (routing, response)
│ └── ProxyEngine.java // Core proxy logic (relay, redirect)
├── handler/
│ ├── ResourceHandler.java // Interface for serving resources
│ ├── FilesystemHandler.java // Filesystem-based resource handler
│ └── ReplyAndBody.java // Reply record with body data
└── protocol/
├── Request.java // Request parsing and validation
├── Reply.java // Response parsing and validation
└── ProtocolException.java // Custom exception for protocol errors
┌────────────────────────────────────────────────────────┐
│ CLI Entry Points │
│ Client.java │ Server.java │ Proxy.java │
└───────────┬─────────┴───────┬───────┴────────┬─────────┘
│ │ │
┌───────────▼─────┐ ┌────────▼────────┐ ┌─────▼──────────┐
│ ClientEngine │ │ ServerEngine │ │ ProxyEngine │
│ - Fetch/retry │ │ - Parse req │ │ - Relay req │
│ - Redirects │ │ - Route/serve │ │ - Redirects │
│ - Backoff │ │ - MIME detect │ │ - Error relay │
└───────────┬─────┘ └────────┬────────┘ └─────┬──────────┘
│ │ │
└────────┬───────┴────────┬───────┘
│ │
┌─────────▼──────┐ ┌──────▼──────────────┐
│ Protocol Layer │ │ Resource Handler │
│ Request/Reply │ │ (FilesystemHandler) │
│ parsing & │ │ - Safe path resolve │
│ validation │ │ - Directory listing │
└────────────────┘ └─────────────────────┘
This project was developed for educational purposes as part of the BCS2110 course at Maastricht University.