How to pass Apache environment variable to url in .htaccess - apache

I am setting a apache environment variable through php function, apache_setenv.
apache_setenv("EXAMPLE_VAR", "Example Value");
But I am having problem accessing this variable inside .htaccess I am not able to use this env variable inside .htaccess in anyway. but I can access it through php getenv().
And problem is not only by setting variable through php I am unable to access env variable set by .htaccess itself.
I've tried
Suppose env variable to be www.domain.com.
RewriteEngine On
RewriteCond ^(.*)$ test.php?id=%{ENV:VARIABLE} [L]
&
RewriteEngine On
RewriteCond %{ENV:VARIABLE} ^www.(.+)
RewriteRule ^ test.php?id=%1 [L]
And similar other test to just verify that env variable are set and functioning.
Mod_env and mod_rewrite is on.

Variable set using SetEnv directives are not seen by mod_rewrite due to sequence of module loading by Apache. Use SetEnvIf instead like that:
SetEnvIf Host ^ VAR=/foo/bin
Then use it in mod_rewrite rules:
RewriteEngine On
RewriteCond %{ENV:VAR} =/foo/bin
RewriteRule ^home/?$ /something [L,NC]

Related

How to add a header if the url contain any get parameter using htaccess file?

I am running PHP in Apache2 server. I would like to add header("X-Robots-Tag: noindex", true); to my pages if the url contains any get parameters like https://example.com/? or https://example.com/a.php? or https://example.com/a.php?key=value. So basically, if the url contain ? charter, the header needs to be added.
Is it possible to do it using .htaccess file and how to do it? Or is there any other way to achieve this?
Ref: https://yoast.com/x-robots-tag-play/
EDIT
Below are the existing rewrite codes;
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteRule ^nps-benchmarks/(.*)$ http://testing.mysite.com.s3-website-us-east-1.amazonaws.com/$1 [P]
RewriteRule ^agency/(.*)$ http://testing.mysite.com.s3-website-us-east-1.amazonaws.com/site/mod1/$1 [P]
RewriteRule ^apps/(.*)$ http://testing.mysite.com.s3-website-us-east-1.amazonaws.com/site/mod2/$1 [P]
RewriteRule ^help-each-other/(.*)$ http://testing.mysite.com.s3-website-us-east-1.amazonaws.com/site/mod3/$1 [P]
RewriteRule ^customers-help-each-other/(.*)$ http://testing.mysite.com.s3-website-us-east-1.amazonaws.com/site/mod4/$1 [P]
RewriteRule ^de/(.*)$ http://testing.mysite.com.s3-website-us-east-1.amazonaws.com/site/multilanguage/de/$1 [P]
RewriteRule ^es/(.*)$ http://testing.mysite.com.s3-website-us-east-1.amazonaws.com/site/multilanguage/es/$1 [P]
RewriteRule ^fr/(.*)$ http://testing.mysite.com.s3-website-us-east-1.amazonaws.com/site/multilanguage/fr/$1 [P]
RewriteRule ^(wp-content/themes/my-site/assets/)(css|js)(/.+)(-v\d+\.\d+)\.(min)\.(js|css)$ $1/$2/$3.$5.$6 [L]
RewriteBase /
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
</IfModule>
like https://example.com/? or https://example.com/a.php?
The issue in these two instances are that the query string is empty, so you can't check for this using the standard QUERY_STRING server variable ("empty" and "not-exists" evaluate to the same thing, ie. empty).
However, you can check for a literal ? (ie. query string delimiter) in the first line of the HTTP request headers, as contained in the THE_REQUEST Apache server variable.
In the case of the first example above, this will contain a string of the form:
GET /? HTTP/1.1
And for /a.php?key=value, this will be:
GET /a.php?key=value HTTP/1.1
We can use mod_rewrite to check this and set an environment variable. Then use the header directive to set the required X-Robots-Tag HTTP response header conditionally based on whether this env var is set.
For example, near the top of the root .htaccess file:
RewriteEngine On
# Check for literal "?" in URL and set QUERY_EXISTS env var
RewriteCond %{THE_REQUEST} \s/.*\?
RewriteRule ^ - [E=QUERY_EXISTS:1]
# Set header if QUERY_EXISTS is set
header set X-Robots-Tag "noindex" env=QUERY_EXISTS
This sets the header on 2xx "OK" responses. It won't, for instance, set the header on a 404 - but 404s are not indexed anyway, so the header is redundant. However, if you specifically need to set the header on all (non-2xx) responses then use the always condition. For example:
# Use "always" to set on non-2xx responses as well
header always set ....
Note that this is also dependent on other directives you might have in your .htaccess file. For example, if you have existing mod_rewrite directives that cause the rewrite engine to "loop" then the env var will be renamed to REDIRECT_QUERY_EXISTS and you will likely need to check for this instead in the header directive.

how to compare the current time to a variable in a .htaccess

