Mod Rewrite not working correctly - apache

I have written a simple mod rewrite script to turn website.com/index.php?var1=1&var2=2&var3=3 into website.com/index/1/2/3. For some reason it's not working, any ideas why?
#RewriteRule ^$ index.php [QSA]
RewriteCond %{REQUEST_FILENAME}\.php -f
RewriteRule ^(.+)$ $1\.php [QSA]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.+)$ index.php/$1 [QSA]
RewriteRule ^([a-zA-Z0-9]+)/([a-zA-Z0-9]+)/([a-zA-Z0-9]+)$ comments.php?var1=$1&var2=$2&var3=$3

The first rule rewrites index/1/2/3 to index/1/2/3.php.
then the second rule rewrites this to index.php/index/1/2/3.php
and finally the last rule doesn't match.
If you want to rewrite website.com/index.php?var1=1&var2=2&var3=3 into website.com/index/1/2/3, you must capture the query string arguments with RewriteCond and insert them into a RewriteRule
RewriteEngine on
RewriteCond %{QUERY_STRING} var1=(.*?)&var2=(.*?)&var3=(.*?)
RewriteRule ^index.php$ /index/%1/%2/%3 [L]
If you want to redirect instead of internally rewrite, i.e. show the new URL in the browser, use [R,L] as RewriteRule flags
RewriteRule ^index.php$ /index/%1/%2/%3 [R,L]

It looks like the rewrite on line 6 will catch that and send it to index.php. It's hard to tell not knowing what things are files and directories, but I would guess that it isn't. If you have access to the httpd.conf you can turn up the rewrite logging, set
RewriteLogLevel 8
And it will log far more information than you need to debug this. On newer versions of apache the setting is set with LogLevel e.g..
LogLevel alert rewrite:trace8
which may be allowed in vhosts or htaccess so look it up in your version's docs.
Don't leave this on as it will seriously impact performance.

Related

htaccess from https to http

I have these vales in my htacces file it all works fine except when i try to go back to http from https i have tried swapping the rules around with no success, any help would be awsome
I have tried all the sujestion with still no suucess so maybe i need to show you guys the entire thing.
Still not going back to http from https, here is the whole thing
Have i got the rules in the wrong order? im lost
<ifModule mod_rewrite.c>
RewriteEngine on
# For Sales:
RewriteRule ^shop/sales/?$ sales.php
# For the primary categories:
RewriteRule ^shop/([A-Z-Aa-z\+]+)/?$ shop.php?type=$1
# For specific products:
RewriteRule ^browse/([A-Za-z\+]+)/([A-Za-z\+\-]+)/([0-9]+)$ browse.php?type=$1&category=$2&id=$3
#For https pages:
#RewriteCond %{HTTPS} on
#RewriteRule ^(.*)$ http://%{HTTP_HOST}%{REQUEST_URI} [R=301,L=301]
#RewriteCond %{HTTPS} off
#RewriteRule ^(checkout\.php|final\.php|admin/(.*))$ https://{HTTP_HOST}/$1[R=301,L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ index.php?$1 [L,QSA]
RewriteCond %{THE_REQUEST} ^[A-Z]{3,}\s(.*)/index\.php [NC]
RewriteRule ^ /%1 [R=301,L]
</ifModule>
I am not able to test the rules, but I think you need to change the following:
In the first rule your flag is attached to the 2nd argument. This should create an internal error. Your second rule would rewrite all url's to their http equivalent, making an infinite loop. You need to make sure it doesn't match url's that you want to be in https. You can do this with %{REQUEST_URI} and a negation (!). As far as I am aware, L=301 is an invalid flag too. You probably meant to make it R=301.
RewriteCond %{HTTPS} off
RewriteRule ^(checkout\.php|final\.php|admin/(.*))$ https://{HTTP_HOST}/$1 [R,L]
RewriteCond %{HTTPS} on
RewriteCond %{REQUEST_URI} !/(checkout\.php|final\.php|admin/(.*))$
RewriteRule ^http://%{HTTP_HOST}%{REQUEST_URI} [R,L]
Last but not least an word of advice. Don't test your .htaccess with permanent redirects until everything works as expected. The browser will cache permanent redirects, not picking up further tries to make your .htaccess work as you want.

mod_rewrite for clean URL's not working

