Rewrite or redirect Firebase Function

1. Caddy version (caddy version): v2.2.1

2. How I run Caddy: As a systemd service on Ubuntu server 20.04. Default Caddyfile on /etc/caddy/Caddyfile

a. System environment: Ubuntu server 20.04

b. Command:

service caddy restart

c. Service/unit/compose file:

[Unit]
Description=Caddy
Documentation=https://caddyserver.com/docs/
After=network.target network-online.target
Requires=network-online.target

[Service]
User=caddy
Group=caddy
ExecStart=/usr/bin/caddy run --environ --config /etc/caddy/Caddyfile
ExecReload=/usr/bin/caddy reload --config /etc/caddy/Caddyfile
TimeoutStopSec=5s
LimitNOFILE=1048576
LimitNPROC=512
PrivateTmp=true
ProtectSystem=full
AmbientCapabilities=CAP_NET_BIND_SERVICE

[Install]
WantedBy=multi-user.target

d. My complete Caddyfile or JSON config:

{
    email myemail@example.com
}

subdomain.domain.com, www.subdomain.domain.com {
    root * /usr/share/caddy
    file_server
    import webconf

    uri replace /api/ /test_api/
    reverse_proxy /test_api/* https://region-project.cloudfunctions.net
}

3. The problem I’m having:

Hello there.
I’m using Firebase Cloud functions and I’m trying to give them pretty urls. I want to point specific URLs from Caddy to another specific URL (firebase function url).

In the example Caddyfile I’m trying to redirect any request received at subdomain.domain.com/api to be redirected to https://region-project.cloudfunctions.net/test_api without the client noticing they’re actually calling Firebase.
I’m trying to make this work to every subsequent resource, i.e. subdomain.domain.com/api/resource to https://region-project.cloudfunctions.net/test_api/resource

I would like to understand what I need to do to achieve that. All help is appreciated!

4. Error messages and/or full log output:

I receive a 404 http error page issued by Google for this endpoint.

5. What I already tried:

I’ve tried to use uri replace and also rewrite for the /api path and reverse proxy after that.

6. Links to relevant resources:

That should work okay…

What’s import webconf pulling in? That’s not included in what you posted.

Another approach would be to use handle_path instead (which implicitly strips a prefix from a URL), give this a shot:

handle_path /api* {
	rewrite * /test_api{path}
	reverse_proxy https://region-project.cloudfunctions.net
}

Oh come to think of it, I think it’s likely because the upstream expects the Host to be set to your cloudfunctions domain:

reverse_proxy https://region-project.cloudfunctions.net {
	header_up Host region-project.cloudfunctions.net
}

By default, Caddy will pass through the domain from the original request (i.e. subdomain.domain.com or whatever) for the Host, and this likely breaks what Google wanted.

Thank you so much for your quick help!

Sorry, I missed that. Is just this:

    (webconf) {
      encode gzip
    }

As for using handle_path as you suggested, it works the same, getting the same error from Google. When I try adding the Host header inside the reverse_proxy directive, like this:

subdomain.domain.com, www.subdomain.domain.com {
    root * /usr/share/caddy
    file_server
    #import webconf

    handle_path /api* {
        rewrite * /test_api{path}
        reverse_proxy https://region-project.cloudfunctions.net{
            header_up Host region-project.cloudfunctions.net
        }
    }
}

I got the error Error during parsing: due to parsing difficulties, placeholders are not allowed when an upstream address contains a scheme.

Is there anyway to add such header to that reverse_proxy?

Thank you so much.

You missed the space before the {. Spaces are important in the Caddyfile. The lexer tokenizes the config by using whitespace as the delimiter. Here, Caddy thinks your upstream is a placeholder because it contains { which isn’t allowed here (when using https:// as well).

1 Like

I get it. Thank you so much for your help, it works perfectly now.

1 Like

This topic was automatically closed after 30 days. New replies are no longer allowed.