All Articles

Google Cloud Functions reverse proxy

Google Cloud Load balancer supports url rewrite only as a prefix to the url, so you can transform a request to host/url to host/prefix/url.

For my usecase I’m using a storage bucket as a backend, but if a request comes in to host/urlI would need it to proxy it to host/host/url so that it adds the host as a dynamic prefix to the url.

This is not supported out of the box so as fix I’ve changed the backend to a cloud function which proxies the request to the target bucket.

Embedded from

import * as functions from 'firebase-functions';

import * as http from 'http';

const BUCKET_NAME = "target-bucket"

exports.rewriteGCSRequest = functions.https.onRequest((oreq: any, ores: any) => {
    const redirectPath = oreq.originalUrl === '/' ? '/index.html' : oreq.originalUrl
    const options = {
        // host to forward to
        host: '',
        // port to forward to
        port: 80,
        // path to forward to
        path: `${BUCKET_NAME}/${oreq.hostname}${redirectPath}`,
        // request method
        method: 'GET',
        // headers to send
        headers: oreq.headers,
        agent: httpAgent

    const creq = http
        .request(options, pres => {

            // set http status code based on proxied response
            ores.writeHead(pres.statusCode, pres.headers);

            // wait for data
            pres.on('data', chunk => {

            pres.on('close', () => {
                // closed, let's end client request as well

            pres.on('end', () => {
                // finished, let's finish client request as well
        .on('error', e => {
            // we got an error
            try {
                // attempt to set error message and http status
            } catch (error) {
                // ignore


Check the original code here

The function also proxies all the requests to the root / to index.html, that is optional and can actually be configured directly in the load balancer.

Published Mar 18, 2021

Software engineer.