htaccess env variable and headers - apache

I am trying to add an Access-Control-Origin header in .htaccess for all URIs ending with .json. I cannot use <FilesMatch> as my paths are rewritten by mod_rewrite. (Or if I can it doesn't work.)
I found on Stack that it should be possible to do it with an env variable:
<IfModule mod_headers.c>
SetEnvIf Request_URI "\.json$" IS_JSON=TRUE
# ".json$" yields the same result
Header set Access-Control-Allow-Origin "*" env=IS_JSON
# "Header add" yields the same result
</IfModule>
But it does never add the header.
I tried using a snipper from another stack answer to check if the env variable is there using:
RewriteCond %{REQUEST_URI} !echo.php
RewriteRule .* echo.php?uri=%{REQUEST_URI}&json=%{ENV:IS_JSON} [L]
And it really was true.
When I remove the condition and leave it as:
Header set Access-Control-Allow-Origin "*"
the header is added, so the mod is loaded, but I would like to limit it for ".json$" only.
What am I doing wrong?

Instead of Header you probably meant to use RequestHeader to send custom headers to your code
SetEnvIf Request_URI \.json$ IS_JSON
RequestHeader set Access-Control-Allow-Origin "*" env=IS_JSON

Related

Apache SetEnvIf Request_URI does not match URLs

I'm trying to set HTTP header X-Robots-Tag to "noindex" on any URL starting with /exit/, but i can't figure out why SetEnvIf Request_URI simply does not match my URLs.
Part of my .htaccess file where i'm trying to solve the issue:
# For info
SetEnvIf Request_URI ^(.*)$ REQUEST_URI=$1
Header set X-Request-Uri "%{REQUEST_URI}e"
# Works
SetEnvIf Request_URI ^/.* WHY1
Header set X-Test1 "test1" env=WHY1
# Does not work any more
SetEnvIf Request_URI ^/e.* WHY2
Header set X-Test2 "test2" env=WHY2
SetEnvIf Request_URI ^\/e.* WHY3
Header set X-Test3 "test3" env=WHY3
SetEnvIf Request_URI ^\/\e.* WHY4
Header set X-Test4 "test4" env=WHY4
SetEnvIf Request_URI ^/\e.* WHY5
Header set X-Test5 "test5" env=WHY5
# What i'd like it worked
SetEnvIf Request_URI ^/exit/.* NOINDEX
Header set X-Robots-Tag "noindex" env=NOINDEX
This is what i get in network tab in Chrome browser:
x-request-uri: /exit/22216832/
x-test1: test1
This is what i actually expected:
x-request-uri: /exit/22216832/
x-test1: test1
x-test2: test2
x-test3: test3
x-test4: test4
x-test5: test5
x-robots-tag: noindex
EDIT
I sacrificed a little more of my hair and found out that i was actually overwriting Request_URI which seems to be some kind of global variable. After more testing i also figured out that this variable is a little liar:
.htaccess file:
# Getting value from a global variable
Header set X-Request-Uri "%{Request_URI}e"
# Expecting that Request_URI1 will have the same value as Request_URI
SetEnvIf Request_URI ^(.*)$ Request_URI1=$1
Header set X-Request-Uri1 "%{Request_URI1}e"
Network tab in Chrome browser:
x-request-uri: /exit/12313/
x-request-uri1: /index.php
So Request_URI in the global space is /exit/12313/, but in case of SetEnvIf it is /index.php and they say magic does not exist ☺.

Apache requestheaders env variable and also early

I am working on a system that needs to send Bearer token keys (JWT) for all URLs from an app our company is developing, the problem occurs when there is an attachment that needs to be downloaded, when clicking the link it fires the browser on the mobile device.
As you know this will not allow the headers to be set, so am working on a solution to add the header if it is emtpy.
Now I can get the env variable populated from the query string.
But I need a way to set the requestheader early along with the env= value, is this possible?
This is what I have:
RewriteCond %{QUERY_STRING} (?:^|&)token=([^&]+)
RewriteRule (.*) - [E=JW_TOKEN:%1]
RequestHeader setIfEmpty Authorization "Bearer %{JW_TOKEN}e" "env=JW_TOKEN"
What I need to do is something like:
RewriteCond %{QUERY_STRING} (?:^|&)token=([^&]+)
RewriteRule (.*) - [E=JW_TOKEN:%1]
RequestHeader setIfEmpty Authorization "Bearer %{JW_TOKEN}e" "env=JW_TOKEN early"
But this does not work.
I had a similar issue with HSTS. The most elegant way to conditionally set the header is (as described here: https://stackoverflow.com/a/24145033/3433306):
Header set Strict-Transport-Security "max-age=31536000" env=HTTPS
But this cannot be combined with the early flag. However, we can set the header early and remove it later, if the environment variable is not set as required.
Header set Strict-Transport-Security "max-age=31536000" early
Header unset Strict-Transport-Security env=!HTTPS
In your case, this would make something like the following (not tested):
RewriteCond %{QUERY_STRING} (?:^|&)token=([^&]+)
RewriteRule (.*) - [E=JW_TOKEN:%1]
RequestHeader setIfEmpty Authorization "Bearer %{JW_TOKEN}e" "early"
RequestHeader unset Authorization "env=!JW_TOKEN"

Allow Access-Control for Subdomain in .htaccess

Having issues setting up a generic Allow Origin for any subdomain in my .htaccess file. The following works for a singular subdomain:
<IfModule mod_headers.c>
Header set Access-Control-Allow-Origin http://subdomain.website.com
</IfModule>
But what I am looking for is something similar to this:
<IfModule mod_headers.c>
Header set Access-Control-Allow-Origin {ANY SUBDOMAIN}.website.com
</IfModule>
I have tried using a simple *.website.com wildcard, but that does not seem to work. Do you have to specify exactly what is coming in?
If you're looking to do it for whatever subdomain was being requested, try the following:
<IfModule mod_headers.c>
Header set Access-Control-Allow-Origin %{HTTP_HOST}
</IfModule>
If you need something more advanced, use mod_rewrite to set an environment variable and then refer to it using %{variable_name}e

apache SetEnvIf access query string

How do you access the query string from SetEnvIf? Somethig like:
SetEnvIf Query_String "p=path/to/file$" got_path
UPDATE:
In htaccess, I have:
SetEnvIf Request_URI !/folder/page1\.html$ NO_COOKIE
Header unset Cookie env=NO_COOKIE
RewriteRule (.*) /h.php?ref=$1 [L]
Basically, I ask h.php to take control of all user requests. And I use SetEnvIf to allow cookies only for /folder/page1.html.
However, it seems like Request_URI is always set to "h.php" and never to " /folder/page1.html" (maybe because of the redirection). For that reason I added ref=$1 to try to recognize which url it is being redirected from. Therefore I need to read the query string from SetEnvIf.
I hope I am making some sense.
You don't need to add a query string for this.
You can use:
# always start with NO_COOKIE=1
RewriteRule ^ - [E=NO_COOKIE:1]
# unset NO_COOKIE when URI is /folder/page1.html
RewriteCond %{THE_REQUEST} /folder/page1\.html
RewriteRule ^ - [E=!NO_COOKIE]
Header set NoCookie %{NO_COOKIE}e
RequestHeader set NoCookie %{NO_COOKIE}e

Apache 2.2 conditional headers on response

I am trying to configure apache to send expires and cache-control headers on response but only if I receive some specific query string on the request.
For this I've tried configuring the server as follows:
RewriteCond %{QUERY_STRING} ^.*{whateverIWantInMyQueryString}.*$
RewriteRule ^(.*)$ - [env=CACHE_HEADERS:1]
<FilesMatch "\.(js|css|png|gif|GIF)$">
<IfDefine CACHE_HEADERS>
ExpiresActive On
ExpiresDefault "access plus 12 hours"
Header append Cache-Control "public"
</IfDefine>
</FilesMatch>
But this does not seem to work.
If I change the configuration as follows:
....
<IfDefine !CACHE_HEADERS>
....
It does work, so it seems IfDefine is not able to check that CACHE_HEADERS environment variable is being set.
I've also tried configuring things with Header directive and conditional based on the same environment variable using something like this:
RewriteCond %{QUERY_STRING} ^.*{whateverIWantInMyQueryString}.*$
RewriteRule ^(.*)$ - [env=CACHE_HEADERS:1]
<FilesMatch "\.(js|css|png|gif|GIF)$">
Header always set Cache-Control "max-age=3600, public" env=CACHE_HEADERS
Header always set Expires "Thu, 01 Jan 2015 00:00:00 GMT" env=CACHE_HEADERS
</FilesMatch>
.....
But this does not work either. So I am assuming this might be because of the environment variable that is being set by mod_rewrite, that for some reason is not being detected by neither IfDefine directive nor Header directive.
Does anyone know what may be causing this or why is this not working at all?
The reason why IfDefined is not working you can find here: Apache IfDefine conditionals in .htaccess
Basically it's that IfDefined only evaluates variables defined at command line not if you define them like you did or with SetEnv or SetEnvIf.
However as far as I know env= should work.