I have looked at every question and every example of reWriteRule for an apache server... Nothing has worked.
I just need to change
http://beta.EXAMPLE.com/profile.php?profile_name=ntgCleaner
to
http://beta.EXAMPLE.com/ntgCleaner
I have to see if my .htaccess file is being read and checked to see if mod_rewrite is enabled and they both work perfectly fine.
For some reason, the examples that I have come across are not working for me. Here are some of the examples.
RewriteEngine On
RewriteRule /(.*)$ /profile.php?username=$1
,
RewriteEngine On
RewriteBase /
RewriteRule ^profile\/(.*)$ ./profile.php?profileId=$1 [L,NC,QSA]
and
Options +FollowSymlinks
RewriteEngine on
RewriteOptions MaxRedirects=10
RewriteRule ^([a-zA-Z0-9_-]+)$ profile.php?profile_name=$1
RewriteRule ^([a-zA-Z0-9_-]+)/$ profile.php?profile_name=$1
But none of these work. Is this because I am using a subdomain? I plan on eventually switching over the subdomain from BETA to just www when I finish the site.
Any advice?
Try this:
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^([a-zA-Z0-9_-]+)/?$ /profile.php?profile_name=$1 [L,QSA]
Your examples have a lot of different query strings in it, so I'm not sure which one is the one you really want. You have ?username=, ?profileId=, ?profile_name=.
You must use condition (RewriteCond) and when is condition met, rule (RewriteRule) is applicated. So, when you don't use condition, rule is not used, because engine don't know for what to use it.
RewriteCond must be used before RewriteRule, I use it against web-bots in this form:
RewriteCond %{REMOTE_HOST} .googlebot.com$ [NC,OR]
RewriteCond %{REMOTE_HOST} .search.msn.com$ [NC,OR]
RewriteCond %{REMOTE_HOST} .kimsufi.com$ [NC]
RewriteRule ^.*$ /errors/404.html [F]

htaccess for redirect to SSL

For the past few hours (days) I have been having some trouble redirecting a
page to SSL.
My setup is as follows: I have the following .htaccess for an e-commerce site
on Apache 2.2.16 on Debian (all required mods enabled)
RewriteEngine On
RewriteBase /shop
RewriteCond $1 !^(index\.php|products|img|theme\.php|checkout\.php)
RewriteRule ^(.*)$ index.php?/$1 [L]
all requests are passed to index.php which acts as my controller and includes
other .php files as necessary.
I now want to use HTTPS for the checkout process which is a php script
cleverly called checkout.php
I thought it would be as easy as changing my .htaccess to:
RewriteEngine On
RewriteBase /shop
RewriteCond %{SERVER_PORT} !^443$
RewriteCond %{SERVER_URI} checkout\.php
RewriteRule ^checkout.php?/$1 https://localhost/shop/checkout.php?/$1 [L,R]
RewriteCond $1 !^(index\.php|products|img|theme\.php|checkout\.php)
RewriteRule ^(.*)$ index.php?/$1 [L]
so that checkout.php is not processed by index.php.
Apparently it is not that simple. I could probably do it by using a hardcoded
https link to checkout but I would prefer to do it with mod_rewrite.
If anyone can share some insight into
this it would be really appreciated.
Thanks in advance
There are a few problems. First, the pattern in your first RewriteRule
RewriteRule ^checkout.php?/$1 https://localhost/shop/checkout.php?/$1 [L,R]
is written incorrectly. $1 isn't meaningful there (it's a capture result, but no capture has happened yet), and also the query string (part of the request after the ?) isn't part of what's matched, as the RewriteRule documentation says.
Second, I think you meant to use REQUEST_URI instead of SERVER_URI.
So I think you want something like this:
RewriteCond %{HTTPS} off
RewriteCond %{REQUEST_URI} ^/checkout\.php
RewriteRule .* https://localhost/shop/checkout.php [L,R]
RewriteCond %{REQUEST_URI} !^/(index\.php|products|img|theme\.php|checkout\.php)
RewriteRule ^(.*)$ /index.php?/$1 [L]
A few notes:
You don't need to match or add back in the query string in the first RewriteRule; mod_rewrite will automatically add it back in.
It's conventional to test RewriteCond %{HTTPS} off instead of
RewriteCond %{SERVER_PORT} !443, as #Jon Lin suggests.
You may want to add the QSA flag in your second RewriteRule.

Need help with Apache Rewrite issues

