-
-
Notifications
You must be signed in to change notification settings - Fork 4.2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Reject configuration when placeholders are missing #2815
Comments
I like the idea of failing early, but there's a few complications with this. Placeholders aren't evaluated until they are used. In the example you gave, that replacement happens when the server is starting up, but in other cases a replacement doesn't happen until an HTTP request. Would we treat the whole HTTP request as an error then? I agree though that it would be useful to make a ReplaceAll method that could return an error value if a placeholder is not recognized. Another question: do we treat an empty placeholder as an error, or make that an option as well? i.e. what is the difference between an env variable being set and being empty? Empty environment variables are indistinguishable from unset/nil ones, but other placeholders (like properties of the HTTP request) can distinguish empty from unset/nil. Do you think this kind of check would be better handled by a linter? |
Related to #2313 |
The Replacer interface has new methods to customize how to handle empty or unrecognized placeholders. Closes #2815.
@pascalgn Alrighty, I had to update the replacers to make logging work in #2831 so you can find these enhancements in 755d442.
In that PR I've also updated the examples you mentioned, of placeholders in automatic HTTPS and in listener addresses, so those yield errors now. It's a bit tricky though. The listener address one was pretty straightforward: if a placeholder isn't recognized or is empty, that should be an error. The host matcher one is more nuanced, because those are meant to be evaluated at HTTP-request-time, not at server startup like we're doing for automatic HTTPS. So the placeholder could be one that exists only during an HTTP request. We don't want to error completely for that at startup, but we should error if the placeholder is recognized and still empty. While I don't love a signature like Env variables make things even tricker because I don't think there's a super-efficient way in Go to know whether an env variable is set: we can only know whether it is empty (and unset == empty, although maybe by iterating all known env variables we could determine the difference, but that doesn't seem efficient). Anyway, I hope that is sufficient. Will close this now. Let me know how it works for you! |
I'm having a look at #2831 and it's looking quite good! Regarding the To also support use cases where a variable can be empty, we will need a way to specify a default value for missing parameters, though, as already requested in #2313 (I would also support the suggested syntax from bash, Technically, for both environment variables and e.g. HTTP headers we could treat nonexistent and empty differently, but I think then we would also need to provide a different default-value-syntax and IMO it would make things unnecessarily complicated. So I think treating empty and missing the same should be fine. |
Ah, I'll give you one:
Actually two -- here's another:
In the first case, we have a template string that is evaluated by the templates handler above it, but static response bodies also support placeholders. Thus, Similarly for JSON: These only happen a few places in the current code base, I think: pretty much everywhere else doesn't expect template- or JSON-style values, so it is rare that it happens, but it happens.
Aha 😄 I do like smileys. We can move the discussion about default placeholder values to that issue. If we expand the functionality of placeholders, I want to be careful how we do it. (There's also some talk of giving placeholders the ability to be wrapped in a simple function, like for formatting time, etc.) |
Agree, I will continue the discussion about default values in #2313! However, regarding your examples, I think we need another solution. Usually this should be solved by escaping, I think (although it would increase the replacer complexity). So IMO it would be hard to explain to users that the following works (
But the following will not work correctly (
(Especially considering that even the first example could break in the future, when for some reason a new replacement I think what we really need is some kind of escaping, like
|
Yeah I also considered that, but I just hate how tedious escaping is... You have a good point though, the inconsistency here isn't great. It's something we should figure out before the stable release. |
* logging: Initial implementation * logging: More encoder formats, better defaults * logging: Fix repetition bug with FilterEncoder; add more presets * logging: DiscardWriter; delete or no-op logs that discard their output * logging: Add http.handlers.log module; enhance Replacer methods The Replacer interface has new methods to customize how to handle empty or unrecognized placeholders. Closes #2815. * logging: Overhaul HTTP logging, fix bugs, improve filtering, etc. * logging: General cleanup, begin transitioning to using new loggers * Fixes after merge conflict
I had some thoughts on this and I think escaping isn't the best solution right now. The suggestion from some days ago was escaping, like However, consider for example the following config:
As we use What I thought now is to maybe make the beginning and end of placeholders configurable, so users which need to use
This has some advantages, some disadvantages, but I think we could consider it as an alternative to escaping... |
Going to close this since we have addressed the idea of replacers returning errors; other things are for different issues I think. |
Can something like this be done with current version of caddy? I've read about the default environment variables, but I'm looking for something similar to bash's I find that whenever there's a missing env variable that usually means I messed up somewhere, so it's helpful to get |
@thenbe please open a new issue, this one is way too old, it was from before Caddy v2 even existed. |
1. What would you like to have changed?
When placeholders are used in the configuration, for example
{env.NO_SUCH_VAR}
, caddy should fail during startup, to indicate that something is wrong.2. Why is this feature a useful, necessary, and/or important addition to this project?
IMO it's better usability to fail early, because it allows users to detect the root cause of the problem more easily.
Having an error like
2019/10/14 17:02:45 [ERROR][{env.DOMAIN_NAME}] failed to obtain certificate: acme: error.
is a bit harder to understand than (for example)ERROR: Placeholders not found in configuration value: {env.DOMAIN_NAME}
3. What alternatives are there, or what are you doing in the meantime to work around the lack of this feature?
The alternative is to just leave it as is and accept the slightly worse user experience.
4. Please link to any relevant issues, pull requests, or other discussions.
Extra: Implementation details
For example, here we do some replacement:
caddy/modules/caddyhttp/caddyhttp.go
Lines 297 to 305 in acf7dea
The
repl.ReplaceAll
method only returnsstring
, so we cannot know if the replacement was successful. An easy solution would be to introduce another method, likeReplaceAllOrFail
, but there might be better ways...The text was updated successfully, but these errors were encountered: