Happy path works, but how to failback?

1. Output of caddy version:

v2.6.2 h1:wKoFIxpmOJLGl3QXoo6PNbYvGW4xLEgo32GPBEjWL8o=

2. How I run Caddy:

I run caddy using docker; no fancy stuff.

a. System environment:

Ubuntu 22.04 LTS, latest docker

d. My complete Caddy config:

my.name.com {
	file_server @secured {
		root "/static"
	}

	@secured {
		query "param=blabla"
	}

}

3. The problem I’m having:

I’m trying to enforce that the param query is set with value blabla. This works perfect. I understand that this is not safe, but for my purposes it’s good enough. Now I want to make it better by responding with a 401 when the query param is not provided. I simply don’t understand how to do that. So in other words: the happy path works, but how to catch all the scenario’s where the param does not have value blabla?

5. What I already tried:

I tried adding respond "nope" 401 to the caddyfile, but this resulted in always responding a 401.

my.name.com {
	file_server @secured {
		root "/static"
	}

	@secured {
		query "param=blabla"
	}

    respond "nope" 401

}

Can somebody push me into the right direction?

Hey, I already found out! Turns out to that I needed to be way more explicit in the handlers. I now did this:

my.name.com {
	
	@secured {
		query "param=blabla"
	}

	handle_path / {
		file_server @secured {
			root "/static"
		}
	}
	
	handle / {
		respond "access denied" 401
	}

}

The docs didn’t really tell me this by the way.

2 Likes

It’s due to directive ordering:

You can read more about this in our wiki:

In short, your solution is good :+1: (although you can change your handle_path to handle, since there’s no prefix to strip).

Hey @matt , turns out my solution isn’t 100% good :slight_smile: . So I have the following config in use now:

my.name.com {

	@secured {
		query "param=blabla"
	}

	handle "/" {
		file_server @secured {
			root "/static"
		}
	}

	handle / {
		respond "access denied" 401
	}

}

This works for the “root” page, in my case that’s an index.html file. Also the validation part (the param check) also works. But the piece which doesn’t work is everything else then fetching the root page. For example, I have a css file in the same directory as well: index.css. When I try to open that file, I still get a HTTP 200 response, including an empty page. Any clue?

Your handle directives don’t make sense – handle blocks are mutually exclusive, so only the first matching one will run. You’re using the same matcher (a path matcher of / which only matches exactly / and nothing else) so the first one will shadow/cover/overlap the other one and cause it to never run.

I’m not quite sure what you’re trying to do. You only want to serve something on the root path of your site but no other paths? Then remove the / matcher from your second handle so that it matches all requests.

Also, you don’t need the double-quotes around the matcher of your first handle, you’re not using and spaces in that “token” so it’s redundant.

You might also intend to put the @secured matcher on your handle instead of on file_server. But again I’m not sure your intent so that’s just a clue in case you didn’t realize you could do that.

Well, I try to do the following:

  • I want to serve all files in a directory (directory “/static” on the file system where caddy runs)
  • but all requests need to have a certain param in place with a certain value. If that header is missing, then caddy needs to return a 401.

That’s basically it. I have a feeling I’m almost there… but currently it only works on the index.html page only.

You probably want this, then:

my.name.com {
	@secured query "param=blabla"
	handle @secured {
		root * /static
		file_server
	}

	handle {
		respond "Access Denied" 403
	}
}
1 Like

This indeed does the trick. Thanks for all your help, @francislavoie !

1 Like

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