Multiple RewriteRule - .htaccess

I would like to have multiple RewriteRules in my .htaccess file.
# Enable Rewriting
RewriteEngine on
# Rewrite profile urls
# Input: /user<userId>
# Output: /profile.php?id=<userId>
RewriteRule ^user(\d+)/?$ profile.php?id=$1 [L]
# Rewrite by default to redirect.php
RewriteRule .* redirect.php
Every requests points to redirect.php
I thought, with the [L] flag in the first RewriteRule, would stop processing the rule set.

If you would like to rewrite /user<userId> to /profile.php?id=<userId> and rewrite the other URLs to /redirect.php, then you could try these two configuration directives:
RewriteEngine on
RewriteRule ^user([a-zA-Z0-9_-]+)/?$ /profile.php?id=$1 [L]
RewriteRule .* /redirect.php
OR:
RewriteEngine on
RewriteRule ^user([a-zA-Z0-9_-]+)/?$ /profile.php?id=$1 [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule .* /redirect.php

Adding the following to the second RewriteRule works.
# Rewrite by default to redirect.php
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule .* redirect.php
But im not sure, why this is needed.

[L] flag stops processing only in current iteration but mod_rewrite repeat process until path will not be constant.
In your case I think you can use this rule:
RewriteRule ^user\d+$ profile.php
RewriteCond %{REQUEST_URI} !profile.php
RewriteRule ^.*$ redirect.php

Related

adding .php extension if not exist

I have the below rewrite but I want to replace the URL without extension .php if the user types the URL with .php at last, how can I revise the below rewrite script?
# /m/yyy rule
RewriteRule ^m/([\w-]+)/?$ merchants/$1/index.php [L,NC]
# /m/yyy/abc rule
RewriteRule ^m/([\w-]+)/([\w-]+)$ merchants/$1/$2.php [L,NC]
# /m/yyy/abc/ rule
RewriteRule ^m/([\w-]+)/([\w-]+)/$ merchants/$1/$2/index.php [L,NC]
With your shown samples, please have your .htaccess file with following Rules. Please make sure to clear your browser cache before testing your URLs.
RewriteEngine ON
# metchants/yyy/index.php to redirect /m/yyy rule
RewriteRule ^merchants/([\w-]+)/index\.php/?$ m/$1 [R=301,L,NC]
# merchants/yyy/abc.php to redirect /m/yyy/abc rule
RewriteRule ^merchants/([\w-]+)([\w-]+)\.php/?$ m/$1/$2 [R=301,L,NC]
# merchants/yyy/xyz/abc.php to redirect /m/yyy/xyz/abc rule
RewriteRule ^merchants/([\w-]+)/([\w-]+)/index\.php/?$ m/$1/$2 [R=301,L,NC]
# To handle /m/yyy/index.php rewrite rule.
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^m/([\w-]+)/?$ merchants/$1/index.php [QSA,L,NC]
# To handle /m/yyy/abc/index.php rewrite rule.
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^m/([\w-]+)/([\w-]+)$ merchants/$1/$2.php [QSA,L,NC]
# To handle /m/yyy/xyz/abc/index.php rewrite rule.
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^m/([\w-]+)/([\w-]+)/$ merchants/$1/$2/index.php [QSA,L,NC]

generic solution for Rewriteurl for all URL's [duplicate]

My website runs a script called -> WSS wallpaper script
My Problem -> I have been trying to force remove or add trailing slash to the end of my URL to prevent duplicated content and also to clean up my URLs.
I have tried all sorts and tried everything I could think of and loads from the interwebs but no such luck yet! It might be a quick fix but I have looked at it so much I am probably blind to something dead obvious.
So I present you with all my .htaccess code:
DirectoryIndex index.php
RewriteEngine on
RewriteRule ^download/([0-9]+)?/([0-9]+)x([0-9]+)/([^/\.]+) image.php?id=$1&width=$2&height=$3&cropratio=$4&download=1 [L]
RewriteRule ^file/([0-9]+)?/([0-9]+)x([0-9]+)/([^/\.]+) image.php?id=$1&width=$2&height=$3&cropratio=$4 [L]
RewriteRule ^preview/([0-9]+)?/([0-9]+)x([0-9]+)/([^/\.]+) wallpaper_preview.php?id=$1&width=$2&height=$3&name=$4 [L]
RewriteRule ^thumbnail/([0-9]+)?/([0-9]+)x([0-9]+)/([^/\.]+)/([^/\.]+)/([^/\.]+)/([^/]+) image.php?wallpaper_id=$1&width=$2&height=$3&cropratio=$4&align=$5&valign=$6&file=$7 [L]
RewriteRule ^cat/([0-9]+)?/([^/\.]+)/p([0-9]+) index.php?task=category&id=$1&name=$2&page=$3 [L]
RewriteRule ^cat/([0-9]+)?/([^/\.]+)/([0-9a-zA-Z?-]+)/p([0-9]+) index.php?task=category&id=$1&name=$2&sortby=$3&page=$4 [L]
RewriteRule ^cat/([0-9]+)?/([^/\.]+)/([0-9a-zA-Z?-]+)-([0-9]+) index.php?task=category&id=$1&sortby=$3&page=$4 [L]
RewriteRule ^cat/([0-9]+)?/([^/\.]+) index.php?task=category&id=$1&name=$2 [L]
RewriteRule ^tag/([^/\.]+)/([0-9a-zA-Z?-]+)/([0-9]+) index.php?task=tag&t=$1&sortby=$2&page=$3 [L]
RewriteRule ^tag/([^/\.]+) index.php?task=tag&t=$1 [L]
RewriteRule ^profile/([0-9]+)?/([^/\.]+) index.php?task=profile&id=$1&name=$2 [L]
RewriteRule ^profile/comments/([0-9]+)?/([^/\.]+) index.php?task=users_comments&id=$1&name=$2 [L]
RewriteRule ^page/([0-9]+) index.php?task=view_page&id=$1 [L]
RewriteRule ^register index.php?task=register [L]
RewriteRule ^lost-password index.php?task=lost_pass [L]
RewriteRule ^links index.php?task=links [L]
RewriteRule ^news/item/([0-9]+)/([^/\.]+) index.php?task=news&id=$1 [L]
RewriteRule ^news/page([0-9]+) index.php?task=news&page=$1 [L]
RewriteRule ^members/([^/\.]+)-([^/\.]+)/page([0-9]+)? index.php?task=member_list&sort=$1&order=$2&page=$3 [L]
RewriteRule ^members index.php?task=member_list [L]
RewriteRule ^messages index.php?task=messages [L]
RewriteRule ^submit index.php?task=submit [L]
RewriteRule ^search/([^/\.]+) index.php?task=search&q=$1 [L]
RewriteRule ^search index.php?task=search [L]
RewriteRule ^submit index.php?task=submit [L]
RewriteRule ^r-([0-9]+)?-([0-9]+)? go.php?id=$1&ref=$2 [L]
RewriteRule ^r-([0-9]+)? go.php?id=$1 [L]
RewriteRule ^([^/\.]+)/([0-9]+)/([^/\.]+) index.php?task=view&id=$2&name=$3 [L]
RewriteRule ^news/([^/\.]+) index.php?task=news&name=$1 [L]
RewriteRule ^profile/([^/\.]+) index.php?task=profile&name=$1 [L]
RewriteRule ^news index.php?task=news [L]
RewriteRule ^page/([^/\.]+) index.php?task=view_page&name=$1 [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^([^/\.]+)/([0-9a-zA-Z'?-]+)/([0-9]+) index.php?task=category&name=$1&sortby=$2&page=$3 [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^([^/\.]+)/([^/\.]+) index.php?task=view&name=$2 [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^([^/\.]+) index.php?task=category&name=$1 [L]
## www reslove ##
RewriteCond %{HTTP_HOST} !^www\.
RewriteRule ^(.*)$ http://www.%{HTTP_HOST}/$1 [R=301,L]
## www reslove ##
## index reslove ##
Options +FollowSymLinks
RewriteCond %{THE_REQUEST} ^.*/index\.php
RewriteRule ^(.*)index.php$ http://www.epicwallpaper.net/$1 [R=301,L]
## index reslove ##
Right below the RewriteEngine On line, add:
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)/$ /$1 [L,R] # <- for test, for prod use [L,R=301]
to enforce a no-trailing-slash policy.
To enforce a trailing-slash policy:
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*[^/])$ /$1/ [L,R] # <- for test, for prod use [L,R=301]
EDIT: commented the R=301 parts because, as explained in a comment:
Be careful with that R=301! Having it there makes many browsers cache the .htaccess-file indefinitely: It somehow becomes irreversible if you can't clear the browser-cache on all machines that opened it. When testing, better go with simple R or R=302
After you've completed your tests, you can use R=301.
To complement Jon Lin's answer, here is a no-trailing-slash technique that also works if the website is located in a directory (like example.org/blog/):
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_URI} (.+)/$
RewriteRule ^ %1 [R=301,L]
For the sake of completeness, here is an alternative emphasizing that REQUEST_URI starts with a slash (at least in .htaccess files):
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_URI} /(.*)/$
RewriteRule ^ /%1 [R=301,L] <-- added slash here too, don't forget it
Just don't use %{REQUEST_URI} (.*)/$. Because in the root directory REQUEST_URI equals /, the leading slash, and it would be misinterpreted as a trailing slash.
If you are interested in more reading:
PR 3145 for Laravel
A discussion on commit 343c31e
(update: this technique is now implemented in Laravel 5.5)
This is what I've used for my latest app.
# redirect the main page to landing
##RedirectMatch 302 ^/$ /landing
# remove php ext from url
# https://stackoverflow.com/questions/4026021/remove-php-extension-with-htaccess
RewriteEngine on
# File exists but has a trailing slash
# https://stackoverflow.com/questions/21417263/htaccess-add-remove-trailing-slash-from-url
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^/?(.*)/+$ /$1 [R=302,L,QSA]
# ok. It will still find the file but relative assets won't load
# e.g. page: /landing/ -> assets/js/main.js/main
# that's we have the rules above.
RewriteCond %{REQUEST_FILENAME} !\.php
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME}\.php -f
RewriteRule ^/?(.*?)/?$ $1.php
Options +FollowSymLinks
RewriteEngine On
RewriteBase /
## hide .html extension
# To externally redirect /dir/foo.html to /dir/foo
RewriteCond %{THE_REQUEST} ^[A-Z]{3,}\s([^.]+).html
RewriteRule ^ %1 [R=301,L]
RewriteCond %{THE_REQUEST} ^[A-Z]{3,}\s([^.]+)/\s
RewriteRule ^ %1 [R=301,L]
## To internally redirect /dir/foo to /dir/foo.html
RewriteCond %{REQUEST_FILENAME}.html -f
RewriteRule ^([^\.]+)$ $1.html [L]
<Files ~"^.*\.([Hh][Tt][Aa])">
order allow,deny
deny from all
satisfy all
</Files>
This removes html code or php if you supplement it. Allows you to add trailing slash and it come up as well as the url without the trailing slash all bypassing the 404 code. Plus a little added security.

