Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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.

like image 782
l0b0 Avatar asked Aug 14 '09 21:08

l0b0


People also ask

How do you assign a variable to a URL?

To add a URL variable to each link, go to the Advanced tab of the link editor. In the URL Variables field, you will enter a variable and value pair like so: variable=value.

What is Setenv in Apache?

SetEnv DirectiveSets an internal environment variable, which is then available to Apache HTTP Server modules, and passed on to CGI scripts and SSI pages.


2 Answers

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.

like image 163
Gumbo Avatar answered Oct 20 '22 01:10

Gumbo


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>
like image 39
l0b0 Avatar answered Oct 20 '22 00:10

l0b0