Status 404 for certain types of files

(b2c) #1

How to put 404 status for this files, not only in root but any location?

status 404 { 
    /autoload.php
    /composer.
    /config.php
    /eula.txt
    /eula_
    /CONTRIBUTING.md
    /UPGRADE-
    /README.md
}
(Matthew Fay) #2

One way to lend more advanced matching capabilities to the status directive is by using a rewrite. Use the if statements and placeholders to determine when to rewrite to a known path and then use status on that path.

rewrite {
  if_op or
  if {file} is autoload.php
  if {file} starts_with composer.
  if {file} is config.php
  if {file} is eula.txt
  if {file} starts_with eula_
  if {file} is CONTRIBUTING.md
  if {file} starts_with UPGRADE-
  if {file} is README.md
  to /not-found
}

status 404 /not-found

https://caddyserver.com/docs/rewrite
https://caddyserver.com/docs/placeholders

1 Like
(b2c) #3

Thanks it works. Is there any way to show actual 404(instead of 200) status with custom 404 message?

(Matthew Fay) #4

status 404 /not-found will produce a real Status 404 response with the default response body “404 Not Found”.

As far as I know, the errors directive works fine with status.

errors {
  404 custom-404-page.html
}

https://caddyserver.com/docs/errors

(b2c) #5

I’ve 404 custom page on root.

rewrite {
	if {path} not_starts_with /api 
		to {path} {path}/ /
}

rewrite {
    if_op or
    if {file} is autoload.php
    if {file} starts_with composer.
    if {file} is config.php
    if {file} is eula.txt
    if {file} starts_with eula_
    if {file} is CONTRIBUTING.md
    if {file} starts_with UPGRADE-
    if {file} is README.md
        to /not-found
}

status 404 /not-found

It’s not producing 404 status for any of the file, just 200!

(Matthew Fay) #6

Only one rewrite is ever executed for a given request. I assume the fallback rewrite is operating in your testing, ensuring that some real file is returned. If you test without that fallback rewrite, you should find the expected behaviour.

To resolve this, you can either play with rewrite ordering so the rewrite to 404 is checked first, or - to be more thorough - you can write the inverse of all the if checks into the first rewrite so that they can’t clash.

(b2c) #7

Yes reordering works. Now it shows 404 status with custom message for any non-existing files/directories as well as marked files in any location. It also hides php:no input file error. Thanks.

rewrite {
    if_op or
    if {file} is autoload.php
    if {file} starts_with composer.
    if {file} is config.php
    if {file} is eula.txt
    if {file} starts_with eula_
    if {file} is CONTRIBUTING.md
    if {file} starts_with UPGRADE-
    if {file} is README.md
        to /not-found
}

rewrite {
	if {path} not_starts_with /special 
		to {path} {path}/ /not-found
}

status 404 /not-found

errors {
	404 /404.html
}
1 Like
(Matthew Fay) #8

No worries!

Super minor, inconsequential, splitting-of-hairs nitpick: It’s not incorrect to call this an error, but it’s the same as a 404. When you get a Status 404 on a fastcgi endpoint, the response body generated upstream is prioritized over the usual “404 Not Found” response body. So this is really just a regular 404, but from PHP.

(b2c) #9

Agreed. Though I believe it creates a couple of scenarios in production server.

i. Un-usual user/bot will find out I’m using php in backend and which version.
ii. Caddy will serve non-existent request to php-fpm/php-cgi, it creates unnecessary load on php end.

So I prefer to check/hide before sending anything to php.

1 Like