RewriteRule variables blank - .htaccess

I have a couple of rewrite rules in htaccess. They work on one server but not another. My script is as follows (I've commented out how the urls look):
RewriteEngine On
RewriteBase /
RewriteCond %{REQUEST_URI} !^/images/
#example.com/regions/fife/
RewriteRule ^regions/([A-Za-z0-9\-\+\']+)/?$ /regions.php?region=$1 [L]
#example.com/regions/fife/dunfermline
RewriteRule ^regions/([^/]+)/([^/]+)$ /regions.php?region=$1&town=$2 [L]
It returns two variables (region & town) I can manipulate in PHP, and throw up the appropriate content. I have a Rackspace server, and the script works perfectly, but on another server (Freedom2surf) it only works so far. It doesn't return the variables. I get a blank $_GET array...
Any ideas? F2S aren't giving me any clues, just that I should check my code. But if it works on another server, then what gives? Is it an Apache setting that is different?

I think you may be after the 'QSA' flag, which will append the query string from the original request to the redirected request, e.g:
#example.com/regions/fife/
RewriteRule ^regions/([A-Za-z0-9\-\+\']+)/?$ /regions.php?region=$1 [L,QSA]

This sounds like you have a mod_negotiation conflict here and you need to turn Multiviews off. Sometimes apache default configurations have Multiviews turned on by default. What that does is it will look at a request, say, /regions/1234 and mod_negotiation will notice that there is a file /regions.php and assume that the request is actually for that php file. It'll thus serve /regions.php/1234 and completely bypass mod_rewrite. You can use Options to turn it off. Just add this to the top of your htaccess file:
Options -Multiviews

Related

.htaccess RewriteRule returns a blank page

I'm trying to solve this for more than two hours now.
I have a personal site which uses .htaccess to manage urls.
It looks like this:
RewriteEngine on
RewriteBase /
...
RewriteRule ^sklad/?$ index.php?action=sklad
RewriteRule ^sklad/user/([0-9]+)?$ index.php?action=sklad&user=$1
RewriteRule ^sklad/folder/(.+)?$ index.php?action=sklad&folder=$1
RewriteRule ^sklad/file/(.+)?$ engine/ajax/sklad.php?file=$1
RewriteRule ^sklad/logout/?$ index.php?action=sklad&op=logout
...
RewriteRule ^admin/?$ admin.php
RewriteRule ^admin/news/?$ admin.php?action=news
the first five ones work fine. The admin/ one works fine. But when I try to access admin/news/, I get a blank page. No errors displayed or logged by Apache, and no output. admin.php?action=news is working fine.
Both sklad/ and admin/ folders physically exist on the server. BUT when I rename the admin/ folder to something else OR change the the last RewriteRule to something like
RewriteRule ^admin123/news/?$ admin.php?action=news
I can access admin123/news/. If it has something to do with the actual folder existing on the server, then why the first five rules are working? This doesn't make sense.
I'm out of ideas, hope someone here helps...
Yes, it's called news.php... I renamed the file and exerything is fine now, thanks! Didn't know about this, pretty unobvious bug (or not?)
It's not a bug, it sounds like content negotiation (via mod_negotiation) is turned on and it's doing something you don't want. Negotiation can be turned on via a type map or the MultiViews option. Typemaps are a little explicit to setup, so I'm assuming since you don't know why this is happening, you haven't set of a specific type that maps to news.php. So you've probably got Multiviews turned on. You can turn it off by either removing it from an Options statement:
# remove this word -----------v
Options Indexes FollowSymLinks Multiviews
This could be anywhere, in your htaccess, server config, vhost config, some config include file, etc. So you can also explicitly unset it in your htaccess file (as long as you aren't also explicitly setting it in the same file):
Options -Multiviews
I am not to good with htaccess and RegExp but i think admin/news will fall into your first htaccess rule.
RewriteRule ^admin/?$ admin.php
It wont proceed on your second rule on admin which is:
RewriteRule ^admin/news/?$ admin.php?action=news
Its the same problem I was facing before.
Try to modify your admin.php, echo/print something when there is no params pass. Something like this:
if($_GET['action'])
{
echo 'With Parameters';
}
else
{
echo 'No Parameters pass';
}
Debugged it that way.

using mod_rewrite to strip out junk

We're seeing some really weird URLs in our logs and I've been told to start redirecting them.
I know of a couple of better ways to go about fixing this, but the boss wants it done this way. I apologize in advance.
We're seeing stuff like the following in our logs:
http://www.example.com/foo/bar/bla&ob=&ppg=&rpp=100&ob=&rpp=&ppg=&rpp=30&ppg=&ppg=1&rpp=10&rpp=50&ob=&ob=&ob=&rpp=40&ob=&rpp=5&rpp=30&rpp=&rpp=20&order_by=&results_per_pge=75
I've been told to 'toss some mod_rewrite rules in the .htaccess file' to take this and strip out all the ob, rpp, and ppg variables.
Now, I've found ways to strip everything out. And that wouldn't be too bad if I could leave the /foo/bar/bla in there. But I can't seem to do that. Basically, any help would be appreciated.
Try:
# strip out any params that's ob=, rpp= or ppg=
RewriteRule ^/?(.*)&ob=([^&]*)&(.*)$ /$1&$3 [L]
RewriteRule ^/?(.*)&rpp=([^&]*)&(.*)$ /$1&$3 [L]
RewriteRule ^/?(.*)&ppg=([^&]*)&(.*)$ /$1&$3 [L]
# if everything's gone, finally redirect and fix query string
RewriteCond %{REQUEST_URI} !&(ob|rpp|ppg)
RewriteRule ^/?(.*?)&(.*) /$1?$2 [L,R=301]
The problem here is that your URL:
http://www.example.com/foo/bar/bla&ob=&ppg=&rpp=100&ob=&rpp=&ppg=&rpp=30&ppg=&ppg=1&rpp=10&rpp=50&ob=&ob=&ob=&rpp=40&ob=&rpp=5&rpp=30&rpp=&rpp=20&order_by=&results_per_pge=75
has A LOT of ob=, rpp=, and ppg= in the URI. More than 10. That means you'll get a 500 internal server error if you use these rules against that URL. By default, apache has the internal recursion limit set to 10, that means if it needs to loop more than 10 times (and it will for the above URL), it'll bail and return a 500. You need to set that higher:
LimitInternalRecursion 30
or some other sane number. Unfortunately, you can't use that directive in an htaccess file, you'll need to go into server or vhost config and set it.

htaccess rewrite working offline on WAMP but not online on linux host

I'm just going to explain my problem here :
http://mysite.com/movie/20000
should be rewritten to
http://mysite.com/movie.php?id=20000
my htaccess file :
Options +FollowSymlinks
RewriteEngine On
RewriteRule ^movie/([0-9]+)$ movie.php?id=$1
On my localhost WAMP installation this works fine, but when I put it online on my linux host it doesn't completely work. It does go to the movie.php page, but it seems it gives no GET parameter id.
Edit :
if I use
Options +FollowSymlinks
RewriteEngine On
RewriteRule ^movie([0-9]+)$ movie.php?id=$1
then
http://mysite.com/movie20000
Goes to the correct page, but I would like /movie/20000 and not just /movie20000
It also seems that my host automatically rewrites a visit to mysite.com/movie to mysite.com/movie.php
After searching for a long time, and pulling some of my lovely hair out I found the solution.
I just added
Options -MultiViews
to my htaccess file and that fixed it.
Why? Because .php was being added to urls without an extension, which I really did not need.
This should work.
RewriteRule ^movie/([0-9]+)$ http://mysite.com/movie.php?id=$1 [NC,L]
Don't forget the [NC, L] it means Case insensitive, last rule... If you don't, it will continue to process through your htaccess rules, maybe triggering other ones.
Still, the stuff below is good advice.... :)
Check to see if the Rewrite module is loading with apache. Look for this line in the httpd.conf file:
LoadModule rewrite_module modules/mod_rewrite.so
Check to see if your apache config allows for .htaccess files for your system or in the virtual host definition.
Also, test with a simpler rewrite catch all and test that alone to see if it's working at all like this (get rid of everything else in your htaccess file to limit the test):
RewriteEngine On
RewriteRule ^(.*)$ http://www.google.com [L,R=301]
Any request to your site should go to google if the configuration for apache is correctly set.

removing file extension with htaccess failing

i'm using an htaccess script trying to remove the .php testing the .htaccess on a testing server it runs fine, but on the live server that is a different host it trys rewriting the file based on the absolute path and the rewrite fails
here is the htaccess:
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME}\.php -f
RewriteRule ^(.*)$ $1.php
this is taking a url like this www.example.com/services
and trying to point it to /n/c/example.com/public/service.php
I know the {REQUEST_FILENAME} is suppose to be pulling the full local system path, but i don't understand why it's not finding the file. i know very little about htaccess and mod_rewriting so i'm not really sure what I should try to make it base everything off of just the url path, or if there is a better solution. I'm really open to suggestions.
Any help would be greatly appreciated.
Thanks
Use RewriteRule .* %{REQUEST_URI}.php [L]
It is hard to tell why your rule did not worked for you by having so little info about your Apache setup and any other rewrite rules that you may have.
Quite possible that the [L] flag did the trick for you -- you may have other rewrite rules that were rewriting this URL further, producing incorrect result in the end. I don't think that %{REQUEST_URI} did such a big job on its own, unless you have some symbolic links / aliases or even some transparent proxy in use which could make a difference.
Keep in mind, that the rules you have shown in your question cannot generate this sort of URL to be visible in browser's address bar (example.com//service.php/) -- it has to be a redirect (3xx code) involved .. which suggests that you have other rules somewhere.
Most likely it is a combination of your Apache specific settings & combined rewrite rules logic (where the L flag can make a big difference depending on those other rules).
The only way to give more precise answer will be enabling rewrite debugging and analyzing how rewrite was executed and what was involved.
Have you enabled mod_rewrite on the other server? AddModule mod_rewrite, I think.
Also - more likely - have you enabled .htaccess? You would need to have
AllowOverride All
or
AllowOverride FileInfo
for that.
These directives will need to go in the apache config files (usually /etc/httpd/conf/httpd.conf or one of the files in /etc/httpd/conf.d), and you will need to restart apache to get them to take effect.

Stop mod_rewrite returning REQUEST_URI when (.*) is empty

Options +FollowSymLinks
RewriteEngine On
RewriteRule ^mocks/site/(.*)$ http://thelivewebsite.com/$1 [R=301,L]
That is my htaccess file's contents.
The htaccess file is in the root directory of the hosting account and I just want to redirect the directory mocks/site/ to the new domain (with or without any extra directories).
eg: if someone goes to http://mywebsite.com/mocks/site then it needs to redirect to http://thelivewebsite.com. If they go to http://mywebsite.com/mocks/site/another/directory then it needs to redirect to http://thelivewebsite.com/another/directory. I hope that makes sense.
So the problem I have is that the htaccess code above seems to work pretty well when there is something after mocks/site/ however when there isn't something after that then the $1 in the redirect seems to reference the whole REQUEST_URI (eg: mocks/site/ rather than nothing - as there is nothing after it).
I don't know how to stop this. I thought about using a RewriteCond, but I'm not sure what to use there. I can't find anything that helps me to determine if there is anything after mocks/site/ or not.
Any help will be much appreciated.
Thank you.
That's very strange behaviour -- never seen anything like that. Therefore I think it could be something else (another rule somewhere -- on old or even new site). I recommend enabling rewrite debugging (RewriteLogLevel 9) and check the rewrite log (that's if you can edit Apache's config file / virtual host definition).
In any case, try this combination:
Options +FollowSymLinks
RewriteEngine On
RewriteRule ^mocks/site/$ http://thelivewebsite.com/ [R=301,L]
RewriteRule ^mocks/site/(.+)$ http://thelivewebsite.com/$1 [R=301,L]
It will do matching/redirecting in 2 steps: first rule is for exact directory match (so no $1 involved at all) and 2nd will work if there is at least 1 character after the /mocks/site/.
Alternatively (Apache docs even recommending this one) use Redirect directive (no need for mod_rewrite at all for such simple redirects):
Redirect 301 /mocks/site/ http://thelivewebsite.com/

Resources