My developer has provided me some Apache rewrite rules that are required for our application to work. When I added them to Apache my www.domain.com/blog and www.domain.com/phpmyadmin pages no longer worked. I tried to add the first RewriteCond rule for my blog and also the final phpmyadmin rule but neither one is working as expected. Essentially I want any requests to /blog or /phpmyadmin to NOT rewrite and go to my document root directory and run those applications outside of rewrites. Can you help me figure out a solution? Thanks
RewriteCond %{REQUEST_URI} !^/blog/
RewriteRule ^/(.*_css.*\.css.*) /$1 [QSA,L]
RewriteRule ^/(.*_js.*\.js.*) /$1 [QSA,L]
RewriteRule ^/(.*_swf.*\.swf.*) /$1 [QSA,L]
RewriteRule ^/(.*_img.*\.[jpg|JPG|jpeg|JPEG|gif|GIF|bmp|BMP|png|PNG].*) /$1 [QSA,L]
RewriteRule ^/(.*)$ /index.php?url=$1 [QSA,L]
RewriteRule ^/phpmyadmin(.*)$ /phpmyadmin$1 [QSA,L]
</VirtualHost>
They are located at www.domain.com/blog and www.domain.com/phpmyadmin.
Apache 2.2.13
Thanks!
If you want to avoid rewriting URLs that begin with /blog/ or /phpmyadmin/ then you may be able to get away with the first rule being:
RewriteRule ^/(?:blog|phpmyadmin)/ - [L]
(replacing your RewriteCond and then removing the old phpmyadmin rule).
A quick explanation: this matches any URLs that begin with /blog/ or /phpmyadmin/ and doesn't rewrite them (- for the replacement), and then stops any further rewriting ([L]).
Previous answer:
Your rewrite rules are conflicting, for a start. Also, at the moment, the RewriteCond only applies to the first rule. Also, the final rule is ignored because of the rule before it matching everything. You may want something like this:
RewriteRule ^/blog/(.*)$ /index.php?url=$1 [QSA,L]
as I assume you're just trying to rewrite all URLs from /blog/foo/bar to /index.php?url=foo%2fbar? If not, please explain what you're trying to accomplish and I'll edit my answer.
Err... not sure what you are trying to do. Are you trying to "Exclude" static files as images/stylesheets/flash movies/javascript files and the link to PHPMyAdmin? Maybe something like this could do the job for you 'quick 'n dirrrrty'
# Enable the RewriteEngine
RewriteEngine On
RewriteBase /
# Check if the file, directory or symlink does not already exists.
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-F
RewriteCond %{REQUEST_FILENAME} !favicon\.ico
RewriteCond %{REQUEST_FILENAME} !robots\.txt
# Rewrite all other requests to the index.php
RewriteRule ^(.+)$ /index.php?url=$1 [QSA,L]

Multiple RewriteConds and RewriteRule Stacked Together

I have this apache rewrite rule:
RewriteEngine on
RewriteBase /
RewriteCond %{HTTP_HOST} mycompany.com
RewriteRule ^$ http://mycompany.com/login [L]
# we check if the .html version is here (caching)
RewriteRule ^$ index.html [QSA]
RewriteRule ^([^.]+)$ $1.html [QSA]
RewriteCond %{REQUEST_FILENAME} !-f
# no, so we redirect to our front web controller
RewriteRule ^(.*)$ index.php [QSA,L]
The only thing I can make sense of is if it's mycompany.com, then the script will redirect to http://mycompany.com/login. If not, then ...
I can't figure out already.
Any idea what does the above script say?
Something quite interesting, not easy to understand.
A google search on the comment texts inside the code gave interesting results: http://www.google.com/search?q=%22%23+we+check+if+the+.html+version+is+here+%28caching%29%22
Edit: if we look at the last lines and knowing that Symfony uses caching (it creates local files with .html extension in the same directories as the URL shows 'em) I can try to explain the lines here
If the requested url is something like http://yoursite.com/blabla/ we try to open an index.html file in that directory. If the file is not there, another cycle of rewriting will happen and the last Cond will be hit (where the file does not exist)
RewriteRule ^$ index.html [QSA]
If something more is in the url, like http://yoursite.com/blabla/blblbl, try to find a file blblbl.html
RewriteRule ^([^.]+)$ $1.html [QSA]
This is the collector of all urls that did not match any of the previous rules or the cached file did not exist:
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*)$ index.php [QSA,L]