Something wrong in caddyfile

First i use the caddyfile like below.

https://example.com {
        reverse_proxy  xx:xx:xx:xx:port
        tls cert.crt private.key
}

i enter https://example.com in broewser. Everything is right.
i change the caddyfile like below.

https://example.com {
        reverse_proxy  /api/*  xx:xx:xx:xx:port
        tls cert.crt private.key
}

then i enter https://example.com/api in browser. it shows blank.
i also try this

https://example.com {
        reverse_proxy  /api  xx:xx:xx:xx:port
        tls cert.crt private.key
}

it shows 404.
how can i do?

This is expected behaviour.

The requested URI /api is not matched by the reverse proxy which is looking for /api/*.

It is missing a slash on the end, at minimum, e.g. /api/ or more afterwards, e.g. /api/foo.

Since you have not configured Caddy to do anything with requests which do not match /api/*, it simply serves an empty 200 OK response (no body), i.e. a blank page.

This configuration cannot generate a 404, so the 404 status must have come from upstream (xx:xx:xx:xx:port). The upstream server must not have been expecting a request for /api - it may instead have been expecting a request for the web root /.

2 Likes

thanks for reply

https://example.com {
        reverse_proxy  /api/*  xx:xx:xx:xx:port
        tls cert.crt private.key
}

if i use this config and i enter https://example.com/api/ in browser, which one is been shown, xx:xx:xx:xx:port or xx:xx:xx:xx:port/api?
i use this config and i enter https://example.com/api/. it shows 404. i have a service which can be accessed by xx:xx:xx:xx:port. i want to access it by https://example.com/api/. How can i do?

Caddy does not, by default, alter the URI of the request in any way when passing it through to the upstream server.

That means when you request https://example.com/api/, Caddy requests http://xx:xx:xx:xx:port/api/.

This means the second will be shown (xx:xx:xx:xx:port/api/).

You’ll need to configure Caddy to alter the URI yourself to remove the extra part (/api), before proxying the request.

You can do that with the uri directive (e.g. uri strip_prefix /api) or via the handle_path directive, which uses the uri directive behind the scenes.

I’d also recommend using a strict rewrite/redir to treat the literal /api as if it were /api/, so that you can avoid an /api* matcher accidentally catching /apifoo (clearly not intended).

A working configuration might look something like:

https://example.com {
  tls cert.crt private.key
  redir /api /api/
  handle_path /api/* {
    reverse_proxy xx:xx:xx:xx:port
  }
}

You might run into an issue where links and Location headers returning from the upstream server are mismatched to what Caddy now expects to receive, but you might not, depending on the upstream app. If you encounter some weird behavior here, read up on the “subfolder problem”.

See:

2 Likes

it works perfectly. thanks for your kind for such a stupid question. :heart:

1 Like