Rewrite different page with .htaccess url rewrite

I'd like to use .htaccess for url rewrite.
In my previous post you have shown me how to do it to the index.php page but now would like to do also for other pages like browser.error.php, etc.
To do so I tried to add the last 2 rows in the .htaccess, but unfortunately if I try the link www.mysite/browser-error/ it doesn't work - Return me in the index page.
Options +FollowSymLinks
RewriteEngine on
RewriteRule \.(css|jpe?g|gif|png|js|ico)$ - [L,NC]
# rule to ignore files and directories from all rewrite rules below
RewriteCond %{REQUEST_FILENAME} -d [OR]
RewriteCond %{REQUEST_FILENAME} -f
RewriteRule ^ - [L]
RewriteRule ^(.*)/(.*)/(.*)\/?$ index.php?op=$1&idric=$2&sp=$3 [L,QSA,NC]
RewriteRule ^(.*)/(.*)\/?$ index.php?op=$1&idric=$2 [L,QSA,NC]
RewriteRule ^(.*)\/?$ index.php?op=$1 [L,QSA]
#NEW ADDED ROWS
RewriteRule ^browser-error/(.*)\/?$ browser.error.php?r=$1 [L]
RewriteRule ^browser-error\/?$ browser.error.php [L]
Where I am doing wrong? How would I go? Thank you
I would suggest avoid use of .* and use [^/]+ instead with re-ordering of your rules:
Options +FollowSymLinks -MultiViews
RewriteEngine on
RewriteRule \.(css|jpe?g|gif|png|js|ico)$ - [L,NC]
# rule to ignore files and directories from all rewrite rules below
RewriteCond %{REQUEST_FILENAME} -d [OR]
RewriteCond %{REQUEST_FILENAME} -f
RewriteRule ^ - [L]
#NEW ADDED ROWS
RewriteRule ^browser-error/([^/]+)/?$ browser.error.php?r=$1 [L,QSA,NC]
RewriteRule ^browser-error/?$ browser.error.php [L,NC]
RewriteRule ^([^/]+)/([^/]+)/([^/]+)/?$ index.php?op=$1&idric=$2&sp=$3 [L,QSA]
RewriteRule ^([^/]+)/([^/]+)/?$ index.php?op=$1&idric=$2 [L,QSA]
RewriteRule ^([^/]+)/?$ index.php?op=$1 [L,QSA]
You have rules before preceding this rule. That makes your petition change to index.php before your rule is reached. (They all have the L flag that makes them be the LAST rule processed). As they are not restricted to not be applied when url is browser-error, they will run on every ///* or simialr petition.
Then, you should add RewriteCond to negate the browser-error url in your other RewriteRules as this:
Please try, and comment if that´s not what you need of it does not work as expected.
Hope it helps
Options +FollowSymLinks
RewriteEngine on
RewriteRule \.(css|jpe?g|gif|png|js|ico)$ - [L,NC]
# rule to ignore files and directories from all rewrite rules below
RewriteCond %{REQUEST_FILENAME} -d [OR]
RewriteCond %{REQUEST_FILENAME} -f
RewriteRule ^ - [L]
RewriteRule ^(.*)/(.*)/(.*)\/?$ index.php?op=$1&idric=$2&sp=$3 [L,QSA,NC]
RewriteCond %{REQUEST_URI} !^browser-error\/?(.*)?\/?%
RewriteRule ^(.*)/(.*)\/?$ index.php?op=$1&idric=$2 [L,QSA,NC]
RewriteCond %{REQUEST_URI} !^browser-error\/?(.*)?\/?%
RewriteRule ^(.*)\/?$ index.php?op=$1 [L,QSA]
#NEW ADDED ROWS
RewriteRule ^browser-error/(.*)\/?$ browser.error.php?r=$1 [L]
RewriteRule ^browser-error\/?$ browser.error.php [L]

