Automatic redirect to HTTPS only if on_demand ask gives 200 OK

You can do :443 or https://, and a separate server block for :80 or http:// where you can do your own handling of redirects and such. This will override the default http:// catch-all that is automatically provisioned via automatic HTTPS.

Caddy currently only uses ask when it encounters a TLS handshake for a domain it hasn’t encountered yet. This means it only happens on HTTPS requests for a domain that Caddy doesn’t have a certificate for yet. This happens before any handlers are executed because it happens at the TLS handshake which is basically the first thing after accepting the connection.

If Caddy doesn’t have a valid certificate (or refuses to issue one because ask said no), then there’s no way for it to respond to the request with anything but a failed TLS handshake. Those errors would only happen if ask says no, so that means you can log the domains you rejected on your backend if you need.


I have a couple additional comments.

  • In your PHP script, I recommend using isset() instead of in_array() because isset() is O(1) whereas in_array() is O(n). With a lot of domains, this could make a significant performance difference. You’d just need to make sure the keys are the domains instead of the values (i.e. make your array like 'cfl.man-at-work.it' => true and so on)

  • Since it seems like you still want to serve sites on HTTP if the domain isn’t in your whitelist, I recommend you disable automatic HTTPS redirects (this is possible in the Caddyfile starting in Caddy v2.1 beta 1 with the global option auto_https disable_redirects, but having a http:// block will override this anyways) and have your PHP backend make the decision whether a redirect should occur rather than having Caddy do it.
    This essentially means that you’ll make an http:// server block in Caddy which you have handled by php_fastcgi, and in your backend, if the request was for HTTP, you can make a decision whether to respond with a Location header to trigger a redirect, or just serve whatever you want to serve if you don’t want to trigger a redirect.

Hopefully that answers your questions.

2 Likes