A high-performance caching proxy server built with Express.js that intelligently caches static resources and reduces backend server load.
Find a file
2025-07-02 21:28:38 +08:00
.gitignore first commit 2025-07-02 21:28:38 +08:00
config.toml first commit 2025-07-02 21:28:38 +08:00
LICENSE first commit 2025-07-02 21:28:38 +08:00
package.json first commit 2025-07-02 21:28:38 +08:00
README.md first commit 2025-07-02 21:28:38 +08:00
server.js first commit 2025-07-02 21:28:38 +08:00

Express Cache Proxy Server

A high-performance caching proxy server built with Express.js that intelligently caches static resources and reduces backend server load.

Features

  • 🚀 Smart Caching: Automatically caches GET requests for static files
  • Dual Cache Duration: Different cache times for regular files vs. query-parameterized files
  • 🎨 Colored Logging: Visual distinction between cache hits, pass-through, and non-cacheable requests
  • ⚙️ TOML Configuration: Flexible configuration via TOML file
  • 📁 File Type Detection: Configurable file extensions for caching
  • 🔄 Query String Support: Special handling for versioned assets (e.g., app.js?v123)

Installation

npm install

Usage

Basic Usage

npm start

Development Mode

npm run dev

Configuration

Create a config.toml file in the project root to customize behavior:

[server]
port = 24300
target_server = "http://localhost:8080"

[cache]
directory = "./cache"
default_duration_hours = 24
query_only_duration_hours = 72

# Regular cacheable extensions
extensions = ["html", "css", "js", "png", "jpg", "json"]

# Extensions that support query string caching
query_cache_extensions = ["png", "jpg"]

Configuration Options

Server Section

  • port: Proxy server port (default: 24300)
  • target_server: Backend server URL (default: http://localhost:8080)

Cache Section

  • directory: Cache storage directory (default: ./cache)
  • default_duration_hours: Cache duration for regular files (default: 24 hours)
  • query_only_duration_hours: Cache duration for query-parameterized files (default: 72 hours/3 days)
  • extensions: Array of cacheable file extensions
  • query_cache_extensions: Array of extensions that support query string caching

Caching Rules

Cacheable Requests

Regular Files (24 hours by default):

  • /index.html
  • /styles/main.css
  • /images/logo.png
  • /data.json

Query-Parameterized Files (3 days by default):

  • /image.jpg?v123456 (jpg in query_cache_extensions)
  • /image.png?hash789abc (png in query_cache_extensions)
  • /style.css?build2024 (css not in query_cache_extensions)

Non-Cacheable Requests

  • POST, PUT, DELETE requests
  • Files without cacheable extensions
  • Query strings with = (e.g., /api/data?page=1&limit=10)
  • Files with query strings not in query_cache_extensions (e.g., /data.json?abc if json not in list)

Non-Cacheable Requests

  • POST, PUT, DELETE requests
  • Files without cacheable extensions
  • Query strings with = (e.g., /api/data?page=1&limit=10)
  • Dynamic API endpoints

Log Output

The server provides color-coded logs for easy monitoring:

[07:10:01] 127.0.0.1 - GET /index.html (86400s)        # 🟢 Green - Cache hit
[07:10:02] 127.0.0.1 - GET /app.js?v123                # 🔵 Blue - Pass-through and cache
[07:10:03] 127.0.0.1 - POST /api/login                 # ⚫ Gray - Not cacheable

Log Colors

  • 🟢 Green: Cache hit - served from local cache
  • 🔵 Blue: Pass-through - forwarded to backend and cached for future requests
  • Gray: Not cacheable - forwarded to backend without caching

Cache Strategy

Two-Tier Cache Duration

  1. Regular Static Files: Shorter cache duration for frequently updated content
  2. Versioned Assets: Longer cache duration for content-hashed or versioned files

This approach optimizes for:

  • Fast content updates for regular files
  • Maximum performance for versioned assets
  • Reduced backend load for static resources

Query String Handling

The proxy now provides fine-grained control over query string caching:

  • Simple queries (no = sign): Only cached if file extension is in query_cache_extensions
  • Complex queries (with = sign): Never cached
  • Extension-based filtering: Different rules for different file types

Examples:

# ✅ Cached (png in query_cache_extensions)
/image.png?v123

# ❌ Not cached (json not in query_cache_extensions by default)
/data.json?abc123

# ❌ Not cached (contains = sign)
/api/data?page=1

# ✅ Cached (no query string, js in extensions)
/app.js

Performance Benefits

  • Reduced Backend Load: Static files served from cache
  • Faster Response Times: Local file serving vs. backend requests
  • Bandwidth Savings: Fewer requests to origin server
  • Improved User Experience: Faster page loads

File Structure

project-root/
├── server.js          # Main server file
├── config.toml        # Configuration file
├── package.json       # Dependencies
├── cache/            # Cache directory (auto-created)
└── README.md         # This file

Dependencies

  • express: Web framework
  • axios: HTTP client for proxying requests
  • toml: TOML configuration parser

License

MIT