URL Rewrite Including Trailing Slash If Not Present

I've got this RewriteRule to work.
RewriteBase /my/path/
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /my/path/index.php [L]
So URLs with a trailing slash work. http://localhost/my/path/foo/bar/
The problem is that URLs without the trailing slash will break relative links. Plus it dosen't look good.
This reaches the maximum number of internal redirects.
RewriteRule ^/my/path/(.*[^/])$ $1/ [R]
RewriteRule . /my/path/index.php [L]
And this will do... http://localhost/my/path/index.php/bar/
RewriteRule . /my/path/index.php
RewriteRule ^/my/path/(.*[^/])$ $1/ [R,L]
Any Ideas or solutions?
The confusing feature of mod_rewrite is that, after an internal redirect, even one qualified with [L], the entire set of rules is processed again from the beginning.
So you redirect a nonexistent path to index.php, but then the rules for adding a slash kick in and you don't get the result you want.
In your case you simply need to put the file nonexistence condition on both of the redirect rules:
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule [^/]$ %{REQUEST_URI}/ [L,R]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^ /my/path/index.php [L]
Or maybe move this condition to the top of the file:
RewriteCond %{REQUEST_FILENAME} -f [OR]
RewriteCond %{REQUEST_FILENAME} -d
RewriteRule ^ - [L] # redirect to same location to stop processing
RewriteRule [^/]$ %{REQUEST_URI}/ [L,R]
RewriteRule ^ /my/path/index.php [L]
There's also an undocumented trick to stop processing after an internal redirect which should make more complex rulesets easier to write – using the REDIRECT_STATUS environment variable, which is set after an internal redirect:
RewriteCond %{ENV:REDIRECT_STATUS} . # <-- that's a dot there
RewriteRule ^ - [L] # redirect to same location to stop processing
RewriteRule [^/]$ %{REQUEST_URI}/ [L,R]
RewriteRule ^ /my/path/index.php [L]

