mod_rewrite precedence - mod-rewrite

Let's say I want to support urls like twitter where:
twitter.com/username redirects to twitter.com/user_name.php?user=username
I have the following
RewriteRule ^(.*)$ user_name.php?user=$1
And that works fine. But the problem is now that everything, including twitter.com/index.php will of course redirect to user_name.php
How can I either create exceptions or precedence so that "real files" don't get rewritten? I tried adding an explicit rule for index.php before and after that one, but it doesn't seem to take effect.

You need to add RewriteCond for this
RewriteCond %{REQUEST_URI} !-f [OR] # for existing files
RewriteCond %{REQUEST_URI} !-d # for existing directories
RewriteRule ^(.*)$ user_name.php?user=$1

Related

.htaccess syntax code needing revision

1) i am trying to 301 all non www's to www's (including files)
e.g. /subdirectory/ + /subdirectory/1.jpg (all possibilities with the www.)
2) i am trying to exclude ONLY but ALL .html and .php files from showing and would like only the non trailing version to be indexed, the rest to be 301's to my domain
e.g. /example.html or .php >> /example
e.g. /example.html or .php >> to not work + to not be indexed
e.g. /example to ONLY work and to ONLY be indexed (to avoid duplicate content)
3) i am trying to 301 all dead links and 404's to my domain
e.g. /deadlink or /deadlink.pdf >> 301'd to my domain, example.com
Here is the code i currently have, however i am not sure if it's 100% proper.
Can someone please reply with a validated syntax for these 3 tasks? Thanks.
Options +FollowSymLinks
RewriteEngine On
RewriteCond %{HTTP_HOST} ^example\.com$ [NC]
RewriteRule ^(.*)$ http://www.example.com/$1 [R=301,L]
RewriteEngine on
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME}\.php -f
RewriteRule ^(.*)$ $1.php
RewriteEngine on
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME}\.html -f
RewriteRule ^(.*)$ $1.html
RewriteEngine on
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule . / [L,R=301]
OK, you've got three parts you're trying for here, and I'll address them all separately.
Before we begin, you only need to have one
RewriteEngine on
It only needs to be turned on once.
You should also set:
Options -MultiViews
as MultiViews can otherwise cause some weird issues here.
Redirect to WWW
Your current rules should work, but you can simplify them a little using the != prefix on RewriteCond:
RewriteCond %{HTTP_HOST} !=www.example.com
RewriteRule ^(.*)$ http://www.example.com/$1 [R=301,L]
Removing .php and .html suffixes
You need two separate sets of rules here: one to remove suffixes from URLs, and another to readd them internally.
Let's do the second half first, since that's easier:
RewriteCond %{SCRIPT_FILENAME}.html -f
RewriteRule ^(.*)$ $1.html [L]
RewriteCond %{SCRIPT_FILENAME}.php -f
RewriteRule ^(.*)$ $1.php [L]
With this in place, though, removing suffixes is a little tricky without conflicting with the rule that goes ahead and tries to put them back on. The best approach I was able to come up with was:
RewriteCond %{THE_REQUEST} \.(html|php)
RewriteRule ^(.*)\.(html|php)$ $1 [R=301,L,NC]
But I'm open to suggestions.
301ing all dead links
Don't do that. If a link doesn't exist, it should return a page with a 404 status. If you want to redirect visitors to your home page from dead links, put a link in your 404 page.

mod_rewrite forward shortend URL

I am looking for a way to create a short URL path for a longer URL on my page
the long url is: domain.com/tagcloud/user.html?t=1234ABCD
i would like to offer a short version of the URL to easy access it:
domain.com/t/1234ABCD
I tried a few examples but I just don't get it how I could forward these rules.
RewriteRule ^(.*)/t/$ /tagcloud/user.html?t=$1 [L]
I am also using MODX so they already use rules.
in addition my htaccess file
RewriteEngine On
RewriteBase /
# Always use www
RewriteCond %{HTTP_HOST} .
RewriteCond %{HTTP_HOST} !^www\.domain\.com [NC]
RewriteRule (.*) http://www.domain.com/$1 [R=301,L]
# The Friendly URLs part
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ index.php?q=$1 [L,QSA]
I must keep the code snippets above in my htaccess file. The first one simply forwards http://domain.com requests to www.domain.com
The friendly URLs part is needed to translate the internal IDs of my CMS with the alias of the URL. This feature must remain because the entire site cannot be influencted by the changes I try to make in htaccess...
I simply would like to add a listener that only if the URL matches www.domain.com/t/abcd1234
Therefore I need something that identifies the www.domain.com/t/ URL
your help is much appreciated
Try this:
RewriteCond %{REQUEST_URI} ^/t/.*
RewriteRule ^t/(.*)$ /tagcloud/user.html?t=$1 [R=301,L]

Friendly URL for images