I would like to make a redirection after a deadline on my site.
currently everything works correctly if I write this :
RewriteEngine On
SetEnv DEADLINE 16/06/2022_19h30
RewriteCond %{TIME_DAY}/%{TIME_MON}/%{TIME_YEAR}_%{TIME_HOUR}h%{TIME_MIN} >=16/06/2022_19h30
RewriteRule ^index.php$ read_only/index.html [L]
the advantage of using an environment variable is that I can use it elsewhere in a PHP file
So is there a way to test between the current time and the DEADLINE variable?
You can do this but you need to set your variable using SetEnvIf directive, so that it is available for evaluation in .htaccess RewriteCond:
Define this variable first:
SetEnvIf Host ^ DEADLINE=20220616193000
Then use it in .htaccess using RewriteCond expressions:
RewriteEngine On
RewriteCond expr "%{TIME} -ge env('DEADLINE')"
RewriteRule ^index\.php$ read_only/index.html [L,NC]
Due to use of expr in RewriteCond, it will require Apache 2.4+

Can I pick of environment variables inside .htaccess somehow?

I have a set of apache (2.4.25) sites that use mod_vhost_alias so the one vhost services multiple subdomains.
I want to be able to set a environment variable, say
<VirtualHost _default_:443>`
ServerNameAlias *.whatever-it-is.com
SetEnv HOME_URL https://www.whatever-it-is.com/
# etc
then in my various sites .htaccess files pick up that variable. So a site might allow access to a subfolder or a specific file and redirect everything back to the home site.
php_flag engine off
RewriteEngine On
RewriteCond %{REQUEST_URI} ^/?
RewriteCond %{REQUEST_URI} !^/myapp[/]?
RewriteCond %{REQUEST_URI} !^favicon.ico
RewriteRule (.*) %{HOME_URL} [R=301,L]
# ^--- not working, how would you do it?
then in the case where I need to change the home_url across all sites, I can just apply it in the vhost and each of the dozens of subdomain sites will pick it up.
* also tried
RewriteRule (.*) %{ENV:HOME_URL} [R=301,L]
http://httpd.apache.org/docs/2.0/env.html
The %{ENV:variable} form of TestString in the RewriteCond allows mod_rewrite's rewrite engine to make decisions conditional on environment variables...
Use SetEnvIf to set your environment variable so that it is available for mod_rewrite later in .htaccess.
Inside VirtualHost config have it like this:
SetEnvIf Host ^ HOME_URL=https://www.whatever-it-is.com/
Then inside .htaccess have a simple rule:
RewriteEngine On
RewriteRule .* %{ENV:HOME_URL} [R=301,L]
Make sure to clear your browser cache before testing this change.

mod rewrite - set and get env variables

I set env variables in a distributor htaccess file this way:
RewriteCond %{HTTP_HOST} ([^\.]+\.[^\.]+)$
RewriteRule ^(.*)$ %1/$1 [QSA,L,E=DOMAIN:%1,E=URI:$1]
After that apache start to process another htaccess file in the %1 subfolder.
How can I read the ENV:DOMAIN and ENV:URI variables in that htaccess?
I tried with
%{ENV:DOMAIN}
%{ENV:URI}
but those variables are empty...
Try using %{ENV:REDIRECT_DOMAIN} instead. Apache adds the REDIRECT_ prefix before every environment variable, after rewriting.

How to use SetEnv with a URL parameter

I'm trying to implement language switching in .htaccess, and the only thing left now is to handle clients which don't support cookies. To do that, I must set prefer-language when the user clicks a link with a language parameter.
RewriteEngine On
RewriteBase /
RewriteCond %{QUERY_STRING} (?:^|&)language=(en|fr|no)
RewriteRule ^(.*)$ $1? [cookie=language:%1:.example.com,env=language:%1,R]
SetEnv prefer-language $language
The problem is with the last line - The value is always set to empty. It works if I hardcode it, but not if I try to refer to a variable. Is there some special syntax to refer to environment variables in this context, or is there some other way to set prefer-language?
Edit: Cross-posted to Apache users list.
You can set environment variables with mod_rewrite as well. Actually, you already did that (see env/E flag).
I can’t test it with mod_negotiation myself, but the following should work and set the prefer-language:
RewriteCond %{QUERY_STRING} ^((?:[^&]&)*)language=(en|fr|no)&?([^&].*)?$
RewriteRule ^ %{REQUEST_URI}?%1%3 [L,CO=language:%2,R]
RewriteCond %{HTTP_COOKIE} (^|[,\s])language=([^\s,;]+)
RewriteRule ^ - [L,E=prefer-language:%2]
SetEnvIf REDIRECT_prefer-language (.+) prefer-language=$1
But it would be far easier if you put the language identifier into the URL path like /en/…:
SetEnvIf Request_URI ^/(en|fr|no)/ prefer-language=$1
SetEnvIf REDIRECT_prefer-language (.+) prefer-language=$1
I don’t know if you need the additional/second SetEnvIf variable.
Looks like there's no support for variables in SetEnv, but here's a working configuration if someone else is trying to do the same. It's a simpler kind of language selection, since it just copies the language parameter from the referer to the current URL if it's not changed:
RewriteEngine On
RewriteBase /
# Keep the language parameter if specified in the last URL
RewriteCond %{HTTP_REFERER} ^(?:.*[&?])?language=(en|fr|no).*$
RewriteCond %{QUERY_STRING} !^(?:.*&)?language=(en|fr|no).*$
RewriteRule ^(.*)$ $1?language=%1 [redirect=permanent]
# Set the language from the URL parameter
RewriteCond %{QUERY_STRING} ^(?:.*&)?language=(en|fr|no).*$
RewriteRule ^ - [env=prefer-language:%1]
# Cache only when the language parameter is set
<IfDefine !prefer-language>
Header set Vary *
</IfDefine>