Apache2, mod_rewrite - use variable from prev condition in next condition - apache

I would like to check if file exist in subdirectory.
And I mean subdirectory that "is taken" from "subdomain".
Eg. url: "test.domain.com/file.txt" file location is "/test/file.txt"
I have wildacrd and i can't hardcode "test" directory. How can i do it?
I tried add %{DOCUMENT_ROOT}%1/$1 but this dosen't work.
Options +FollowSymLinks -MultiViews
RewriteEngine On
RewriteCond %{ENV:REDIRECT_STATUS} ^$
RewriteCond %{HTTP_HOST} !^www\.
RewriteCond %{HTTP_HOST} ^([^.]+)\.domain.com
RewriteCond %{DOCUMENT_ROOT}%1/$1 -f [OR]
RewriteCond %{DOCUMENT_ROOT}%1/$1 -d
RewriteRule ^ /%1%{REQUEST_URI} [L]
RewriteCond %{ENV:REDIRECT_STATUS} ^$
RewriteCond %{HTTP_HOST} !^www\.
RewriteCond %{HTTP_HOST} ^([^.]+)\.domain.com
RewriteRule ^images/(.*)$ /%1/image.php?test=$1 [L]

With your shown samples, please try following. Please make sure to clear your browser cache before testing your URLs.
Options +FollowSymLinks -MultiViews
RewriteEngine ON
RewriteCond %{ENV:REDIRECT_STATUS} ^$
RewriteCond %{HTTP_HOST} !^www\. [NC]
RewriteCond %{HTTP_HOST} ^([^.]+)\.domain.com [NC]
RewriteCond %{DOCUMENT_ROOT}/%1/$1 -f [OR]
RewriteCond %{DOCUMENT_ROOT}/%1/$1 -d
RewriteRule ^(.*)/?$ %1/$1 [L]
RewriteCond %{HTTP_HOST} !^www\. [NC]
RewriteCond %{HTTP_HOST} ^([^.]+)\.domain.com [NC]
RewriteRule ^images/(.*)/?$ %1/image.php?test=$1 [QSA,NC,L]
Fixes in OP's attempts: You need not to use condition RewriteCond %{ENV:REDIRECT_STATUS} ^$ in 2nd Rules sets, even first one may not need it but for safer side you can have it. Then your sequence of accessing path from %{DOCUMENT_ROOT} was not correct which was corrected here.

Related

.htaccess won't rewrite my url at all

