Allow url without .html extension with json api

1. The problem I’m having:

I have looked into existing related topics and the closest i found was Do not require .html extension Caddy v2
But i still cannot make it work.

I have the following apps/http/servers config:

{
  "website": {
    "listen": [":443"],
    "routes": [
      {
        "match": [
          {
            "host": ["example.com"]
          },
          {
            "file": {
              "root": "/var/www/quartz/public",
              "try_files": [
                "{http.request.uri.path}",
                "{http.request.uri.path}.html"
              ]
            }
          }
        ],
        "handle": [
          {
            "handler": "encode",
            "encodings": {
              "gzip": {},
              "zstd": {}
            }
          },
          {
            "handler": "rewrite",
            "uri": "{http.matchers.file.relative}{http.request.uri.query_string}"
          }
          {
            "handler": "file_server",
            "root": "/var/www/quartz/public",
            "hide": [".git"]
          }
        ]
      }
    ]
  }
}

what i am trying to do is to map any request without .html extension to look for a file with that extension and rewrite to it.

my understanding is that {http.matchers.file.relative} should contain a value if the file matcher matched, but it seems to stay empty. so i conclude the file matcher does not match. is there a way to debug the actual filepath it tries with try_files?
or anything else i am missing?

2. Error messages and/or full log output:

current output: since the rewrite becomes an empty string it rewrite all the quest to empty string so basically looking for the index.html. so all request return the content of the index.html.
my understanding is that the file matcher would not match if non of the try_files match resulting in a not-found.

3. Caddy version:

v2.7.6 h1:w0NymbG2m9PcvKWsrXO6EEkY9Ru4FJK8uQbYcev1p3A=

4. How I installed and ran Caddy:

a. System environment:

installed on a debian using apt.

b. Command:

runs with systemd that gets installed with apt.

c. Service/unit/compose file:

na

d. My complete Caddy config:

see above

5. Links to relevant resources:

The easiest way to learn how to write JSON config is actually to write the equivalent Caddyfile first, then adapt it to JSON with the caddy adapt -p command.

What you’re trying to do is easily expressed like this as a Caddyfile:

example.com {
	root * /var/www/quartz/public
	encode zstd gzip
	try_files {path} {path}.html
	file_server {
		hide .git
	}
}

This produces this JSON config:

{
  "apps": {
    "http": {
      "servers": {
        "srv0": {
          "listen": [
            ":443"
          ],
          "routes": [
            {
              "match": [
                {
                  "host": [
                    "example.com"
                  ]
                }
              ],
              "handle": [
                {
                  "handler": "subroute",
                  "routes": [
                    {
                      "handle": [
                        {
                          "handler": "vars",
                          "root": "/var/www/quartz/public"
                        }
                      ]
                    },
                    {
                      "handle": [
                        {
                          "handler": "rewrite",
                          "uri": "{http.matchers.file.relative}"
                        }
                      ],
                      "match": [
                        {
                          "file": {
                            "try_files": [
                              "{http.request.uri.path}",
                              "{http.request.uri.path}.html"
                            ]
                          }
                        }
                      ]
                    },
                    {
                      "handle": [
                        {
                          "encodings": {
                            "gzip": {},
                            "zstd": {}
                          },
                          "handler": "encode",
                          "prefer": [
                            "zstd",
                            "gzip"
                          ]
                        },
                        {
                          "handler": "file_server",
                          "hide": [
                            ".git"
                          ]
                        }
                      ]
                    }
                  ]
                }
              ],
              "terminal": true
            }
          ]
        }
      }
    }
  }
}

If you enable debug level logging, then your logs should show more details about what’s going on with the rewrites. Add this at the top of your config.

  "logging": {
    "logs": {
      "default": {
        "level": "DEBUG"
      }
    }
  },

thank you so much for your fast reply. i didn’t know about adapt. super helpful tool.
and your answer solved my problem :slight_smile:

1 Like