RewriteMap in httpd.conf and RewriteRule in .htaccess conflicting - .htaccess

I am working on a site where I have many short URLs which is redirected to a bigger version of URL. The idea is that the short URLs are distributed offline and users generally remembers them and types in the browser address bar. As example:
http://www.example.com/abc should redirect to http://www.example.com/higher_education/companion/politics/abc.html
Also there are some external links as well. like: http://www.example.com/google will redirect user to https://www.google.com
EDIT -
There is another scenario where http://www.example.com/elementary/def.html will be redirected to http://www.example.com/elementary/xyz.html
However, we now want to achieve this with RewriteMap. The code that we've written for that is as below:
<IfModule rewrite_module>
RewriteEngine on
RewriteMap custommap txt:/var/www/vhosts/example.com/httpdocs/map.txt
#RewriteCond %{REQUEST_URI} !^/index.php$
RewriteRule "^(.*)$" "${custommap:$0}" [R,L,NC]
</IfModule>
The map.txt contains:
abc http://www.example.com/higher_education/companion/politics/abc.html
google https://www.google.com
The problem is .htaccss file contains also some RewriteRule.
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)/(.*)\.html$ /index.php?sid=$1&ssid=$2 [L,NC,QSA]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)\.html$ /index.php?sid=$1 [L,NC,QSA]
So any request comes with .html will be served by index.php as standard CMS feature. However, now the code goes into redirect loop.
If someone shares some light in order to mitigate this issue then that would be great. The Apache version is 2.2 so I can't use any IF-ELSE in that.
Regards,
Aneek

You should put some restrictions on the rule serving URLs from RewriteMap:
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond ${custommap:$0} !^$
RewriteRule ^[^.]+$ ${custommap:$0} [R=301,L,NE]
This will ensure only non-files and non-directories with no DOT in URI will be handled by custommap.
More importantly it will also check existence of a mapping in custommap before redirecting.
Make sure you clear your browser cache before testing this change.

Related

.htaccess Rewrite Rule Understanding Problems

Site Structure
/articles/Employment/Companies.php
/articles/Employment/Companies/.htaccess
/articles/Employment/Companies/index.php
.htaccess file reads
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^/(.*)$ index.php [L]
So when you go to
/articles/Employment/Companies/[company type]
It is displaying the index.php page.
The Problem
I'm trying to link to
/articles/Employment/Companies.php
without the .php being displayed, however if I link to
/articles/Employment/Companies
it is going to
/articles/Employment/Companies/
What i'm Ideally Looking For
Understand why I my site is adding the / when linking to folder/hello
to strip out all .php so if you go to /hello it'll display /hello.php apart from in certain directories such as my current .htaccess file is located where /this or /that will display /index.php.
Please try with below, use from rewritecond with your existing rule what I am doing if the request is actually for php file which is not index.php then serve the extension less code.
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME}\.php -f
RewriteRule !index.php$ $1.php [L]

Rewrite and redirect with php variables

