CFnew Dual-Mode Request Handling System: Routing API and Proxy Traffic in Cloudflare Workers

CFnew’s Cloudflare Worker implements a dual-mode request handling system that inspects incoming request paths to route /api/* traffic to a management API while processing all other requests as subscription proxy traffic that dynamically generates client configurations based on User-Agent headers.

The byJoey/cfnew repository deploys a single Cloudflare Worker capable of serving two distinct traffic patterns without requiring separate services. This architecture consolidates configuration management and subscription generation into one edge function, utilizing KV storage for persistent settings and query-string parameters for runtime overrides.

How the Dual-Mode Dispatcher Works

The request handler registered via addEventListener('fetch', …) in src/worker.js acts as a traffic router. It evaluates the url.pathname and request.method to determine which processing pipeline to invoke.

  • API Mode: Triggered when url.pathname.startsWith('/api/'). The worker delegates to handleApi(request) to process CRUD operations on preferred IPs and global settings.
  • Proxy Mode: Activated for all non-API paths. The worker delegates to handleProxy(request) to generate VLESS/Trojan URLs or subscription files.

If a request uses a method other than GET and does not target the /api/ namespace, the dispatcher immediately returns a 405 Method Not Allowed response, enforcing read-only access for subscription endpoints.

API Mode: Configuration Management

When operating in API mode, the worker exposes endpoints such as POST /api/preferred-ips and GET /api/preferred-ips. These handlers parse JSON payloads, validate optional API access flags stored in the KV namespace C, and mutate configuration state.

The API handler supports adding, deleting, and listing preferred proxy IPs with custom names and ports. After updating the KV store, it returns a JSON response containing { success: true, count: … } confirming the operation.

Proxy Mode: Subscription Generation

Proxy mode handles traffic from clients like Clash, Surge, Sing-Box, and Loon. The worker inspects the User-Agent header to infer the client type and format requirements. Based on this detection, it dynamically constructs YAML or JSON subscription files, or returns individual WebSocket-compatible VLESS/Trojan URLs (wss://…).

The proxy handler first loads the cached configuration from the KV namespace C, then applies any per-node overrides specified in the request URL before generating the final output.

Configuration Cache and KV Storage

Both modes share a common KV-based configuration cache bound to the namespace C as defined in wrangler.toml. This cache stores:

  • Global defaults (UUID, proxy IP lists, SOCKS5 endpoints)
  • Per-node preference tables
  • API access flags

Centralizing state in KV allows the worker to maintain consistency between administrative changes made via the API and subscription generation requests served through the proxy handler.

Per-Node Overrides via Query Parameters

The proxy handler interprets URL query parameters as runtime configuration overrides that take precedence over KV-stored values. Supported parameters include:

  • p= – Custom proxy IP and port (e.g., p=1.1.1.1:443)
  • wk= – WebSocket path overrides
  • s= – Security type modifications
  • rm= – Region mapping adjustments
  • ed= – Early data/WebSocket0-RTT settings
  • alpn= – TLS ALPN values (e.g., alpn=h3,h2)
  • ech= – Encrypted Client Hello configuration

These parameters enable dynamic node customization without redeploying the worker or modifying persistent storage.

Implementation Files and Architecture

The dual-mode logic is distributed across the following logical modules referenced in the deployment configuration:

File Responsibility
wrangler.toml Binds the KV namespace C and defines the worker entry point
src/worker.js Contains the fetch event listener and dispatch logic routing between API and proxy modes
src/api.js Implements handleApi(request) for JSON API responses and KV mutations
src/proxy.js Implements handleProxy(request) for User-Agent detection and subscription generation
src/config.js Centralizes default values, environment variable parsing, and region mapping tables

While the production build may compile these into a single script, the source structure maintains this separation of concerns.

Practical Usage Examples

Calling the Management API

// POST to /api/preferred-ips to add a new preferred node
fetch('https://my-worker.workers.dev/123e4567/api/preferred-ips', {
  method: 'POST',
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify({ 
    ip: '1.2.3.4', 
    port: 443, 
    name: '香港节点' 
  })
})
.then(r => r.json())
.then(console.log);
// Response: { success: true, count: 5 }

Generating a Clash Subscription

// Standard proxy request triggers subscription generation
fetch('https://my-worker.workers.dev/123e4567?ed=2048&p=1.1.1.1')
  .then(r => r.text())
  .then(yaml => {
    // yaml contains Clash-compatible configuration
    console.log(yaml);
  });

Applying Per-Node Overrides

// Request with query overrides for custom proxy settings
const link = 'https://my-worker.workers.dev/123e4567?ed=2048&p=proxy.example.com:443&alpn=h3,h2';
fetch(link)
  .then(r => r.text())
  .then(vlessUrl => {
    // Returns VLESS URL with embedded custom parameters
    console.log(vlessUrl);
  });

Summary

  • The dual-mode request handling system in byJoey/cfnew uses path-based routing to separate API management from subscription proxy functionality within a single Cloudflare Worker.
  • API mode handles /api/* paths for CRUD operations on KV-stored configurations, requiring validation and supporting JSON payloads.
  • Proxy mode processes all other requests, detecting client types via User-Agent headers to generate appropriate subscription formats (YAML for Clash, etc.).
  • Both modes share the KV namespace C for persistent configuration, enabling real-time updates via API that immediately affect subsequent proxy responses.
  • Query parameters (p=, alpn=, ed=, etc.) allow runtime per-node overrides without modifying stored configuration.

Frequently Asked Questions

How does CFnew decide whether to use API mode or proxy mode?

The worker inspects url.pathname in the fetch event handler located in src/worker.js. If the path starts with /api/, it routes to handleApi(request). Otherwise, it routes to handleProxy(request) after verifying the request method is GET (returning 405 for other methods).

What configuration options can be overridden via URL parameters?

The proxy handler recognizes several query parameters for runtime customization: p for proxy IP/port, alpn for TLS ALPN, ed for early data settings, wk for WebSocket paths, s for security type, and rm for region mapping. These overrides take precedence over values stored in the KV namespace C.

Which clients are supported by the proxy mode subscription generator?

The worker detects Clash, Surge, Sing-Box, Loon, and standard VLESS/Trojan clients by parsing the User-Agent header. Based on this detection, it generates the appropriate format: YAML for Clash, text for Surge, JSON for Sing-Box, or plain URLs for direct proxy clients.

Where is the KV configuration stored and accessed?

The worker binds to a KV namespace named C configured in wrangler.toml. Both src/api.js (API mode) and src/proxy.js (proxy mode) read from and write to this namespace to share global settings, preferred IP lists, and per-node configurations across all requests.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →