The following RewriteRule in my htaccess file isn't getting the request header set.
Header set Access-Control-Allow-Origin "*"
RewriteEngine On
RewriteBase /
RewriteCond %{QUERY_STRING} ^(.*)&someUser=(.*)$
RewriteRule ^(.*)SDM$ http://some.domain.com/SDM/Publish.aspx [E=SOME:%2,R,L]
RequestHeader set Some-User: "%{SOME}e"
I don't think the SOME environment variable has anything to do with it because I tried a generic header value as well and it wasn't set either. I did make sure that mod-headers is installed. I am looking for the header in my chrome developer tools. Is it possible that it won't show up there?
Env variables won't be set while doing external redirect, you must do internal rewrite for setting env variables like this:
Header set Access-Control-Allow-Origin "*"
RewriteEngine On
RewriteBase /
RewriteCond %{QUERY_STRING} (^|&)someUser=([^&]+) [NC]
RewriteRule ^(.*)SDM$ /SDM/Publish.aspx [E=SOME:%2,L]
RequestHeader set Some-User "%{SOME}e"
Related
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.
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]
I'm setting this in my vhost in Apache 2.4
SetEnvIf X-Forwarded-Proto https HTTPS=on
And in my .htaccess I add this rule :
RewriteCond %{HTTPS} off
RewriteRule ^(.*)$ https://%{SERVER_NAME}%{REQUEST_URI} [R=301,L]
but I get an infinit loop since my RewriteCond doesn't see the value of HTTPS.
I do a phpinfo(INFO_VARIABLES); and I get $_SERVER['HTTPS'] on
I had debug in my errorLog to get this RewriteCond: input='off' pattern='off' => matched
As you see the RewriteCond doesn't see the value I set.
I read some doc as
The SetEnv directive runs late during request processing meaning that
directives such as SetEnvIf and RewriteCond will not see the variables
set with it.
or this link : http://www.onlinesmartketer.com/2010/05/27/apache-environment-variables-visibility-with-setenv-setenvif-and-rewriterule-directives/#Summary
And what I did is supposed to work.
What's wrong ?
Thanks ;)
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
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>