rewrite rule for my drupal site url not working - .htaccess

I'm trying to write a couple of rewrite rules for my drupal site in its .htaccess file and it doesn't seem to work at all. My lack of prior knowledge and experience in regex and mod_rewrite doesn't seem to help the cause either.
The URLs I'm trying to rewrite are as follows
Source:
http://www.mydrupalsite.com/somealphanumericwithspecialchars/somealphanumericwithspecialchars/somealphanumericwithspecialchars/somealphanumericwithspecialchars/Keyword1/Keyword2/UNIQUEID?queryparam1=somenumber
Destination:
http://www.mydrupalsite.com/legacystuff/UNIQUEID
My .htaccess mod_rewrite code is
RewriteEngine on
# Rewrite URLs of the form 'x' to the form 'index.php?q=x'.
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_URI} !=/favicon.ico
#This is the only rule written by me others are drupals
RewriteRule ^(.*)/(.*)/(.*)/(.*)/Keyword1/Keyword2/([0-9]*)?$ legacystuff/content/$5 [R=302]
RewriteRule ^(.*)$ index.php?q=$1 [L,QSA]
My understanding and implementation based on some quick browsing on tutorials was the first four (.*) would match with the four alphanumericspecialchars in the URL, keyword1 and keyword2 would remain constant so i could match them as such, the unique numeric id which is actually required for my destination URL (param $5 in the destination) would be captured by ([0-9*])?. I use the following vhost in my httpd.conf of my local environment
<VirtualHost *:80>
DocumentRoot "C:/wamp/www/mydrupalsite"
ServerName mydrupalsite.com
</VirtualHost>
My trouble is that the redirect from the source to destination URL does not occur after restarting my local server and clearing the cache. Any help on where I went wrong and how to make it right would be really appreciated.

Finally got it working, added the RewriteBase for my virtual host setting and placed my RewriteRule underneath it with the trailing ? in my destination to ignore query string and the L flag. Setting RewriteLog in my httpd.conf helped understand things from a better perspective. Hopefully this helps someone else new to .htaccess in drupal.
RewriteBase /
RewriteRule ^(.*)/(.*)/(.*)/(.*)/Keyword1/Keyword2/([0-9]*)?$ legacystuff/content/$5? [R=301,L]

Related

htaccess subdomain rewrite without a redirect

Using htaccess Rewrite, I want my url http://*.phoneataxi.com/ (where * is a wildcard, excluding 'www') to show in the address bar as is but get information from http://*.phoneataxi.com/test.php?c=*.
I have tried so many different things but nothing is doing exactly what I need. Most examples are redirecting the subdomain to the '/test.php' file in the address bar which I don't want to do.
I'm trying not to have to create individial subdomains and subdomain folders within my webroot.
Ideas?
I use this htaccess file to make Apache act as a proxy for another host:
IfModule mod_rewrite.c>
RewriteEngine on
RewriteCond %{HTTP_HOST} ^ghost\.pileborg\.se$
RewriteRule (.*) http://vps.pileborg.se/ghost/$1 [P]
</IfModule>
It causes all access to http://ghost.pileborg.se/ to be "redirected" to http://vps.pileborg.se/ghost/.
UPDATE (2020)
Some of the answers regarding this topic is very old and no longer work as expected.
After searching for hours on something that actually works, this is what I came up with; edit as you see fit:
RewriteEngine on
RewriteBase /
RewriteCond %{HTTP_HOST} ([a-z0-9]+)\.
RewriteRule ^(.*)$ - [E=BASE:%1]
RewriteCond %{DOCUMENT_ROOT}/%{ENV:BASE}/index.php -f
RewriteRule ^(.*)$ %{ENV:BASE}/index.php [L,NC,QSA]
RewriteCond %{DOCUMENT_ROOT}/%{ENV:BASE}/index.html -f
RewriteRule ^(.*)$ %{ENV:BASE}/index.html [L,NC,QSA]
Breakdown
Make sure that the rewrite module is installed and enabled on your host
first we turn the rewrite engine on and set the path-base
then isolate the subdomain - any letters/numbers before the first dot
set a variable in this runtime environment that contains the subdomain
check if the subdomain folder and index-file exists
if it does exist -then use that file as the request-handler (no redirect)
if it does not exist then the request carries on normally
Flags
The flags used here are explained here, but the ones used above are quite simple:
[L] Last rule, ignore the rest
[NC] No Case, no uppercase/lowercase restrictions
[QSA] I remember this as "Query String Attach" :D

htaccess multi language site with sub directories, and default 301

I am having some issues setting up my htaccess to allow multiple languages utilising the sub directory method eg:
http://www.domain.com/en/
http://www.domain.com/sw/
http://www.domain.com/ie/
Also to complicate things, the project isn't currently live, its on a dev server. For example, I am currently accessing the project at:
http://dev.domain.com/devname/projectname/
And I want the above to automatically 301 redirect to:
http://dev.domain.com/devname/projectname/en/
Here is my htaccess:
Options +FollowSymLinks -MultiViews
RewriteEngine on
# ----------------------------------------------------------------------
# MULTI LANGUAGE SUB DIRECTORY
# ----------------------------------------------------------------------
RewriteCond %{REQUEST_URI} !^/(en|sw)/
RewriteRule ^(.*)$ en/$1 [R=301,L]
# ----------------------------------------------------------------------
# Rewrite rules
# ----------------------------------------------------------------------
## CASE STUDIES ##
RewriteRule ^casestudies/([^/\.]+).html$ index.php?controller=contents&method=viewCasestudy&link=$1 [L,QSA]
## PRODUCTS ##
RewriteRule ^products/([^/\.]+).html$ index.php?controller=contents&method=viewProduct&link=$1 [L,QSA]
RewriteRule ^([a-z{2}]+)(/)?$ index.php?controller=contents&method=viewHome&lang=$1 [L,QSA] # Default load
RewriteRule ^(/)?$ index.php?controller=contents&method=viewHome [L,QSA] # Default load
The above will actually redirect to:
http://dev.domain.com/home/webserver_dir/devname/projectname/en/
..and if I use RewriteBase it seems to just goto...
http://dev.domain.com/en/
So my question: How do I get the language URLs working correctly relative to the directory its in on my dev server, and then ideally will work when it goes live without any environment specific rules.
Bonus question: Do I need to add the ([a-z{2}]+) bit in front of all my subsequent rewrite rules or can I have a catch all that will effect all further rules?
EDIT -----------------------------
I have reduced it down to the following as suggested...
Options +FollowSymLinks -MultiViews
RewriteEngine on
RewriteBase /devname/projectname/
RewriteCond %{REQUEST_URI} !^/(en|sw)(/|$) [NC]
RewriteRule ^(.*)$ en/$1 [R=301,L]
RewriteRule ^([a-z]{2})/?$ index.php?controller=contents&method=viewHome&lang=$1 [NC,L,QSA] # Default load
... but now its redirecting to http://dev.domain.com/devname/projectname/en/en/en/en/en/en/en/en/en/en/en/en/en/en/en/en/en/en/en/en/en/, any ideas?
Have you tried the answer in the following link? It should do what you're trying to achieve.
Endless Redirect Loop by htaccess rules multi language
RewriteEngine On
RewriteBase /
# empty url -> redirect to en/
RewriteCond %{QUERY_STRING} !lang=(en|de)
RewriteRule ^$ en/ [R=301,L]
# url is ONLY '/en' or '/de' -> redirect to /en/ or /de/ (adding slash)
RewriteRule ^(en|de)$ $1/ [R=301,L]
# now all urls have en/ de/ -> parse them
RewriteRule ^(en|de)/(.*)$ $2?lang=$1&%{query_STRING} [L]
If .htaccess must not change
Change your <VirtualHost> configuration for your DEV server project as
<VirtualHost *:80>
ServerName dev.domain.com
ServerAlias project.domain.com
DocumentRoot "/home/webserver_dir/devname/projectname"
</VirtualHost>
These changes would typically go in your httpd-vhosts.conf file. Your .htaccess files would now have
RewriteBase /
to mark root as your base directory for both your development and live servers.
If you're trying to version your projects or test multiple projects on the same dev host, then you would have to incorporate the naming scheme into the domain names instead of the URL path. For example,
<VirtualHost *:80>
ServerName dev1.domain.com
ServerAlias project1.domain.com
DocumentRoot "/home/webserver_dir/dev1/project1"
</VirtualHost>
<VirtualHost *:80>
ServerName dev2.domain.com
ServerAlias project2.domain.com
DocumentRoot "/home/webserver_dir/dev2/project2"
</VirtualHost>
The bottom line is that you can not have the same .htaccess file rules working untouched with different deployment directories unless you resort to mod-rewrite way of if-else mumbo jumbo which would just be added clutter once you've gone live.
For the rules to work transparently, Apache must only see and apply the rules on what's going live (the content that comes after /devX/projectX/ directories) which is what shifting the DocumentRoot does here for us.
If minimal mods to .htaccess are okay
Not everyone has access to Apache's .conf files. Certain hosts out-rightly reject requests to modify them. Which is why, if they have at least kept mod-rewrite enabled, a lot of website's settings can be tinkered with. One of them is to use RewriteBase to handle the different deployment directories.
So, if you keep RewriteBase / on live but change it to RewriteBase /devX/projectX/ for development, most of your RewriteRules should work as is. So, /devname/projectname/ should correctly redirect to /devname/projectname/en/.
Your use of ([a-z{2}]+) is incorrect. You probably meant ([a-z]{2}) to capture exactly two letters. If you meant to capture two or more, it would become ([a-z]{2,}). So, your default load rewrite would become
RewriteRule ^([a-z]{2})/?$ index.php?controller=contents&method=viewHome&lang=$1 [NC,L,QSA] # Default load
You're correct to assume that you would need this regex for all subsequent rules or they would fail to match. So, your RewriteRule for casestudies won't work. A simpler way to not care about the language prefix is to drop the ^ start of URL path anchor as
RewriteRule /casestudies/([^/\.]+).html$ index.php?controller=contents&method=viewCasestudy&link=$1 [NC,L,QSA]
RewriteRule /products/([^/\.]+).html$ index.php?controller=contents&method=viewProduct&link=$1 [NC,L,QSA]
Your last RewriteRule matching ^(/)?$ isn't required because you're already doing a 301 redirect for all URLs with no language directory prefix to /en/$1 above, which should ideally be
RewriteCond %{REQUEST_URI} !^/(en|sw)(/|$) [NC]
RewriteRule ^(.*)$ en/$1 [R=301,L]
Otherwise, /en would get redirected as well to /en/en.

