Can't get path matched with json

1. Caddy version (caddy version):

v2.2.0 h1:sMUFqTbVIRlmA8NkFnNt9l7s0e+0gw+7GPIrhty905A=

2. How I run Caddy:

static https site
without automatic_https

a. System environment:

ubuntu server 18.04.5
systemd
not docker

b. Command:

systemctl start caddy

c. Service/unit/compose file:

systemd files came from the installtion ("dpkg -i caddy_2.2.0_linux_amd64.deb")
I edited it ("/lib/systemd/system/caddy.service")
mod “--config /etc/caddy/Caddyfile” to “--config /etc/caddy/config.json

d. My complete Caddyfile or JSON config:

{
   "apps":{
      "http":{
         "https_port":443,
         "servers":{
            "srv0":{
               "listen":[
                  ":443"
               ],
               "automatic_https":{
                  "disable":true
               },
               "tls_connection_policies":[
                  {
                     
                  }
               ],
               "routes":[
                  {
                     "match":[
                        {
                           "host":[
                              "*.mydomain.com"
                           ]
                        }
                     ],
                     "handle":[
                        {
                           "handler":"subroute",
                           "routes":[
                              {
                                 "handle":[
                                    {
                                       "handler":"file_server",
                                       "root":"/var/www/html",
                                       "index_names":[
                                          "index.html"
                                       ]
                                    }
                                 ]
                              },
                              {
                                 "match":[
                                    {
                                       "path":[
                                          "/mypath"
                                       ]
                                    }
                                 ],
                                 "handle":[
                                    {
                                       "handler":"file_server",
                                       "root":"/var/www/html",
                                       "index_names":[
                                          "index.html"
                                       ]
                                    }
                                 ]
                              }
                           ]
                        }
                     ]
                  }
               ]
            }
         }
      },
      "tls":{
         "certificates":{
            "load_files":[
               {
                  "certificate":"/myssldir/mycert",
                  "key":"/myssldir/mykey"
               }
            ]
         }
      }
   }
}

3. The problem I’m having:

try to access
https://mydomain.com/mypath
expect index page ("/var/www/html/index.html") defined in json
but got error 404

access to “https://mydomain.com/” is fine, index page showing up

4. Error messages and/or full log output:

got error 404

5. What I already tried:

 "path": [  "/mypath" ]
 "path": [  "*/mypath" ]
 "path": [  "/mypath*" ]
 "path": [  "*/mypath*" ]
 "path": [  "*mypath*" ]
 "path": [  "/some_other_paths" ]

6. Links to relevant resources:

Your first route matches all requests, so once the file server has finished its job the request has already been handled. The more specific route should usually go first.

This wiki article will help; it is about the Caddyfile but will help you understand how to compose handlers in general: Composing in the Caddyfile

1 Like

Matt, thank you for your help!

I switch the route order but nothing change. does it run from up to down always?

"routes":[
   {
      "match":[
         {
            "path":[
               "/mypath"
            ]
         }
      ],
      "handle":[
         {
            "handler":"file_server",
            "root":"/var/www/html",
            "index_names":[
               "index.html"
            ]
         }
      ]
   },
   {
      "handle":[
         {
            "handler":"file_server",
            "root":"/var/www/html",
            "index_names":[
               "index.html"
            ]
         }
      ]
   }
]

I too try add this one : "terminal": true
but the same

It’s always top to bottom, yes. Matching on /mypath will only match exactly /mypath. For anything under that, match on /mypath*.

Also FYI index_names is redundant here, because the default is already index.html.

You can also use the vars handler to set root instead of specifying it for each file_server.

1 Like

it can not get matched even I make it be the only route in json. so strange.

{
   "handler":"subroute",
   "routes":[
      {
         "match":[
            {
               "path":[
                  "/mypath"
               ]
            }
         ],
         "handle":[
            {
               "handler":"file_server",
               "root":"/var/www/html",
               "index_names":[
                  "index.html"
               ]
            }
         ],
         "terminal":true
      }
   ]
}

The JSON docs describe precisely how handlers work, it should answer your question: JSON Config Structure - Caddy Documentation

Here’s how the path matcher works: JSON Config Structure - Caddy Documentation

1 Like

Thanks for help!

I modified routes to like this, but only "/" can be matched.

{
   "handler":"subroute",
   "routes":[
      {
         "match":[
            {
               "path":[
                  "/"
               ]
            }
         ],
         "handle":[
            {
               "handler":"vars",
               "root":"/var/www/caddy"
            }
         ]
      },
      {
         "match":[
            {
               "path":[
                  "/mypath"
               ]
            }
         ],
         "handle":[
            {
               "handler":"vars",
               "root":"/var/www/html"
            }
         ]
      },
      {
         "handle":[
            {
               "handler":"file_server"
            }
         ]
      }
   ]
}

Ah - there’s two issues here. The file_server appends the request path to the root when looking for files. This means that it will be looking for files at /var/www/html/mypath. If you don’t have files there, it won’t serve anything. To solve this, you can use a rewrite to strip the /mypath prefix after setting root, before continuing.

Also, you’ll want to use the group functionality to make the root routes mutually exclusive. You just need to make sure that they both have the same group name. This makes sure that if one is matched, the other will be skipped altogether, instead of possibly running both, i.e. having the root be overridden by the following one.

2 Likes

Done. That’s it, the rewrite thing :rofl: :sweat_smile:

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