Get Even More Visitors To Your Blog, Upgrade To A Business Listing >>

Using FallbackResource with Apache Header Expressions Causes Weirdness

Recently we needed to set one of our Apache servers to output a HTTP Header for a specific URL, a simple task right? Well it turns out it can be a right pain...

The server is pretty standard, it's running Apache 2.4.43 passing requests to a PHP application.

Apache has in built functionality to conditionally set headers it's as simple as:

header set X-Header-Name "Header Value" "expr=%{REQUEST_URI} =~ m#^/matching/uri$#"

This simply put this says output a header named X-Header-Name with the value "Header Value" only if the requested URI matches the regex ^/matching/uri$. This didn't nothing though, I changed the regex and replaced it with a straight == but the only time I could get it to match and set a header was with broad patterns like .* or ^/.+.

Next I wanted to know what Apache thought the value of %{REQUEST_URI} was, clearly it was matching against something but maybe mod_rewrite was changing something. So I got Apache to send a header, non conditionally, which contained the value of %{REQUEST_URI} so I could see what it was:

Header set X-Request-URI "%{REQUEST_URI}e"

This returned exactly what I expected the.. requested URI, this made no sense! At this point I started looking at alternatives to %{REQUEST_URI}, and found that I could match against %{THE_REQUEST} but this felt like a work around that probably had issues I hadn't yet run into.

In an attempt to reduce the number of variables I disabled mod_rewrite, this made no difference, so that can be ruled out.

It was as I was putting the kettle on for the third time that something occurred to me. Even with mod_rewrite disabled the application was still being passed requests. And all requests are passed to index.php: low and behold the regex ^/index.php$ matches. This makes for some confusing possibilities. For example with the following code a request to /matching/uri will set the X-Request-URI header:

Header set X-Request-URI "%{REQUEST_URI}e"

So what this all boils down to is that %{REQUEST_URI} != %{REQUEST_URI}e which kind of makes sense (though I'm not exactly sure what the difference is). In an attempt to get the right value I turned my attention to the env function because I knew that the e in %{REQUEST_URI}e stands for environment.

Header set X-Request-URI "%{REQUEST_URI}e"

This didn't work either, it turns out that when using an env('REQUEST_URI') != %{REQUEST_URI}e however this isn't the case when using an inline expression:

Header set X-Header-Name "Header Value" "expr=env('REQUEST_URI'') =~ m#^/matching/uri$#"

This finally works! The docs allude to being treated slightly specially with regard to environment variables:

When environment variables are looked up within an If> condition, it's important to consider how extremely early in request processing that this resolution occurs.

I am no expert on the order of Apaches request processing so I'll leave working that one out as an exercise to the reader

Conclusion

Apache is weird.

If you are using mod_dir's FallbackResource to pass requests to your application and want to access REQUEST_URI in expressions (which now I write it sounds really niche) you need to use env('REQUEST_URI') otherwise you will get the value of the application entry point (eg index.php)



This post first appeared on Blog | Freshleaf Media, please read the originial post: here

Share the post

Using FallbackResource with Apache Header Expressions Causes Weirdness

×

Subscribe to Blog | Freshleaf Media

Get updates delivered right to your inbox!

Thank you for your subscription

×