htaccess A quick move, from pagefor.local/USERNAME to pagefor/USERNAME.local

Morning all,
I have spent Sunday attempting to rewrite a domain to no avail. I'm using MAMP and have changed my Hosts folder and MAMP httpd.conf with the following :
Addition to hosts file:
127.0.0.1 apagefor.local
Addition to httpd.conf file:
<VirtualHost *>
ServerName pagefor.local
DocumentRoot /Applications/MAMP/htdocs/pagefor
</VirtualHost>
This allowed me get rid of the pesky localhost:8888/pagefor/ to just using a nice local url of pagefor.local this all works perfectly. But now im trying to attempt to do a htaccess rewrite if a username is placed directly after the domain. Allowing me to do the following:
Change this:
pagefor.local/LEE
to this:
pagefor/LEE.local
So what have I tired? Well I thought I could do something like the following (within .htaccess):
RewriteEngine On
RewriteCond %{HTTP_HOST} ^`pagefor.local` [NC]
RewriteRule ^pagefor.local/([A-Za-z0-9-.]+) `http://pagefor/$1.local`
Im still trying to workout how to do this, if anyone can tell me where im going... And if im on even on the right path (pun intended :) ) Thank you.
Update
I have managed to get the url to change from http://pagefor.local/lee to http://pagefor/lee.local Thanks to anubhava. The only contention I have is I originally have everything go to my index.php file which controls the entire application... So would it be possible to do the following:
RewriteCond %{HTTP_HOST} ^pagefor\.local$ [NC]
RewriteRule ^([A-Za-z0-9-.]+)$ http://pagefor/$1.local [NC,L]
Then Have the following line to get $1 into my index.php:
RewriteRule ^([A-Za-z0-9-.]+).local$ index.php?url=$1 [NC,L]
Therefore when the Url is pagefor/lee.local its on the following index.php?url=lee. I tired the above but it did not succeed. I hope im on the right track to solving this problem.
Try this instead:
RewriteEngine On
RewriteBase /
RewriteCond %{HTTP_HOST} ^pagefor\.local$ [NC]
RewriteRule ^([A-Za-z0-9-.]+)$ http://pagefor/$1.local [L,R]

mod_rewrites .htaccess not working with godaddy hosting (linux)

