Different .htaccess rewrite rules depending on a $_GET param - apache

Is there a way to make different rewrite rules in .htacess if a certain GET parameter was passed?
For example, if query string is:
htttp://domain.com/?debug=1, than .htaccess should look like:
<IfModule mod_rewrite.c>
RewriteEngine on
RewriteRule ^$ app/webroot/ [L]
RewriteRule (.*) app/webroot/$1 [L]
</IfModule>
If there is no debug=1 in query string, than:
RewriteEngine on
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-l
RewriteRule !\.(js|ico|gif|jpg|png|css|html|swf|flv|xml)$ index.php?$1 [QSA,L]

You can use RewriteCond like this:
RewriteEngine on
# ?debug=1 is present
RewriteCond %{QUERY_STRING} (^|&)debug=1\b [NC]
RewriteRule (.*) app/webroot/$1 [L]
# ?debug=1 is not present
RewriteCond %{QUERY_STRING} !(^|&)debug=1\b [NC]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-l
RewriteRule !\.(js|ico|gif|jpg|png|css|html|swf|flv|xml)$ index.php?$1 [QSA,L]

You want to match against the query string in a RewriteCond:
RewriteCond %{QUERY_STRING} ^debug=1$ [NC]
RewriteRule (.*) app/webroot/$1 [L]
For more information, see the docs or this example.

Related

Mod Rewrite stop at rule?

I have the following mod rewrite in my .htaccess and when I go to /commPortal.php it still ends up routing me to index2.php.
RewriteRule ^commportal/(.+)$ commPortal.php?data=$1 [L]
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^ index2.php [QSA,L]
RewriteCond %{REQUEST_URI} \.php [NC]
RewriteRule ^ index2.php [QSA,L]
This seems to be due to RewriteRule ^commportal/(.+)$ commPortal.php?data=$1 [L] then getting picked up by:
RewriteCond %{REQUEST_URI} \.php [NC]
RewriteRule ^ index2.php [QSA,L]
Is there any way to get the RewriteCond %{REQUEST_URI} \.php [NC] to see the commPortal.php rather than /commportal or even have it ignored if there was already a matching rewrite rule?
Change your last rule to this:
RewriteRule ^commportal/(.+)$ commPortal.php?data=$1 [L,QSA,NC]
RewriteRule ^index2\.php$ - [L,NC]
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^ index2.php [L]
RewriteCond %{ENV:REDIRECT_STATUS} ^$
RewriteRule \.php$ index2.php [L,NC]
RewriteCond %{ENV:REDIRECT_STATUS} ^$ condition will be true only if there has been no internal rewrite before this rule thus executing this rule only no other rule has been fired before this.
Another option to use THE_REQUEST variable that contains original request not the rewritten one:
RewriteCond %{THE_REQUEST} !\s/+commportal/ [NC]
RewriteRule \.php$ index2.php [L,NC]
Could you please try following, based on your shown samples only. Please make sure to clear your browser cache before testing your URLs.
RewriteRule ^commportal/(.+)$ commPortal.php?data=$1 [NC,L]
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^ index2.php [QSA,L]
RewriteCond %{REQUEST_URI} !commportal\.php/?$ [NC]
RewriteCond %{REQUEST_URI} \.php [NC]
RewriteRule ^ index2.php [QSA,L]

Multiple RewriteRules for a single set of RewriteConds

