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

Reply via email to