Hi -- > I have a particular setup where what I'd like to do is reject all > requests that contain a particular HTTP header (in this case, a header > injected by hardware that means the request is coming from outside our > private network). Here's what I thought I could do: > > SetEnv FOO 1 > SetEnvIf Http-X-Foo .+ !FOO > <Directory /foo> > Allow from env=FOO > </Directory> > > The logic being, set FOO=1, then unset FOO if the HTTP header is > present, and only allow access to a resource if FOO is still present.
I thought a bit more about this last night, did some experimentation, and have a different proposal now. :-/ I found that for my particular situation, I can use: SetEnvIf Http-X-Foo ^$ FOO which works because SetEnvIf matches an empty regex if either the Http-X-Foo header is present and empty, or if it isn't present at all. I find this somewhat counter-intuitive (albeit useful in this particular case): how can a missing header match against anything? So, here's the proposal. Alas, I am deeply short of "round tuits" these days, but perhaps in a couple of months I can supply a patch. Comments welcome beforehand, though. 1) Leave mod_env as-is for the moment, but document that it only functions for content generators, and not for any prior part of the request handling process. In a future release (2.4? 3.0?) change the name of the directives to SetEnvCGI, etc. 2) Alter mod_setenvif so that SetEnvIf only matches if a header is present. To my mind, this is simply the single-header equivalent of what you'd want to happen when using a regex to match header names, e.g.: SetEnvIf ^Http-X-.*$ ... I'd presumably want nothing to happen if no headers match the name regex. In the case where I'm using a simple header name, like Http-X-Foo, that should be equivalent to using ^Http-X-Foo$, and thus follow the same logic; if no header is present that matches that name, nothing should happen (i.e., all value string regexs should fail to match, even for ^.*$ and other always-matching regexs). 3) Add to mod_setenvif a new directive, SetEnvPre, which works like this: SetEnvPre env-variable[=value] and simply sets env-variable to the given value (or an empty string if no value is supplied) before any SetEnvIf directives are applied. 4) Add to mod_setenvif another new directive, SetEnvExists, which works like this: SetEnvExists header|header-regex [!]env-variable[=value] [[!]env-variable[=value]] ... That is, just like SetEnvIf, but it only deals with headers (not other request attributes like Request_URI, etc.), and sets or unsets the env-variables based on whether any matching headers exist in the request. With these directives, one could set up something like: SetEnvPre FOO=false SetEnvExists ^Http-X-Foo-.*$ FOO=true SetEnvPre FOO_IGNORE SetEnvExists Http-X-Foo-Ignore FOO_IGNORE=all SetEnvIfNoCase Http-X-Foo-Ignore ^header=(.*)$ FOO_IGNORE=$1 so that FOO is "false" unless at least one Http-X-Foo-* header exists, in which case it's "true", and FOO_IGNORE is empty unless the Http-X-Foo-Ignore header exists, in which case FOO_IGNORE is "all", or if Http-X-Foo-Ignore has the form header=foo then FOO_IGNORE is "foo". Does that all make sense? As I said, comments welcome, and flames also. ("What's this?! Santa flambé??") Chris. -- GPG Key ID: 366A375B GPG Key Fingerprint: 485E 5041 17E1 E2BB C263 E4DE C8E3 FA36 366A 375B