We've tried all the suggestions on stackoverflow we could find for adding multiple RewriteRules for the same set of RewriteConds, but in all cases, we're only able to get the first RewriteRule to work.
This is the working code for a single rewrite that we'd like to add more categories to:
<IfModule mod_rewrite.c>
RewriteEngine on
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ /designers/$1 [NC,L]
</IfModule>
None of the below work:
<IfModule mod_rewrite.c>
RewriteEngine on
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ /designers/$1 [NC,L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ /labels/$1 [NC,L]
</IfModule>
<IfModule mod_rewrite.c>
RewriteEngine on
RewriteCond %{REQUEST_FILENAME} !-f [OR]
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule .? - [S=2]
RewriteRule ^(.*)$ /designers/$1 [NC,L]
RewriteRule ^(.*)$ /labels/$1 [NC,L]
</IfModule>
Your [OR] cond is almost correct. When you do a logical invert, you must also negate.
RewriteCond %{REQUEST_FILENAME} -f [OR]
RewriteCond %{REQUEST_FILENAME} -d
RewriteRule .? - [S=2]
RewriteRule ^(.*)$ /designers/$1 [NC,L]
RewriteRule ^(.*)$ /labels/$1 [NC,L]
So you don't want !-f, you want -f. Keep in mind that the S=2 skips 2 rules. If you have more categories you'll need to change that, or just use the L flag instead.

Rewrite htaccess so it doesn't need to repeat itself

I have one big htaccess file that does all the redirects for a site. Here is what I do for each directory:
RewriteRule ^CAKE_MIX/.php$ CAKE_MIX/index.php [R,L]
RewriteRule ^CAKE_MIX$ CAKE_MIX/ [R,L]
RewriteRule CAKE_MIX/faqs.php$ /faqs/faqs.php?cat=CAKE_MIX [QSA]
RewriteRule CAKE_MIX/index.php$ /overview/overview.php?cat=CAKE_MIX [QSA,L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_URI} /CAKE_MIX/*
RewriteRule . /faqs/faqs.php?cat=CAKE_MIX&question=%{REQUEST_URI}
RewriteRule ^COOKIE_DOUGH/.php$ COOKIE_DOUGH/index.php [R,L]
RewriteRule ^COOKIE_DOUGH$ COOKIE_DOUGH/ [R,L]
RewriteRule COOKIE_DOUGH/faqs.php$ /faqs/faqs.php?cat=COOKIE_DOUGH [QSA]
RewriteRule COOKIE_DOUGH/index.php$ /overview/overview.php?cat=COOKIE_DOUGH [QSA,L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_URI} /COOKIE_DOUGH/*
RewriteRule . /faqs/faqs.php?cat=COOKIE_DOUGH&question=%{REQUEST_URI}
And I do this for 18 different directories. How would I rewrite the htaccess to say something like "for any of the following directories: COOKIE_DOUGH, CAKE_MIX,ICE_CREAM, follow these rules?" and then the rules could be like:
RewriteRule ^DIRECTORY/.php$ DIRECTORY/index.php [R,L]
And would only have to be written once? Is that possible?
You can use regex alternation:
RewriteRule ^(CAKE_MIX|COOKIE_DOUGH|ICE_CREAM)/\.php$ $1/index.php [R,L]
RewriteRule ^(CAKE_MIX|COOKIE_DOUGH|ICE_CREAM)$ $1/ [R,L]
RewriteRule (CAKE_MIX|COOKIE_DOUGH|ICE_CREAM)/faqs\.php$ /faqs/faqs.php?cat=$1 [QSA]
RewriteRule (CAKE_MIX|COOKIE_DOUGH|ICE_CREAM)/index\.php$ /overview/overview.php?cat=$1 [QSA,L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_URI} /(CAKE_MIX|COOKIE_DOUGH|ICE_CREAM)/
RewriteRule . /faqs/faqs.php?cat=%1&question=%{REQUEST_URI}

htaccess mod_rewrite: Simplifying URL

I've been having trouble with the following rewrite. I'm certain mod_rewrite is enabled but not sure where I am going wrong.
I'm try to change the following pattern:
/profile/?userid=157&username=FirstL
to:
/profile/FirstL
I've tried many different rules, but the two I felt were the closest to being correct aren't working at all. My current failures below:
RewriteEngine On
RewriteCond %{THE_REQUEST} \ /profile/+\?userid=$([^&\ ]+)&username=$([^&\ ]+)
RewriteRule ^ /%1? [L,R=301]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^([^/]+)$ /profile/?userid=$1&username=$2 [L,QSA]
 
RewriteEngine On
RewriteRule ^([^/]*)$ /profile/?userid=$1&username=$2 [L]
Full htaccess:
Options +FollowSymLinks -Multiviews
RewriteEngine On
RewriteCond %{THE_REQUEST} \ /profile/+\?userid=$([^&\ ]+)&username=$([^&\ ]+)
RewriteRule ^ /profile/%1/%2? [L,R=301]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^profile/([^/]+)/([^/]+)$ /profile/?userid=$1&username=$2 [L,QSA]
RewriteBase /
DirectorySlash Off
RewriteRule ^admin$ /admin/index.php [L,E=LOOP:1]
RewriteCond %{ENV:REDIRECT_LOOP} !1
RewriteRule ^admin/index.php$ /admin [R=301,L]
# remove .php
RewriteCond %{THE_REQUEST} ^GET\ (.*)\.php\ HTTP
RewriteRule (.*)\.php$ $1 [R=301]
# remove index
RewriteRule (.*)/index$ $1/ [R=301]
# remove slash if not directory
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_URI} /$
RewriteRule (.*)/ $1 [R=301]
# add .php to access file, but don't redirect
RewriteCond %{REQUEST_FILENAME}.php -f
RewriteCond %{REQUEST_URI} !/$
RewriteRule (.*) $1\.php [L]
#Force non-www:
RewriteCond %{HTTP_HOST} www.(.*)$ [NC]
RewriteRule ^(.*)$ http://%1/$1 [R=301,L]
You're losing the userID part of the URL, so when you try to internally rewrite that back, there's nothing there:
RewriteRule ^([^/]+)$ /profile/?userid=$1&username=$2 [L,QSA]
This rule says the first match is the "userid" and the second match is the "username", and you only have one match, and on top of that, it doesn't even begin with "profile".
You'll need to include the userid somewhere in the URL, otherwise there's no way to extract it.
RewriteEngine On
RewriteCond %{THE_REQUEST} \ /profile/+\?userid=([^&\ ]+)&username=([^&\ ]+)
RewriteRule ^ /profile/%1/%2? [L,R=301]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^profile/([^/]+)/([^/]+)$ /profile/?userid=$1&username=$2 [L,QSA]

mod_rewrite rule keeps in loop

I am doing a quite simple rule for mod_rewrite yet I get a loop
Here are the rules:
first if I have a request like
index.php/SOMETHING.(txt,jpg,php)
I need to first check if /SOMETHING.(txt,jpg,png) exists and display it
if the file is not an index.php/SOMETING and is a real path that exists display it
if not...pass it on to the index.php/SOMETHING.(txt,jpg,php) and show index.php
It all works but the last rule if I have a unexistent txt,jpg,php
example : http://domain.com/index.php/robots1.txt
File does not exist: /Applications/XAMPP/xamppfiles/htdocs/testredir/robots1.txt
works for any other extension...
RewriteEngine On
RewriteBase /
RewriteCond %{REQUEST_URI} ^index.php/.+$
RewriteRule ^index.php/(.+)\.jpg$ $1.jpg [NC,L]
RewriteRule ^index.php/(.+)\.txt$ $1.txt [NC,L]
RewriteRule ^index.php/(.+)\.php$ $1.php [NC,L]
#here I am missing a rule but if i put the following it will loop
#RewriteCond %{REQUEST_URI} -f
#RewriteRule .* index.php/$0 [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_URI} ^index.php/.+$
RewriteRule .* index.php/$0 [PT]
The %{REQUEST_URI} variable always starts with a /, and you're matching against it using ^index.php/.+$, so that condition will always be false.
It looks like you want something like this:
RewriteEngine On
RewriteBase /
RewriteCond %{THE_REQUEST} \ /index\.php/(.+)\.(jpg|txt|php)
RewriteRule ^ /%1.%2 [L,R=301]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-l
RewriteRule ^(.*)$ index.php/$1 [L,PT]