Puzzled by Apache RewriteEngine - apache

My webroot is example.com. I have two sub-directories below webroot, named sub1 and sub2. Inside sub1I've placed the following .htaccess:
RewriteEngine On
RewriteCond %{REQUEST_URI} test\.me$ [NC]
#RewriteRule ^(.*)$ http://example.com/sub2/foo.html [L]
RewriteRule ^(.*)$ /sub2/foo.html [L]
When someone tries to access http://example.com/sub1/test.me, I want them to be served http://example.com/sub2/foo.html.
The above .htaccess does not work. If I un-comment the RewriteRule with the full path, and comment out the RewriteRule with the path relative to the webroot, it almost works as intended (the right page is shown, but the URL shown is also changed from http://example.com/sub1/test.me to http://example.com/sub2/foo.html, which is not wanted).
I am not able to understand why the full path almost works, while the path relative to the siteroot don't.
And if anyone could explain why my approach don't work, and what the the "best practice" for doing this type of redirection is - I would be grateful.

I've solved it.
Unfortunately, I oversimplified the setting when I composed the question. In fact, in a "virgin" environment the original .htaccess works exactly as I intended it to work.
However, the setting I'm using this .htaccess is with Drupal 7, and this makes a difference, since Drupal 7 uses "clean URLs".
What I found is that rewriting to a "clean" url do not work. So the following rule in .htaccess do not work when redirecting to Drupal node #1:
RewriteRule ^(.*)$ /sub2/node/1
However, the following does:
RewriteRule ^(.*)$ /sub2/?q=node/1
Apologies for not putting all that was relevant for cracking it in the question.
I hope this answer helps someone that struggles with the same thing.

Related

Mod Rewrite (SEO Friendly URL's)

You'd think I'd easily be able to find the answer to this on S/O, but I've tried everything and after a few hours of frustration I'm giving in and seeing what the real experts think.
I'm "sure" this can be done with mod rewrite, but I'll defer to you.
Problem: I'm attempting to turn a URL like this...
http://domain.com/new-cars/state.php?stateCode=al
Into this at minimum...
http://domain.com/new-cars/al-new-cars
Though, ideally I'd get it to look like this (yes, I'm willing to rewrite some code to use the full state name as the $stateCode variable to make it easier!)...
http://domain.com/new-cars/alabama-new-cars
Ultimately the plan is to be able to use URL's in links such as...
http://domain.com/new-cars/alabama-new-cars
And have .htaccess take car of associating this SEO-friendly URL with the dynamic version and displaying the page properly.
Either way, I haven't been able to figure out how to do this like I need.
Here's what I've tried.
Options +FollowSymlinks
RewriteEngine on
RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^new-cars/([^-]*)-new-cars/$ /new-cars/state.php?stateCode=$1 [L,QSA,NC]
And different variations that I've created using 2 different mod rewrite generators and various answers to other people's questions.
Absolutely nothing is working.
I expect when I go to
http://domain.com/new-cars/state.php?stateCode=AL
That it rewrites the URL to
http://domain.com/new-cars/AL-new-cars
...but it does not. Instead, it stays exactly the same dynamic URL I typed in. If I go to the "desired" rewrite URL I get a 404 error saying the page doesn't exist.
What am I doing wrong?
I thought maybe my .htaccess privileges weren't set right, but I can do a 301 redirect through .htaccess quite easily, so that's not it.
Maybe someone here can help. I've tried to so many permutations, even settling for the most basic rewrite just to see if I could get it to work - but nothing.
Any help is appreciated!
You can use:
Options +FollowSymlinks
RewriteEngine on
RewriteBase /
# external redirect from actual URL to pretty one
RewriteCond %{THE_REQUEST} \s/+new-cars/state\.php\?stateCode=([^\s&]+) [NC]
RewriteRule ^ /new-cars/%1-new-cars? [R=301,L,NE]
# internal forward from pretty URL to actual one
RewriteRule ^new-cars/([^-]*)-new-cars/?$ /new-cars/state.php?stateCode=$1 [L,QSA,NC]

Mod_rewrite rules from root

This problem has been bugging me for a while now.
I have a created a small site engine and I'm using mod_rewrite to tell the engine what page to proccess, SEO friendly links is a bonus :).
This is how it's works today:
the adress http://www.example.com/site/page
becomes http://www.example.com/engine.php?address=page
But what i want is:
the adress http://www.example.com/page
becomes http://www.example.com/engine.php?address=page
Everything works fine if i create a psuedo directory for the calls (/site) but when i try to do the same from the root strange things start to happends.
RewriteBase /
RewriteRule ^site/(.*) engine.php?%{QUERY_STRING}&address=$1
Works fine: /site/about/contacts becomes eninge.php?address=about/contacts
RewriteBase /
RewriteRule ^(.*)$ eninge.php?%{QUERY_STRING}&address=$1
Doesn't work, for some reason /about/contacts becomes eninge.php?address=eninge.php
(.*) means catch anything. Have you tried exluding files and directory before your catch-all ? Because it will cause an infinite recursion without it.
RewriteEngine On
RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ eninge.php?%{QUERY_STRING}&address=$1 [L]
More information is available in the official documentation: http://httpd.apache.org/docs/current/mod/mod_rewrite.html
Update: You should also specify [L] at the end of your rule, to tell Apache to end the rewriting process here.
Check the RewriteLog (this has been updated in 2.4, check current docs if not using 2.2):
RewriteLog "/usr/local/var/apache/logs/rewrite.log"
RewriteLogLevel 3
This will show you exactly what mod_rewrite is doing and allow you to tune your configuration based on its output. Beware - it grows very quickly, and should never be used in production environments.
As an aside, you have some typos in your post - worth verifying that these differ from your config.
RewriteCond %{REQUEST_FILENAME} !^engine.php
RewriteRule (.*) engine.php?address=$1 [QSA,L]
Try this. What you have is causing the rewrite to loop around and first do engine.php?address=about/contacts as you were expecting, but then go around again and rewrite that to engine.php?address=engine.php. Make sense? The [QSA,L] is a Query String Append and Last flag that will add the query string to your URL and tell the rewrite engine to stop looking for rewrites. The RewriteCond %{REQUEST_FILENAME} !^engine.php is to check that you haven't already specified the engine rewrite by ensuring the current URL doesn't start with engine.php. This is necessary if you are writing this in an .htaccess file rather than the .httpd config files.

.htaccess mod_rewrite subdirectory to URL parameter

I hope this was not asked over and over again before, but I didn't get further to an answer using google, w3schools and so on. So here is my question:
I'm writing a script that creates kind of an index of projects that I have on my homepage and makes a nice list with images and teaser text based on an info file. I mostly have my projects on github and the readme is in markdown so I thought I could dynamically generate the HTML from the markdown of the latest blob from github on demand using PHP so it gets updated automatically.
My directory structure looks like this:
projects
project1
.remoteindex
.info
project2
.remoteindex
.info
index.php
.htaccess
So when just domain.tld/projects/ is requested I get the info from .info and make a nice index of all projects. But if domain.tld/projects/project1/ is request it, I want to internally redirect it to domain.tld/projects/?dir=project1 to do my markdown parsing and so on. But domain.tld/projects/project1/image.png should not be redirected.
This is what I tried:
.htaccess
RewriteEngine on
RewriteRule ^([^/]+)/?$ index.php?dir=$1 [R,L]
I made it redirect instead of rewrite so that I can see what the error is because I just got an 404. The URL that I get redirected to is domain.tld/home/www/web310/html/projects/index.php?dir=project1 so obviously there is something going wrong with the internal structure of the web server an paths an whatever.
I hope you can understand my problem an I would be very pleased if someone could help me, because I'm totally lost on .htaccess anyway.
Edit:
See my answer below for the used .htaccess.
The strange thing is that if I have an index.html in on of the subdirectories, my local web server (Apache with XAMPP for Mac OS X 1.7.3) does not rewrite and the index.html gets displayed, without one it works correctly.But on my real web server that serves my homepage it rewrites both with and without index.html (which is what I want). Any hints on that?
Thanks for all the help so far! You guys are just awesome!
I figured out that a symbiosis of both of your solutions works well for me:
RewriteEngine on
RewriteBase /projects
RewriteCond %{SCRIPT_FILENAME} !-f
RewriteCond %{SCRIPT_FILENAME} -d
RewriteRule ^([^/]+)/?$ index.php?dir=$1 [QSA,L]
Of course only without [R], this was my fault. (See my question edit for another question please).
You need to add a RewriteBase /projects to the htaccess.
That way the redirect will work properly.
Edit:
RewriteEngine on
RewriteRule ^index.php - [L]
RewriteRule ^([^/]+)/?$ index.php?dir=$1 [R,L]
Following what you ask, this is important not to do a redirect, but let the rewriterule modify internally the URL i.e. the RewriteRule should not end with [R,L] but rather [L] and maybe the "query string append" directive to keep what's after the ? so this should probably be [QSA,L].
Now here's how I'd do to avoid rewriting static files: if it's not a file then (and only then) test it:
# if it's not a file...
RewriteCond %{SCRIPT_FILENAME} !-f
# ... and it's a dir
RewriteCond %{SCRIPT_FILENAME} -d
# ... then rewrite it internally and stop further processing:
RewriteRule projects/([^/]+)(/?)$ index.php?dir=$1 [QSA,L]
And now two hints:
Please try to use the RewriteLog directive: it helps you to track down such problems:
# Trace:
# (!) file gets big quickly, remove in prod environments:
RewriteLog "/web/logs/mywebsite.rewrite.log"
RewriteLogLevel 9
RewriteEngine On
My favorite tool to check for regexp:
http://www.quanetic.com/Regex (don't forget to choose ereg(POSIX) instead of preg(PCRE)!)

.htaccess question - redirects after the domain name

Apologies if this is answered elsewhere. I had a search for this on here, but I'm quite confused so I'm not 100% what to search for in the first place.
I have a Wordpress site which is at exampledomain.com. I also own exampledomain.co.uk, and I have put in the .htaccess file the follow lines:
RewriteCond %{http_host} ^exampledomain.co.uk [nc]
RewriteRule ^(.*)$ http://exampledomain.com/$1 [r=301,nc]
These work fine in terms of changing exampledomain.co.uk to exampledomain.com, but the moment I add in something after the exampledomain.co.uk (i.e. exampledomain.co.uk/page1) the .htaccess file doesn't change it so it tries to load.
Is there something I can add to the .htaccess file which will sort this, so that, for example, if I were to type exampledomain.co.uk/page1 it would redirect to exampledomain.com/page1 ?
Thanks,
Charlie
P.S. Apologise for the weirdly parsed example links, but as a new user it won't let me include more than two hyperlinks.
Why not simply do
RedirectPermanent / http://exampledomain.com
in the co.uk's config instead? mod_rewrite is very handy, but for a simple domain redirector, it's major overkill.
comment followup:
I'd go for something like this:
RewriteCond %{HTTP_HOST} exampledomain.co.uk$ [NC]
RewriteRule (.*) http://exampledomain.com/$1 [R=301,L]

Mod Rewrite Hide Folder

I think this is a pretty simple question.
How do you an apache rewrite to hide a folder.
EX: www.website.com/pages/login.php to www.website.com/login.php
or www.website.com/pages/home.php to www.website.com/home.php
The folder needs to alway be hidden. thanks
I assume what you want is for the browser to request /home.php but the server to actually use the file located at /pages/home.php, right? If so, this should work:
Make sure the apache mod_rewrite module is installed. Then, use something like this in your apache config, virtual host config, or (less desirable) .htaccess file:
RewriteEngine On
RewriteRule ^/(.*)$ /pages/$1
The rules use regular expressions, so you may want to look at a reference on that topic if you're unsure. Read the manual for more info on other directives (RewriteCond can be very useful) or rule options.
I know the original post here was from a couple years ago, but it's been coming up first in the search engine, so maybe this will help others looking to hide a folder name in the URL.
Not exactly what original poster wanted, but along the same lines.
RewriteCond %{HTTP_HOST} ^mydomainname\.com$ [OR]
RewriteCond %{HTTP_HOST} ^www\.mydomainname\.com$
RewriteCond %{REQUEST_URI} !^/subfoldername/
RewriteRule (.*) /subfoldername/$1
The above example would redirect any request to mydomainname.com or www.mydomainname.com to the subfoldername directory in the root directory for the domain, and the subfolder name would not appear in the URL.
If your example actually reflects the files you need, then in your .htaccess file:
#Options +FollowSymLinks
RewriteEngine On
RewriteRule ^/pages/(.+)\.php $1\.php [NC, L]
Also, if the directory has read permission, it cannot be, in reality "hidden". I assume you mean that it no longer appears in the url.