Please suggest me what to put into .htaccess file.
I have PNG, GIF, JPG images on server http://domain.tld/images/anyimage.anyextension
Want to make URLs more friendly like a http://domain.tld/anyimage.anyextension
This I have now. First two strings change links as described. But last string doesn't change it back for server.
RewriteCond %{REQUEST_URI} ^/images/(.+)(\.gif|\.jpg|\.png)$ [NC]
RewriteRule ^image/(.+)$ /$1 [R=301,L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^/(.+)$ /images/$1 [L]
If I add
RewriteCond %{REQUEST_URI} ^/([^/.]+\.(png|gif|jpg))$ [NC]
RewriteCond %{DOCUMENT_ROOT}/image/%1 -f
RewriteRule ^([^/.]+\.(png|gif|jpg))$ /image/$1 [L,NC]
Right after previous query string rule then images don't open. If before there's no problem. What it could be? Do you have an idea how to fix it? The last string RewriteRule ^/?(.+)$ /?$1 [L] cause this conflict
RewriteCond %{THE_REQUEST} ^[A-Z]{3,9}\ /\?([^\ ]+) [NC]
RewriteRule ^$ /%1? [R=301,L]
RewriteCond %{QUERY_STRING} ^$
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^/?(.+)$ /?$1 [L]
Not sure how that makes it more friendly, aside from it being shorter. You can try adding this to the htaccess file in your document root:
RewriteEngine On
RewriteCond %{REQUEST_URI} ^/([^/.]+\.(png|gif|jpg))$ [NC]
RewriteCond %{DOCUMENT_ROOT}/images/%1 -f
RewriteRule ^([^/.]+\.(png|gif|jpg))$ /images/$1 [L,NC]
Then you can change all of your links from http://domain.tld/images/anyimage.anyextension to http://domain.tld/anyimage.anyextension
The first condition checks to make sure the request is for anyimage.anyextension, as long as the extension is a case-insensitive png, gif, or jpg.
The second condition checks to make sure the requested image actually exists in the /images/ directory.
RewriteEngine On
RewriteCond %{THE_REQUEST} ^[A-Z]{3,9}\ /images/(.+)(\.gif|\.jpg|\.png) [NC]
RewriteRule ^image/(.+)$ /$1 [R=301,L]
This redirects the browser to the non-/image/ URL. There's 2 completely different things going on here. One deals with the browser and the other deals with content on the server. See the top part of this answer that explains how they are different.
The rules that you have won't work. First:
RewriteRule ^/(.+)$ /images/$1 [L]
will never match. URI's used to match against the regex of a RewriteRule in htaccess files have the leading slash removed, so no URI is going to start with a /. You need to get rid of it.
Secondly, once you do, you'll get a 500 internal server error because your rules will cause an internal infinite loop. You need to match against %{THE_REQUEST} to ensure that a browser is actually requesting a URL with the /images/ path in it, not what has been internally rewritten.

How to redirect an url with parameters?

I'm at a total loss trying to integrate a mod_rewrite in my existing page. Currently, I am building a new site from scratch, and there i have some nice clean url's such as:
http://www.example.nl/nl/example
The old site, running Cms made simple, has some not-rewritten url's that would need to be redirected to the new pages. Those url's look like this:
http://www.example.nl/index.php?page=cake-and-pie&hl=nl_NL
But shorter versions of that like:
http://www.example.nl/index.php?page=cake-and-pie
also work.
It took me a while to figure out that url's with parameters cannot simply be redirected with "Redirect 301", like i'd normaly do. So i tried some online mod_rewrite generators like this and this, but the rules outputted by those result only in 404 errors, (the redirect doesn't work at all).
My .htaccess file current looks like this:
RewriteEngine On
RewriteBase /
# 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]
The old pages would seize to exist.
How do i redirect the old pages to the new ones?
Thanks.
EDIT
RewriteCond %{QUERY_STRING} =page=pie
RewriteRule ^index\.php$ /nl/? [L,R=301]
RewriteCond %{QUERY_STRING} =page=pie&hl=nl_NL
RewriteRule ^index\.php$ /nl/? [L,R=301]
Seems to do the trick. This is of course manual for every url, but i only have a few.
RewriteEngine On
RewriteBase /
RewriteRule ^(.+)/([^/]+)/?$ index.php?page=$1&hl=$2
RewriteRule ^([^/]+)/?$ index.php?page=$1 [QSA]

Rewrite rules confused

I am struggling to achieve this simple thing...
I have some static pages which should be like
www.domain.com/profile etc..
The problem is how to write the rewrite rules in order to ..
There would be some fixed rewrites
like /home
I want every file that exists not to be rewritten
www.domain.com/test.php should go to
test.php
Lastly if it is not found i want it to be redirected to static.php?_.....
RewriteRule ^/home/?$ /index.php?__i18n_language=$1 [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^/([^/]+)/?$ /static.php?__i18n_language=$1
This works ok but if i type index.php or test.php or even the mach from other redirection it gets me in static.php...
Please help!
According to your description you can use these rules:
# stop rewriting process if request can be mapped onto existing file
RewriteCond %{REQUEST_FILENAME} -f [OR]
RewriteRule ^ - [L]
# rewrite known paths /home, /foo, /bar, etc.
RewriteRule ^/(home|foo|bar|…)$ /index.php [L]
# rewrite any other path
RewriteRule ^ /static.php [L]
I haven't used this in a long time, but it's something I found, that should help. It is part of an old script that generates .httaccess files for redirecting from /usr/share/doc only when the doc isn't found:
The rule is "Check, and if the target url exists, then leave":
RewriteEngine On
RewriteBase /doc/User_Documents
### If the directory already exists, then leave
### We're just redirecting request when the directory exists but has been renamed.
RewriteCond %{REQUEST_FILENAME} User_Documents/([^/]+-[0-9][^/]*)
RewriteCond $PWD/%1 -d
RewriteRule .* - [L]
It's the [L] that means leave if one of the conditions is matched. In the old script, there are hundreds of generated rules (after [L]) that are skipped, because one of the conditions matched. In your case you would skip the rest of the rules when the target %{REQUEST_FILENAME} is found.
So, I suggest, before the redirection rule:
RewriteCond %{REQUEST_FILENAME} -f
RewriteCond %{REQUEST_FILENAME} -d
RewriteRule .* - [L]

Resources