I am simply trying to rewrite automatically this:
From: mysite.com/channel.php?id=BBC&name=British Broadcasting Company &date=today
To: mysite.com/channel-britishbroadcastingcompany-today.html
I've tried with:
RewriteRule ^channel-(.*)-(.*)\.html$ /channel.php?id=1&name=$2&date=$3 [R]
But nothing happens.
Hope this simplest one will help you out. This will redirect if
1. REQUEST_URI is /channel.php
2. QUERY_STRING matches this pattern id=something&name=something&date=something
Redirect this to /channel-%1-%2.html here
1. %1 will hold value of name parameter
2. %2 will hold value of date parameter
RewriteEngine on
Options -MultiViews
RewriteCond %{REQUEST_URI} ^/channel\.php$
RewriteCond %{QUERY_STRING} id=.*?&name=(.*?)&date=(.*)
RewriteRule .* /channel-%1-%2.html? [R=301]
As per the requirement specified by OP to first redirect url on html page on the basis of some query parameters then rewriting the request on previous page. So the complete code of .htaccess will be like this.
RewriteEngine on
Options -MultiViews
RewriteCond %{REQUEST_URI} ^/channel\.php$
RewriteCond %{QUERY_STRING} id=.*?&name=(.*?)&date=(.*)
RewriteRule .* /channel-%1-%2? [R=301]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_URI} ^/channel\-(.*?)\-(.*?)
RewriteRule .* /channel.php? [L]
Explanation of 2nd part which is added.
1. REQUEST_FILENAME if file does not exist as a file and directory.
2. REQUEST_URI If request_uri starts with such pattern channel-somewords-somewords
then rewrite request on /channel.php
If I understand the problem correctly, You currently have a file channel.php and what You want to achieve is get more "friendly" URLs for SEO and general aesthetics in the browser location bar but still have channel.php handle your requests.
If this is really the case then You need a two-way rewrite.
First, You need to take your original URL and redirect it to a new, pretty version.
Second, You need to rewrite this pretty URI internally and still feed it to channel.php behind the scenes.
RewriteEngine On
RewriteBase /
# This part rewrites channel.php?name=X&date=Y into channel-X-Y.html
RewriteCond %{ENV:REDIRECT_STATUS} ^$
RewriteCond %{REQUEST_METHOD} =GET
RewriteCond %{QUERY_STRING} (.*\&)?name=([^&]+)\&date=([^&]+)(?:\&(.*))?
RewriteRule ^channel.php$ channel-%2-%3.html?%1%4 [R,L,NE]
# This part rewrites it back into channel.php but keeps the "friendly" URL visible
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^channel-(.*)-(.*).html$ channel.php?name=$1&date=$2 [L,QSA]
Note that the first rule-set limits the rewrite to method GET - otherwise You will lose any submitted POST data.
It also allows for any other query-string parameters to surround name and date (the rest of query-string parameters will pass-through to .html URI and then will be picked back up by channel.php)
Also note the ENV:REDIRECT_STATUS rule - this is crucial, without that part You'll be stuck in redirect loop.
See
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-s
RewriteRule ^([a-z0-9-_.]+)/?$ index.php?id=$1 [NC,L]
RewriteRule ^([a-z0-9-_.]+)/([a-z0-9]+)/?$ index.php?id=$1&goto=$2 [NC,L]
What it's going to do is check the index.php and replace to some like, site/dir/index.php to site/dir/namehere than in index.php you can use explode() to separate the values of current url ang get the variables
I am assuming you are asking for rewrite although you are using redirect flag in your current rules, and also assuming BBC to be static in id variable then try with below,
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^channel-([^/]+)-([^/]+).html$ channel.php?id=BBC&name=$1&date=$2 [L]

rewriting url with .htacces cause files not to be found

In general, I am trying to understand how .htaccess works. I would highly appreciate it if anyone points me in the right direction. I have been trying to make the following url (with optional parameters) pretty.
mysite/v1.0/foldername
mysite/v1.0/foldername/param1/
mysite/v1.0/foldername/param1/param2/etc
I tried the following:
RewriteEngine On
RewriteCond %{REQUEST_URI} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*)/?$ foldername.php [QSA,L]
the problem is that when I get it to pass the parameters it can no longer get the resources. It seems to have changed directory.
.htaccess is in foldername
Also, I would like to know what site i can go to to learn about REQUEST_URI, REQUEST_FILENAME, etc. A site that is not too technical as it's the apache site.
You are incorrectly rewriting the rules correct rule according to your need would be like,
RewriteEngine On
# rule for removing extension
RewriteCond %{REQUEST_FILENAME}.php -f
RewriteRule ^([\w-]+)/?$ $1.php [QSA,L]
# below cond means incoming url is nor a file neither a directory
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
# actual rules
RewriteRule ^([\w-]+)/([\w-]+)/?$ $1.php?param1=$1 [L]
RewriteRule ^([\w-]+)/([\w-]+)/([\w-]+)/?$ $1.php?param1=$2&param2=$3 [L]
Refrences
Reference: mod_rewrite, URL rewriting and "pretty links" explained
http://httpd.apache.org/docs/current/mod/mod_rewrite.html

