Proxying HTTP and HTTPS

Proxying HTTP and HTTPS Origins #

Problem #

Cloudflare allows configuring how it handles SSL/TLS requests to proxied origin servers. Custom SSL/TLS options are:

  • Strict (SSL-Only Origin Pull)
  • Full (Strict) - validates origin cert
  • Full - no cert validation
  • Flexible - pull from origin over HTTP
  • Off (not secure)

However, this configuration is set per domain. So, in the folloing scenario:

  • https://project-one.example.org <– https://secure-origin
  • https://project-two.example.org <– http://my-insecure-origin

If we need to proxy from secure origins (HTTPS) for some sub-domains (project-one) and from HTTP for others (project-two), serving everything to end-users over HTTPS, none of the given SSL/TLS handling options would cover both scenarios.

One may encounter this situation when trying to proxy origin servers that cannot be configured to serve HTTPS out of the box, for example:

Solution 1: Switch to Hosting on Cloudflare #

One solution is to re-deploy the static content (originally hosted on HTTP-only origins) to Cloudflare Pages/Workers and serve them directly.

Solution 2: Switch to Hosting on Another HTTPS-Capable Provider #

Since there are many static hosting providers that support HTTPS and offer generous free tier plans, the second solution is to move all static sites from HTTP to HTTPS hosting providers.

If the source code of the static website is already being pushed to GitLab, switching to GitLab Pages could be the easiest solution. Note that GitLab allows publishing pages from private repositories.

Solution 3: Proxy HTTP or HTTPS with CF Workers #

In some cases, switching hosting providers may require too much effort:

  • updating the CI/CD pipeline to publish static files to a different hosting provider;
  • the need to completely rewrite the CI/CD pipeline (when moving the pipeline to different platform).

In such cases, a simpler approach could be to keep the existing origin servers (and their CI/CD pipelines) as is, and deploy lightweight Cloudflare Workers that would proxy static content from upstream origins.

Minimal CF Worker Proxy #

Here is a sample worker that proxies only GET requests.

export default {
	async fetch(request, env, ctx) {
		async function methodNotAllowed(request) {
			return new Response(`Method ${request.method} no allowed.`, {
				status: 405,
				headers: {
					Allow: "GET",
				},
			});
		}
        // allow only GET requests
		if (request.method !== "GET") return methodNotAllowed(request);

    const url = new URL(request.url);
		return fetch(`${env.ORIGIN_URL}${url.pathname}`);
	},
};