.htaccess redirecting errors

First off I am using the Codeigniter Framework so this issue is a workaround the way CI process URLs along with the current redirects I have set up using mod_rewrite.
I am trying to get a URL like this /?gclid=somestringgoeshere to redirect to /index.php?/home/gclid/somestringgoeshere.
The current .htaccess I have set is below
<IfModule mod_rewrite.c>
Options +FollowSymlinks
RewriteEngine On
RewriteCond %{REQUEST_URI} ^system.*
RewriteRule ^(.*)$ /index.php?/$1 [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^([^_]+)-([^_]+)-([^_]+)-([^_]+)-([^_]+)-([^_]+)-([^.]+)$ index.php?/$1_$2_$3_$4_$5_$6_$7 [L]
RewriteRule ^([^_]+)-([^_]+)-([^_]+)-([^_]+)-([^_]+)-([^.]+)$ index.php?/$1_$2_$3_$4_$5_$6 [L]
RewriteRule ^([^_]+)-([^_]+)-([^_]+)-([^_]+)-([^.]+)$ index.php?/$1_$2_$3_$4_$5 [L]
RewriteRule ^([^_]+)-([^_]+)-([^_]+)-([^.]+)$ index.php?/$1_$2_$3_$4 [L]
RewriteRule ^([^_]+)-([^_]+)-([^.]+)$ index.php?/$1_$2_$3 [L]
RewriteRule ^([^_]+)-([^.]+)$ index.php?/$1_$2 [L]
# Checks to see if the user is attempting to access a valid file,
# such as an image or css document, if this isn't true it sends the
# request to index.php
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
# This last condition enables access to the images and css folders, and the robots.txt file
# Submitted by Michael Radlmaier (mradlmaier)
RewriteCond $1 !^(index\.php|images|robots\.txt|css)
RewriteRule ^(.*)$ index.php?/$1 [L]
</IfModule>
I am trying to use the following code right above the first set up rewrite conditions and rule's to catch it before it try's anything else
RewriteRule ^?gclid=(.*)$ index.php?/home/gclid/$1 [L]
and
RewriteRule ^\?gclid=(.*)$ index.php?/home/gclid/$1 [L]
and
RewriteRule ^/?gclid=(.*)$ index.php?/home/gclid/$1 [L]
All either don't show the correct page or come up with a 500 internal error.
The URI’s query can only be tested with the RewriteCond directive:
RewriteCond %{QUERY_STRING} ^gclid=(.*)
RewriteRule ^$ index.php?/home/gclid/%1 [L]
Or more general (will consider further query parameters):
RewriteCond %{QUERY_STRING} ^([^&]*&)*gclid=([^&]*)
RewriteRule ^$ index.php?/home/gclid/%2 [L]
Oh, by the way: RewriteCond directives only correspond to the first following RewriteRule directive.

Resources