Cloudflare Worker that proxies requests to https://api.qonversion.io as transparently as possible while allowing controlled CORS behavior for browser clients.
- Preserves request method, path, query string, and body stream.
- Forwards request headers with
Host, hop-by-hop transport headers, client IP forwarding headers, and cookies stripped. - Streams upstream responses back with original status and headers.
- Only changes response behavior for configured CORS handling.
- Forces
Accept-Encoding: identityupstream so responses match the direct Qonversion API behavior.
Wrangler variables in wrangler.jsonc:
UPSTREAM_ORIGIN: upstream Qonversion endpoint. Defaults tohttps://api.qonversion.io.ALLOWED_ORIGINS: comma-separated browser origin allowlist for CORS responses. Set to*to allow any origin. The Worker never sendsAccess-Control-Allow-Credentialsbecause this proxy is intended for bearer-token clients, not cookie-based auth.ALLOWED_PATH_PATTERNS: optional comma-separated path allowlist for requests the proxy is allowed to forward. Defaults to/v3/*. Supports exact paths like/v3/health, prefix patterns ending in*like/v3/*, and a literal*to allow any path.ALLOWED_METHODS: comma-separated request method allowlist. Defaults toGET,POST,OPTIONS. Requests using methods outside this allowlist are rejected locally with405. IncludeOPTIONSif browser preflight support is needed.BLOCK_UNAUTHENTICATED_REQUESTS: whentrue, reject non-OPTIONSrequests that do not includeAuthorization.
ALLOWED_ORIGINS format details:
- Use exact origins, not URLs with paths.
- Include the protocol, for example
https://app.example.com. - Include the port when needed, for example
http://localhost:4000. - Do not include a trailing slash.
- Separate multiple origins with commas.
*is supported to allow any origin.- Pattern wildcards such as
*.example.comorhttps://*.example.comare not supported. - Requests with no
Originheader are still allowed, so non-browser clients are not blocked. - Requests with an
Originheader that is not allowed are rejected with403, including non-preflight requests.
Examples:
ALLOWED_ORIGINS=https://app.example.com,http://localhost:4000ALLOWED_ORIGINS=*ALLOWED_PATH_PATTERNS format details:
- Use request paths only, not full URLs.
- Exact paths are supported, for example
/v3/health. - Prefix patterns are supported when they end in
*, for example/api/*. - A literal
*allows any path. - Mid-pattern wildcards such as
/v*/usersare not supported. - Separate multiple patterns with commas.
Examples:
ALLOWED_PATH_PATTERNS=/api/*ALLOWED_PATH_PATTERNS=/v3/health,/v3/identities/*Default:
ALLOWED_PATH_PATTERNS=/v3/*ALLOWED_METHODS format details:
- Use a comma-separated list of HTTP methods.
- Values are normalized case-insensitively.
- The default is
GET,POST,OPTIONS. - Include
OPTIONSto support browser preflight requests.
Examples:
ALLOWED_METHODS=GET,POST,OPTIONSALLOWED_METHODS=GET,POST,PATCH,OPTIONSThe Worker emits structured logs for:
proxy_request: successful upstream requestsproxy_request_error: upstream failuresproxy_request_blocked: requests rejected by the unauthenticated-request guard
To reduce log leakage, logs include the request path and whether a query string existed, but do not log the raw query string.
Edit routes in wrangler.jsonc and add one custom domain per hostname you control:
Cloudflare will create the DNS record and certificate for each custom domain when you deploy.
pnpm install
pnpm test
pnpm run lint
pnpm run typecheck
pnpm run devpnpm run deployNormal proxy request:
curl -i "https://your-alias.example.com/v3/products"Preflight request:
curl -i -X OPTIONS "https://your-alias.example.com/v3/products" \
-H "Origin: https://app.example.com" \
-H "Access-Control-Request-Method: GET" \
-H "Access-Control-Request-Headers: content-type, authorization"If you need large numbers of alternate domains or customer-owned vanity domains, keep the proxy code unchanged and move the deployment model toward wildcard routing or Cloudflare for SaaS.