How to re-direct blog article URLs?

I am trying to redirect a bunch of old blog article URLs using the .htaccess file:
RedirectMatch ^/index\.php/global/article/(.*)$ http://www.mywebsite.com/blog/article/$1
This doesn't really work, however, because my CMS seems to get confused by the index.php bit and keeps adding ?symphony-page= to all the URLs.
It's probably this part that is responsible:
### FRONTEND REWRITE - Will ignore files and folders
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*\/?)$ index.php?symphony-page=$1&%{QUERY_STRING} [L]
Can anybody help?
Please try the following (comments included to explain):
RewriteEngine On
# First, redirect the old URIs to the new ones via a 301 redirect.
# This will allow the CMS to take over using the rules that follow.
RewriteRule ^index.php/global/article/(.+)$ /blog/article/$1 [L,R=301]
# Frontend Rewrites - for the CMS
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*\/?)$ index.php?symphony-page=$1&%{QUERY_STRING} [L]
Try this:
#-- Input URL >> http://www.mywebsite.com/index.php/global/article/abc
### FRONTEND REWRITE - Will ignore files and folders
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*\/?)$ index.php?symphony-page=$1&%{QUERY_STRING}
RewriteCond %{REQUEST_URI} ^/index\.php/global/article/(.*)$
RewriteRule ^.*$ blog/article/%1 [R=301, L]
#--Output URL >> http://www.mywebsite.com/blog/article/abc
I've tested the above with this htaccess.madewithlove and it seems like it will work just fine, hopefully it will work for you too
Screenshot:

Do I need to call for .htaccess?

I have no experience with .htaccess, but I got a tip that it's very useful so I wanted to try this.
I now have a file called .htaccess, in my root folder.
The files contains this;
RewriteBase /
RewriteEngine on
RewriteCond %{HTTP_HOST} ^kellyvuijst\.nl [nc]
RewriteRule (.*) http://www.kellyvuijst.nl/$1 [R=301,L]
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME}\.html -f
RewriteRule ^([^/]+)/$ $1.html
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_URI} !(\.[a-zA-Z0-9]{1,5}|/)$
RewriteRule (.*)$ /$1/ [R=301,L]
What I'm trying to do here is create a 'www.mysite.com/portfolio/' instead of 'mysite.com/portfolio.html' I used some tutorials on this and I think it's correct, but I'm not sure.
So now I have this file, and what now? The tutorials all show what to put in the file but not what to do with it? Do I need to call for it in every .html page I have? And how do I call for it?
A .htaccess file is automatically invoked by the server.
You have just to put this into your file :
RewriteBase /
RewriteEngine on
RewriteRule www.mysite.com/portfolio/ /mysite.com/portfolio.html [L]
Hmm, you're using a lot of rules here to achieve just that.
Anyway, no you don't have to include that file. If you're hosting your site on a server with Apache it'll be included automatically. Can you also run PHP files or is your site just HTML? That's always an easy sign if you're also using Apache (not 100%, but often the go together).
If so, you could try just using these rules first:
RewriteEngine on
RewriteCond %{HTTP_HOST} !^www\.(.+)\.(.+)$ [nc]
RewriteRule ^(.*)$ http://www.%1.%2/$1 [R=301,L]
If that always adds www to your address, even if you type in the URL without www at least you can be certain that it works.
Then, to make the .html disappear you can add this rule:
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule $(.*)/$ /$1.html [L]
This should make every url that ends with a slash (like portfolio/) use a .html file instead (portfolio.html), but only if /portfolio/ isn't an actual directory on your website.
(I removed your url from the rules because this way it should also work if you use it on another website, or if you change your url. It should still do what you want)
Made sure the server is configured to allow htaccess files to override host options. So in your vhost/server config, you need:
AllowOverride All

Resources