I've been crawling forums for about 2 hours and still haven't found the solution to my problem so I am turning to you guys for help.
My URL looks like this
http://gymbirdz.com/article.php?url=benefits-of-fish-oil
I want it to look like this
http://gymbirdz.com/article/benefits-of-fish-oil
This is my .htaccess request but It does not work and still no luck fixing it :/
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^/?article/([A-Za-z0-9-]+)/?$ /article.php?url=$1 [NC,R=301,L]
Any help is appreciated very much! Thank You
UPDATE
This is how my .htaccess looks from above
Options +FollowSymLinks
RewriteEngine On
RewriteRule ^article/([A-Za-z0-9\-]+)$ article.php?url=$1 [NC,R=301,L,QSA]
RewriteCond %{THE_REQUEST} ^GET.*index\.php [NC]
RewriteCond %{REQUEST_URI} !/system/.* [NC]
RewriteRule (.*?)index\.php/*(.*) /$1$2 [R=301,NE,L]
RewriteCond %{HTTP_HOST} ^www\.gymbirdz\.com$
RewriteRule ^/?$ "http\:\/\/gymbirdz\.com\/" [R=301,L]
RewriteCond %{HTTP_HOST} ^192\.254\.185\.208
RewriteRule (.*) http://www.gymbirdz.com/$1 [R=301,L]
RewriteCond %{HTTP_USER_AGENT} libwww-perl.*
RewriteRule .* ? [F,L]
Try this rule your site root .htaccess:
Options +FollowSymLinks -MultiViews
RewriteEngine On
RewriteCond %{HTTP_USER_AGENT} libwww-perl [NC]
RewriteRule ^ - [F,L]
RewriteCond %{HTTP_HOST} ^www\.gymbirdz\.com$ [OR]
RewriteCond %{HTTP_HOST} ^192\.254\.185\.208$
RewriteRule (.*) http://gymbirdz.com/$1 [R=301,NE,L]
RewriteCond %{THE_REQUEST} ^GET.*index\.php [NC]
RewriteCond %{REQUEST_URI} !/system/.* [NC]
RewriteRule (.*?)index\.php/*(.*) /$1$2 [R=301,NE,L]
RewriteCond %{THE_REQUEST} /article\.php\?url=([^\s&]+) [NC]
RewriteRule ^ /article/%1? [R=302,L,NE]
RewriteRule ^/?article/([\w-]+)/?$ article.php?url=$1 [NC,QSA,L]
Maybe I don't understand your question, but this is from the documentation:
Syntax: RewriteRule Pattern Substitution [flags]
This is your rule:
RewriteRule ^/?article/([A-Za-z0-9-]+)/?$ /article.php?url=$1 [NC,R=301,L]
It appears that you may have the two arguments reversed. Try something like this instead:
RewriteRule ^article.php?url=([\w-]+) /article/$1 [NC,L,R=301,QSA]
This assumes that the .htaccess file is in the same directory as article.php.

Multi-Country Using .htacces

I am trying to achieve any one of the following:
http://ca.domain.com/Category/SubCategory -> http://www.domain.com/index.php?country=ca&category=Category&subcategory=Subcategory
http://www.domain.com/ca/Category/SubCategory -> http://www.domain.com/index.php?country=ca&category=Category&subcategory=Subcategory
I have browsed around but unfortunately haven't been able to figure out any working solution. For the first kind I tried the following code:
Options +FollowSymLinks
RewriteEngine on
RewriteCond %{HTTP_HOST} ^([^.]+)\.domain\.com
RewriteRule ^(.*)/$ http://www.domain.com/index.php&country=%1&category=$1 [L]
The issue with sub domain is that it doesn't redirect anywhere at all. I read around and it says I need to setup wildcard virtual host. I haven't been able to figure out how to do that on godaddy. So not sure how to do it.
As for the second kind, I used the following code:
RewriteEngine on
RewriteRule ^(.*)/?(.*)/ home.php?country=$1&category=$2 [B]
But that didn't work for me either. Any help in this regard would be highly appreciated. Thank you
As for Category & Subcategory, Subcategory is kind of mandatory. So it should also work for following link:
http://www.domain.com/ca/Toronto/Programming -> http://www.domain.com/index.php?country=ca&location=Toronto&subcategory=Programming
http://www.domain.com/ca/Programming -> http://www.domain.com/index.php?country=ca&location=&subcategory=Programming
I am not quite sure as to how to tell .htaccess if it is $1=subcategory or $2=subcategory since they switch in scenario 1 & 2.
Thanks to immense help from #anubhava I have reached to the following:
Options +FollowSymLinks
RewriteEngine on
RewriteBase /
RewriteCond %{REQUEST_FILENAME} -f [OR]
RewriteCond %{REQUEST_FILENAME} -d
RewriteRule ^ - [L]
RewriteCond %{HTTP_HOST} ^((?!www\.)[^.]+)\.domain\.com$ [NC]
RewriteRule ^([^/]+)/?$ adlisting.php?country=%1&category=$1 [L,QSA]
RewriteCond %{HTTP_HOST} ^((?!www\.)[^.]+)\.domain\.com$ [NC]
RewriteRule ^([^/]+)/([^/]+)/?$ adlisting.php?country=%1&location=$1&category=$2 [L,QSA]
RewriteCond %{HTTP_HOST} ^(www\.)?\.domain\.com$ [NC]
RewriteRule ^([a-z]{2})/([^/]+)/?$ adlisting.php?country=$1&category=$2 [L,QSA,NC]
RewriteCond %{HTTP_HOST} ^(www\.)?\.domain\.com$ [NC]
RewriteRule ^([a-z]{2})/([^/]+)/([^/]+)/?$ adlisting.php?country=$1&category=$2&subcategory=$3 [L,QSA,NC]
Have these rules in root .htaccess:
Options +FollowSymLinks
RewriteEngine on
RewriteBase /
RewriteCond %{REQUEST_FILENAME} -f [OR]
RewriteCond %{REQUEST_FILENAME} -d
RewriteRule ^ - [L]
RewriteCond %{HTTP_HOST} ^((?!www\.)[^.]+)\.domain\.com$ [NC]
RewriteRule ^([^/]+)/?$ index.php?country=%1&category=$1 [L,QSA]
RewriteCond %{HTTP_HOST} ^((?!www\.)[^.]+)\.domain\.com$ [NC]
RewriteRule ^([^/]+)/([^/]+)/?$ index.php?country=%1&category=$1&subcategory=$2 [L,QSA]
RewriteCond %{HTTP_HOST} ^(www\.)?domain\.com$ [NC]
RewriteRule ^([a-z]{2})/([^/]+)/?$ index.php?country=$1&category=$2 [L,QSA,NC]
RewriteCond %{HTTP_HOST} ^(www\.)?domain\.com$ [NC]
RewriteRule ^([a-z]{2})/([^/]+)/([^/]+)/?$ index.php?country=$1&category=$2&subcategory=$3 [L,QSA,NC]

Htaccess recursive file rewrite

I would like to know if there is a better way to achieve this sort or redirection :
# Apache configuration
Options -Indexes
Options +FollowSymLinks
# Rewrite engine configuration
RewriteEngine On
RewriteBase /
# Force domain www (302 redirect)
RewriteCond %{HTTP_HOST} ^([^\.]+\.[^\.0-9]+)$
RewriteRule ^/?(.*)$ http://www.%1/$1 [L,R=302]
# Request redirection (/module/TLD/module/DOMAIN/module/SUB/data/public/...)
RewriteCond %{REQUEST_URI} !^/index.php
RewriteCond %{HTTP_HOST} ^(.+)\.([^\.]+)\.([^\.0-9]+)$
RewriteCond %{DOCUMENT_ROOT}/module/%3/module/%2/module/%1/data/public/%{REQUEST_URI} -f
RewriteRule ^/?(.+)$ /module/%3/module/%2/module/%1/data/public/$1 [L]
RewriteCond %{REQUEST_URI} !^/index.php
RewriteCond %{HTTP_HOST} ^(.+)\.([^\.]+)\.([^\.0-9]+)$
RewriteCond %{DOCUMENT_ROOT}/module/%3/module/%2/module/%1/data/public/%{REQUEST_URI}/index.php -f
RewriteRule ^/?(.+)/?$ /module/%3/module/%2/module/%1/data/public/$1/index.php [L]
RewriteCond %{REQUEST_URI} !^/index.php
RewriteCond %{HTTP_HOST} ^(.+)\.([^\.]+)\.([^\.0-9]+)$
RewriteCond %{DOCUMENT_ROOT}/module/%3/module/%2/module/%1/data/public/%{REQUEST_URI}/index.html -f
RewriteRule ^/?(.+)/?$ /module/%3/module/%2/module/%1/data/public/$1/index.html [L]
RewriteCond %{REQUEST_URI} !^/index.php
RewriteCond %{HTTP_HOST} ^(.+)\.([^\.]+)\.([^\.0-9]+)$
RewriteCond %{DOCUMENT_ROOT}/module/%3/module/%2/module/%1/data/public/index.php -f
RewriteRule ^/?$ /module/%3/module/%2/module/%1/data/public/index.php [L]
RewriteCond %{REQUEST_URI} !^/index.php
RewriteCond %{HTTP_HOST} ^(.+)\.([^\.]+)\.([^\.0-9]+)$
RewriteCond %{DOCUMENT_ROOT}/module/%3/module/%2/module/%1/data/public/index.html -f
RewriteRule ^/?$ /module/%3/module/%2/module/%1/data/public/index.html [L]
# Request redirection (/module/TLD/module/DOMAIN/data/public/...)
RewriteCond %{REQUEST_URI} !^/index.php
RewriteCond %{HTTP_HOST} ^.+\.([^\.]+)\.([^\.0-9]+)$
RewriteCond %{DOCUMENT_ROOT}/module/%2/module/%1/data/public/%{REQUEST_URI} -f
RewriteRule ^/?(.+)$ /module/%2/module/%1/data/public/$1 [L]
RewriteCond %{REQUEST_URI} !^/index.php
RewriteCond %{HTTP_HOST} ^.+\.([^\.]+)\.([^\.0-9]+)$
RewriteCond %{DOCUMENT_ROOT}/module/%2/module/%1/data/public/%{REQUEST_URI}/index.php -f
RewriteRule ^/?(.+)/?$ /module/%2/module/%1/data/public/$1/index.php [L]
RewriteCond %{REQUEST_URI} !^/index.php
RewriteCond %{HTTP_HOST} ^.+\.([^\.]+)\.([^\.0-9]+)$
RewriteCond %{DOCUMENT_ROOT}/module/%2/module/%1/data/public/%{REQUEST_URI}/index.html -f
RewriteRule ^/?(.+)/?$ /module/%2/module/%1/data/public/$1/index.html [L]
RewriteCond %{REQUEST_URI} !^/index.php
RewriteCond %{HTTP_HOST} ^.+\.([^\.]+)\.([^\.0-9]+)$
RewriteCond %{DOCUMENT_ROOT}/module/%2/module/%1/data/public/index.php -f
RewriteRule ^/?$ /module/%2/module/%1/data/public/index.php [L]
RewriteCond %{REQUEST_URI} !^/index.php
RewriteCond %{HTTP_HOST} ^.+\.([^\.]+)\.([^\.0-9]+)$
RewriteCond %{DOCUMENT_ROOT}/module/%2/module/%1/data/public/index.html -f
RewriteRule ^/?$ /module/%2/module/%1/data/public/index.html [L]
# Request redirection (/module/TLD/data/public/...)
RewriteCond %{REQUEST_URI} !^/index.php
RewriteCond %{HTTP_HOST} ^.+\.([^\.0-9]+)$
RewriteCond %{DOCUMENT_ROOT}/module/%1/data/public/%{REQUEST_URI} -f
RewriteRule ^/?(.+)$ /module/%1/data/public/$1 [L]
RewriteCond %{REQUEST_URI} !^/index.php
RewriteCond %{HTTP_HOST} ^.+\.([^\.0-9]+)$
RewriteCond %{DOCUMENT_ROOT}/module/%1/data/public/%{REQUEST_URI}/index.php -f
RewriteRule ^/?(.+)/?$ /module/%1/data/public/$1/index.php [L]
RewriteCond %{REQUEST_URI} !^/index.php
RewriteCond %{HTTP_HOST} ^.+\.([^\.0-9]+)$
RewriteCond %{DOCUMENT_ROOT}/module/%1/data/public/%{REQUEST_URI}/index.html -f
RewriteRule ^/?(.+)/?$ /module/%1/data/public/$1/index.html [L]
RewriteCond %{REQUEST_URI} !^/index.php
RewriteCond %{HTTP_HOST} ^.+\.([^\.0-9]+)$
RewriteCond %{DOCUMENT_ROOT}/module/%1/data/public/index.php -f
RewriteRule ^/?$ /module/%1/data/public/index.php [L]
RewriteCond %{REQUEST_URI} !^/index.php
RewriteCond %{HTTP_HOST} ^.+\.([^\.0-9]+)$
RewriteCond %{DOCUMENT_ROOT}/module/%1/data/public/index.html -f
RewriteRule ^/?$ /module/%1/data/public/index.html [L]
# Request redirection (/data/public/...)
RewriteCond %{REQUEST_URI} !^/index.php
RewriteCond %{DOCUMENT_ROOT}/data/public/%{REQUEST_URI} -f
RewriteRule ^/?(.+)$ /data/public/$1 [L]
RewriteCond %{REQUEST_URI} !^/index.php
RewriteCond %{DOCUMENT_ROOT}/data/public/%{REQUEST_URI}/index.php -f
RewriteRule ^/?(.+)/?$ /data/public/$1/index.php [L]
RewriteCond %{REQUEST_URI} !^/index.php
RewriteCond %{DOCUMENT_ROOT}/data/public/%{REQUEST_URI}/index.html -f
RewriteRule ^/?(.+)/?$ /data/public/$1/index.html [L]
RewriteCond %{REQUEST_URI} !^/index.php
RewriteCond %{DOCUMENT_ROOT}/data/public/index.php -f
RewriteRule ^/?$ /data/public/index.php [L]
RewriteCond %{REQUEST_URI} !^/index.php
RewriteCond %{DOCUMENT_ROOT}/data/public/index.html -f
RewriteRule ^/?$ /data/public/index.html [L]
# Request redirection (main index file)
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^ /index.php [L,PT]
For exemple, i redirect a request like http://www.testdomain.com/test/file.css to these possibles paths :
/module/com/module/testdomain/module/www/data/public/test/file.css
/module/com/module/testdomain/data/public/test/file.css
/module/com/data/public/test/file.css
/data/public/test/file.css
If none of these paths are correct, i fall back to /index.php. And, for a request with empty uri, i try to dispatch it like http://www.testdomain.com/index.html or http://www.testdomain.com/index.php. Is there a better way to achieve this sort of rewriting ?
What you are trying to do is verbose and somewhat bizarre, and the bizarre nature is what caught my interest. :-) However, I assume that you must have your reasons.
One advantage of being verbose is that you can define exactly what you want to achieve and in one .htaccess file, so if it aint' broke ... Though you are doing quite a few regexp and stat probes in this logic chain, so I am nore sure that I would recommend this as a general approach.
Also any 'options' would also impact the semantics of what you are trying to achieve, but you could use the recursive nature of the rewrite engine to advantage, for example if /module/TLD/module/DOMAIN/module/SUB/data/public/ then the URI must be interpreted in that context, hence something like
# If we have a file match, then we're done
RewriteCond %{REQUEST_FILENAME} -f
RewriteRule ^ - [L]
# Skip the four directory rewrites except on first pass
RewriteCond %{ENV:REDIRECT_PASS} !=""
RewriteRule ^ - [E:PASS=OK, SKIP=5]
RewriteRule ^ - [E:PASS=OK]
# Redirect to correct subdirectory
RewriteCond %{HTTP_HOST} ^(.+)\.([^.]+)\.([^.\d]+)$
RewriteCond %{DOCUMENT_ROOT}/module/%3/module/%2/module/%1/data/public/ -d
RewriteRule ^.*$ /module/%3/module/%2/module/%1/data/public/$0 [L]
RewriteCond %{HTTP_HOST} ^.+\.([^.]+)\.([^.\d]+)$
RewriteCond %{DOCUMENT_ROOT}/module/%2/module/%1/data/public/ -d
RewriteRule ^.*$ /module/%2/module/%1/data/public/$0 [L]
RewriteCond %{HTTP_HOST} ^.+\.([^.\d]+)$
RewriteCond %{DOCUMENT_ROOT}/module/%1/data/public/ -d
RewriteRule ^.*$ /module/%1/data/public/$0 [L]
RewriteRule ^.*$ /data/public/$0 [L]
# Etc ... your URIs now include the correct prefix.
Note
A bare ^ always matches
A bare - in the subst string means leave unchanged
Don't include leading / in PER_DIR (eg. .htaccess patterns
$0 is the entire match string -- saves using brackets if you want the whole thing
You don't need to escape . inside a [] selector.
Read up on setting and using environment variables. If you set the variable PASS then this appears as REDIRECT_PASS after an internal redirect.
You will also need to enable rewrite logging and go through your logs to debug this. Have fun.

Apache .hatccess rewrites not working for legacy URLS

I'm trying to rewrite some legacy Joomla URLs on a site that's now using ExpressionEngine as its CMS but they're not working.
The ExpressionEngine URL rewrites, i.e. removing index.php from the URL work fine though.
This is what I've got:
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteCond %{HTTPS} !=on
# This is the one that's not working
RewriteRule /index.php?option=com_chronocontact&Itemid=54 /contact/ [R=301,L]
# Force www
RewriteCond %{HTTP_HOST} !^www\..+$ [NC]
RewriteCond %{HTTP_HOST} (.+)$ [NC]
RewriteRule ^(.*)$ http://www.%1/$1 [R=301,L]
# Redirect index.php Requests
RewriteCond %{THE_REQUEST} ^[^/]*/index\.php [NC]
RewriteCond %{THE_REQUEST} ^GET
RewriteRule ^index\.php(.+) $1 [R=301,L]
# Standard ExpressionEngine Rewrite
RewriteCond %{REQUEST_URI} ^/
RewriteCond %{QUERY_STRING} ^(gclid=.*)
RewriteRule ^(.+) /index.php?/ [L,PT]
RewriteCond $1 !\.(css|js|gif|jpe?g|png) [NC]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond $1 !^(assets|css|images|tinymce|js|min|cms|themes|index\.php|admin\.php|favicon\.ico|index\.php|path\.php|php\.ini) [NC]
RewriteRule ^(.+) /index.php?/ [L]
</IfModule>
Can anyone spot what I'm doing wrong?
The first thing is the stray RewriteCond %{HTTPS} !=on that you have at the top. It looks like it belongs to the rule under it, as in:
RewriteCond %{HTTPS} !=on
RewriteCond %{HTTP_HOST} !^www\..+$ [NC]
RewriteCond %{HTTP_HOST} (.+)$ [NC]
RewriteRule ^(.*)$ http://www.%1/$1 [R=301,L]
As far as the rule that you have commented that doesn't work, the ? is a reserved character for regular expressions, and your pattern actually says that the second p in /index.php is "optional". Additionally, you can't match against the query string in a rewrite rule, you need to use a rewrite condition and match against the %{QUERY_STRING} variable:
RewriteCond %{QUERY_STRING} ^option=com_chronocontact&Itemid=54$
RewriteRule ^(index.php)?$ /contact/? [R=301,L]
is probably more along the lines of what you're looking for.

How to Use RewriteCond BackReferencing %N

I have the following rules in my httpd.conf
RewriteEngine on
RewriteBase /
RewriteCond %{QUERY_STRING} password=*
RewriteCond %{QUERY_STRING} bi2=(.*)
RewriteCond %{REQUEST_URI} /myGet.php(.*)$
RewriteRule ^(.*)$ http://blog.myexample%1.com/$1
However, when I executed the Request URI
/myGet.php?password=john&bi2=67
I was redirected to
http://blog.myexample.com/myGet.php?password=john&bi2=67
instead of
http://blog.myexample67.com/myGet.php?password=john&bi2=67
It seems that %N for the RewriteCond BackReferencing is not working. Although $N is.
Alter the order or the RewriteCond directives so that the last directive is the one you want the information from:
RewriteCond %{QUERY_STRING} password=*
RewriteCond %{REQUEST_URI} /myGet.php(.*)$
RewriteCond %{QUERY_STRING} bi2=(.*)
RewriteRule ^(.*)$ http://blog.myexample%1.com/$1
But I rather suggest:
RewriteCond %{QUERY_STRING} password=
RewriteCond %{QUERY_STRING} bi2=([^&]*)
RewriteRule ^/myGet\.php.*$ http://blog.myexample%1.com$0