GitHub - erson/zircon: Zircon - An (Experimental-AI-Built) Minimal Secure Web Server | High-performance, security-focused web server in C with XSS protection, SQL injection prevention, rate limiting, and extensive testing. Built for secure static content serving.

3 min read Original article ↗

Zircon

A lightweight, event-driven HTTP server written in C.

Note: This is an experimental project developed with AI assistance. Not recommended for production use.

Features

  • Event-driven architecture using kqueue (macOS/BSD) or epoll (Linux)
  • Zero-copy file transfer via platform-native sendfile
  • HTTP Keep-Alive for connection reuse
  • Security hardened:
    • Path traversal prevention
    • File type restrictions
    • Security headers (CSP, X-Frame-Options, HSTS, etc.)
    • Rate limiting
    • Request size limits with proper 413 responses
  • HTTP caching with ETag support and Cache-Control headers
  • MIME type detection by extension and magic bytes
  • Graceful shutdown on SIGTERM/SIGINT
  • Connection timeouts for idle connections
  • Config file support

Quick Start

# Build
make

# Run (listens on 127.0.0.1:8000 by default)
./bin/zircon

# Run with options
./bin/zircon --port 8080 --bind 0.0.0.0 --keep-alive

# Load from config file
./bin/zircon --config conf/server.conf

# Show all options
./bin/zircon --help

Usage

Usage: ./bin/zircon [OPTIONS]

Options:
  --config FILE      Load config from FILE
  --port PORT        Listen on PORT (default: 8000)
  --bind ADDR        Bind to ADDR (default: 127.0.0.1)
  --root DIR         Serve files from DIR (default: www)
  --timeout SEC      Connection timeout in seconds (default: 30)
  --keep-alive       Enable HTTP Keep-Alive
  --workers N        Run with N worker threads (experimental)
  --platform-info    Show platform capabilities
  --help             Show this help

Configuration File

Example conf/server.conf:

# Network
port = 8000
bind = 127.0.0.1

# Paths
root = www

# Limits
timeout = 30
max_request_size = 8192

# Features
keep_alive = false

Project Structure

zircon/
├── src/
│   ├── main.c              # Entry point, CLI parsing
│   ├── server_async.c      # Event-driven server core
│   ├── http.c              # HTTP parsing, MIME types, ETag
│   ├── rate_limiter.c      # IP-based rate limiting
│   ├── security_headers.c  # Security header generation
│   ├── logger.c            # Logging system
│   └── platform/           # Platform abstraction layer
│       ├── event_kqueue.c  # macOS/BSD event loop
│       ├── event_epoll.c   # Linux event loop
│       ├── sendfile.c      # Zero-copy file transfer
│       ├── thread_pool.c   # Worker thread pool
│       └── thread.c        # Thread utilities
├── include/                # Header files
├── test/                   # Test suite
├── www/                    # Default web root
├── conf/                   # Configuration files
└── Makefile

Building

Requirements

  • GCC or Clang
  • POSIX-compliant OS (Linux, macOS, FreeBSD)
  • pthread library

Build Commands

make              # Release build
make DEBUG=1      # Debug build with symbols
make clean        # Clean build artifacts
make test         # Run test suite

Testing

# Run all tests
make test

# Run specific test categories
make test-unit
make test-security
make test-performance

# Run edge case security tests
./test/edge_case_test.sh

Architecture

Event Loop

The server uses a single-threaded event loop by default:

  1. Accept connections via non-blocking socket
  2. Register client fd with kqueue/epoll
  3. On read event: parse HTTP request, validate, serve file
  4. Use sendfile() for zero-copy transfer
  5. With keep-alive: reset connection state and continue
  6. Without keep-alive: close connection

Security Model

All requests pass through multiple validation layers:

  • Path validation: Blocks .., encoded traversal, null bytes
  • Method restriction: Only GET and HEAD allowed
  • File type check: Whitelist of allowed extensions
  • Request size limit: Returns 413 for oversized requests
  • Rate limiting: Per-IP request throttling
  • Response headers: CSP, HSTS, X-Frame-Options, etc.

Performance

Single-threaded async mode on macOS (Apple Silicon):

  • ~15,000 requests/second with 50 concurrent connections
  • Sub-millisecond latency for small files

Limitations

  • No HTTPS (TLS) support
  • No HTTP/2
  • No dynamic content / CGI
  • Single-threaded by default

License

MIT License

Acknowledgments

Developed as an experiment in AI-assisted systems programming.