My application used to do language switching using a lang.php file. A URL to redirect to English for /path/to/page.php?foo=bar would look like this:
/path/to/lang.php?lang=en-CA&uri=%2Fpath%2Fto%2Fpage.php%3Ffoo%3Dbar
Recently there has been some changes to accept a lang query parameter on all pages. So this URL is nicer:
/path/to/page.php?foo=bar&lang=en-CA
I'd like to be able to add a .htaccess file to all the locations that I have a lang.php file in order to keep the existing URL working without the lang.php file. Is this possible?
The RewriteRules must be completely relative to lang.php as the application is running on different hostnames and paths.
I took a stab at it based on the answer here but this is giving me a 404:
RewriteCond %{REQUEST_FILENAME} lang.php$
RewriteCond %{QUERY_STRING} (?:^|&)uri=([^&]+) [NC]
RewriteRule lang.php - [E=LANG_REDIR_URI:%1]
RewriteCond %{REQUEST_FILENAME} lang.php$
RewriteCond %{QUERY_STRING} (?:^|&)lang=([^&]+) [NC]
RewriteRule lang.php - [E=LANG_REDIR_LANG:%1]
RewriteCond %{REQUEST_FILENAME} lang.php$
RewriteRule . %{LANG_REDIR_URI}e [L,R=temporary]
The uri parameter may already have query parameters (as in the examble above), and the code should not make the application vulnerable to an open redirect vulnerability.
Different cases:
- URI with query string, lang first:
/foo/bar/lang.php?lang=en-CA&uri=%2Ffoo%2Fbar%2Fpage.php%3Fid%3D123should redirect to/foo/bar/page.php?id=123&lang=en-CA - URI without query string, lang first:
/foo/bar/lang.php?lang=en-CA&uri=%2Ffoo%2Fbar%2Fpage.phpshould redirect to/foo/bar/page.php?lang=en-CA - URI with query string, uri first:
/foo/bar/lang.php?uri=%2Ffoo%2Fbar%2Fpage.php%3Fid%3D123&lang=en-CAshould redirect to/foo/bar/page.php?id=123&lang=en-CA - URI without query string, uri first:
/foo/bar/lang.php?uri=%2Ffoo%2Fbar%2Fpage.php&lang=en-CAshould redirect to/foo/bar/page.php?lang=en-CA
The order of the query parameters do not matter in the redirect target.
UPDATE
After the initial answer provided at https://stackoverflow.com/a/45732670/404623, I've tried the following .htaccess rules:
# This only works for uri values without query strings
RewriteCond %{QUERY_STRING} ^(lang=[^&]+)&uri=([^&]+) [NC]
RewriteRule lang\.php$ /%2\?%1 [L,NE,R=temporary]
RewriteCond %{QUERY_STRING} ^uri=([^&]+)&(lang=[^&]+) [NC]
RewriteRule lang\.php$ /%1\?%2 [L,NE,R=temporary]
# This only works for uri values with query strings
RewriteCond %{QUERY_STRING} ^(lang=[^&]+)&uri=([^&]+) [NC]
RewriteRule lang\.php$ /%2&%1? [L,NE,R=temporary]
RewriteCond %{QUERY_STRING} ^uri=([^&]+)&(lang=[^&]+) [NC]
RewriteRule lang\.php$ /%1&%2? [L,NE,R=temporary]
%2Fis not allowed in Apache unless you have usedAllowEncodedSlashesin Apache server config.