On my site www.sqcp.com in testing on another linux server, all worked as it should. However since moving it to godaddy, the mod_rewrites haven't been working, therefore none of the other pages have been accessible. Even if I create a blank directory/folder in the what it's trying to tidy the url to it then works for that page (obviously isn't a fix).
So any help would be great here my .htaccess file.
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteRule ^index\.php$ / [L,R=301]
RewriteRule (.*)/{2,}$ /$1/ [L,R=301]
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{THE_REQUEST} ^GET\ /[^?\s]+\.php
RewriteRule (.*)\.php$ /$1/ [L,R=301]
RewriteRule ^(.*)/(\d{4}\-\d{2}\-\d{2}\-[a-zA-Z0-9\-_]+)$ $1?s=$2 [L]
RewriteRule ^(.*/)?staff.php/([a-zA-Z0-9\-_]+) $1staff.php?s=$2 [L]
RewriteCond %{REQUEST_FILENAME} -d
RewriteRule (.*)/$ $1.php [L]
RewriteCond %{REQUEST_FILENAME}/index.php !-f
RewriteRule (.*)/$ $1 [L]
</IfModule>
Godaddy run a perfectly good shared hosting service, addressing a large market sector -- users who want an active site (that is with some scripting) but without the cost or complexity of paying for or having the expertise to administer their own Linux VM. This isn't a GoDaddy problem. Its yours.
So first get to understand the environment that you are running under by running a phpinfo script, and make sure it creates the variables that you use. As far as I can see on your example:
Rules 1-3 are 301 redirections to enforce some request naming convention.
Rule 1 redirects /index.php to /
Rule 2 collapses trailing multiple / to a single /
Rule 3 rewrites GET requests for *.php to *.php/
Rules 4-6 map public URIs to internal ones
Rule 4 rewrites /*/yyyy-mm-dd-word to *?s=yyyy-mm-dd-word (note no QSA)
Rule 5 seems to be attempting to rewrite /*/staff.php/word to /*/staff.php?s=word but the syntax is wrong for this.
Rule 6 replaces any trailing / by .php on redirection
Rule 7 strips any trailing '/' unless the uri is a directory with an index.php (I assume that you are assuming a DirectoryIndex index.php (is this the case for GoDaddy?)
This is all hopelessly confused. Are you hiding or exposing the .php extension? Because Rule 3,5 and 6 are inconsistent. And rule 5 would seem more logical as
RewriteRule ^(.*?)/staff.php/([a-zA-Z0-9\-_]+) $1/staff.php?s=$2 [L]
Go back to the drawing board and work out what you are trying to do with your htaccess rules; what you want your public URI grammar to be; how your scripts are laid out; what redirects you want to pass back to the client browser and which you want Apache to handle as internal rewrites and what extra conditions are needed to prevent looping and misfiring. Make sure this makes sense and then debug them by building up your .htaccess file one rule at a time and using test requests to exercise each rule in turn to validate what its doing.
Trying adding the following at the start of your htaccess file. I had the same problem getting rewrites to work on GoDaddy which worked everywhere else:
Options -Multiviews

htaccess command to prevent master site access via subdirectory?

I have hosting setup with a master domain (mapped to the web root) and then a number of addon domains (each with their own folder within the web root). At the moment you can visit www.masterdomain.com/addondomainsubdir and reach the same page as you would if you visited www.addondomain.com (which maps to /public_html/addondomainsubdir). I want to prevent this so if you visit www.masterdomain.com/addondomainsubdir then it will do a 301 redirect to www.addondomain.com. The new addondomain.com site is a single page site so it does not have to map any additional pages.
Adding rules to the htaccess file in the web root does notaffect anything as the subdir exists which is wierd as i thought the htaccess command should work even if there is a matching subdir (i've tried the following which works when there's no matching subdir):
RewriteRule ^addondomainsubdir?$ http://www.addondomain.com [NC,R=301,L]
Logically given it's reaching this directory I figure i need to add a command within the htaccess file in the addondomainsubdir directory however nothing appears to have any effect (i've got various other rules setup and they work fine).
I would be massively grateful if anyone explain the best way to rectify this?
Thanks so much for your help,
Dave
I know this is an old post, but it has never been successfully answered. So for all of you finding this via search, this should do what the OP is asking.
Add this line to your .htaccess file:
redirect permanent /addondomainsubdir/ http://www.addondomain.com
Try these rules in your .htaccess:
Options +FollowSymlinks -MultiViews
RewriteEngine on
# for http
RewriteCond %{HTTP_HOST} ^(www\.)?masterdomain\.com$ [NC]
RewriteCond %{SERVER_PORT} =80
RewriteRule ^([^/]+)/?$ http://www.$1.com/ [R=301,L]
# for https
RewriteCond %{HTTP_HOST} ^(www\.)?masterdomain\.com$ [NC]
RewriteCond %{SERVER_PORT} =443
RewriteRule ^([^/]+)/?$ https://www.$1.com/ [R=301,L]
Instead of putting a rule in your main .htaccess, I would make make a .htaccess for each add-on domain, putting each one in the respective subdirectory.
RewriteEngine on
RewriteCond %{HTTP_HOST} masterdomain\.com$ [NC]
RewriteRule ^addondomainsubdir(.*)$ http://www.addondomain.com/$1 [R=301,L]

Resources