.htaccess RewriteRule outputs wrong parameter result - regex

I am trying to use .htaccess RewriteRule to beautify some urls, but I've got a problem that I can't fix.
I've written this:
RewriteEngine On
RewriteRule ^(.*)/(foro|forum)$ code/forum/forum.php?id=$1
RewriteRule ^(.*)/(foro|forum)/(.*)$ code/forum/forum.php?id=$1&subf=$3
RewriteRule ^(.*)/(foro|forum)/(.*)/(.*)$ code/forum/forum.php?id=$1&subf=$3&post=$4
The first url rewrite works properly, showing as result the id parameter (I.e. localhost/web/user501/forum -> id=user501).
It happens the same with the second one (localhost/web/user501/forum/3 -> id=user501, subf=3).
But when I try the third url rewrite, somehow the output id is not 'user501' as I expect, but 'code/forum/forum.php'.
The output of the other vars is normal (localhost/web/user501/forum/3/5 -> id=code/forum/forum.php, subf=3, post=5).
I tried to change the first (.*) on that url rewrite for a fixed word... it worked, but unfortunately I need it to be a changeful word.
Does someone know what's happening?

That is because ^(.*)/(foro|forum)/(.*)/(.*)$ pattern also matches code/forum/forum.php hence RewriteRule runs again and gives you wrote results.
Try this code:
RewriteEngine On
# ignore /code/forum/forum.php
RewriteRule ^code/forum/forum\.php$ - [L,NC]
RewriteRule ^(.*)/(foro|forum)$ code/forum/forum.php?id=$1 [L,QSA]
RewriteRule ^(.*)/(foro|forum)/(.*)$ code/forum/forum.php?id=$1&subf=$3 [L,QSA]
RewriteRule ^(.*)/(foro|forum)/(.*)/(.*)$ code/forum/forum.php?id=$1&subf=$3&post=$4 [L,QSA]

Related

Apache url rewriting and loop

setting url rewriting to have nice urls, i have existing urls like that :
/xxx/test.php
but in the background, it is allways going to the same script with a query :
/xxx/index.php?id=test
with the following rewrite :
RewriteRule ^xxx/([0-9a-z\-]*)\.php$ /xxx/index\.php?id=$1 [QSA,L]
it's working fine.
now, there are old urls still like /xxx/index.php?id=$1
and i want to get rid of these old urls, meaning I want all of them to be for the users like /xxx/test.php with a 301 redirect
i did a rewrite for this but then i'm entering a loop despite the L flag
RewriteCond %{QUERY_STRING} ^id=(.*)$
RewriteRule ^xxx/index\.php$ /xxx/%1.php? [R=301,L]
? is it possible to handle that and how ?
and other to describe it is allways use the script :
/xxx/index.php?id=$1
but allways have the right url in the browser displayed
Keep your existing
RewriteRule ^xxx/([0-9a-z\-]*)\.php$ /xxx/index\.php?id=$1 [QSA,L]
which appears to work fine.
Add in these two lines before that which will catch if there is an id= and strip it out of the URL.
RewriteCond %{QUERY_STRING} ^id=([^&]*)(.*)$
RewriteRule ^xxx/([0-9a-z\-]*)\.php$ /xxx/index\.php?id=%1%2 [L,R=301]
^ start of query string
([^&])* any character except &
(.*) any following characters
So if query string is id=test&something=else RewriteRule will append exactly that and nothing else as there is no more QSA flag.
Try those 3 lines together (htaccess test website), here is the full htaccess file:
RewriteCond %{QUERY_STRING} ^id=([^&]*)(.*)$
RewriteRule ^xxx/([0-9a-z\-]*)\.php$ /xxx/index\.php?id=%1%2 [L]
RewriteRule ^xxx/([0-9a-z\-]*)\.php$ /xxx/index\.php?id=$1 [QSA,L]
Make your RewriteRule not match index.php or remove the QSA flag.
Say you type test.php well now you will go to index.php?id=test
Then Rewrite occurs again and you will go to index.php?id=index&id=test
Then it will occur again because the page is different: index.php?id=index&id=index&id=test etc.
So add in your regex a negative lookahead: xxx/(?!index)([0-9a-z\-]*)\.php
Try:
RewriteRule ^xxx/(?!index)([0-9a-z\-]*)\.php$ /xxx/index\.php?id=$1 [QSA,L]

htaccess Rewrite Rules appending parameter?

Our original urls began with a parameter and the following rewrite works to redirect them (thanks to Jon Lin).
However, the original parameter is being appended to redirect, so that
RewriteEngine On
RewriteCond %{QUERY_STRING} ^old-page$
RewriteRule ^$ /newpage [R=301,L]
ends up going to mydomain.com/newpage?old-page
Any idea how to fix? thanks again,
Geoff
Have it like this to strip off existing query string:
RewriteEngine On
RewriteCond %{QUERY_STRING} ^old-page$ [NC]
RewriteRule ^$ /newpage? [R=301,L]
Take note of ? at the end of target URI, that is used to strip-off existing query string.

HTACCESS PUZZLE! Why does "?" work in one Rewrite statement and doesn't in another? See example

So, I've been working on htaccess since like yesterday. I have two Rewrite statements in my htaccess file.
RewriteRule ^.*wp-login\.php\?loggedout=true.*$ /not_found [R,L]
The above statement works. While
RewriteRule ^.*wp-login\.php\?action=login.*% /not_found [R,L]
...doesn't!
To make the second case work, I used the following statements.
RewriteCond %{QUERY_STRING} action=logout
RewriteRule ^wp-login\.php$ /not_found/? [R,L]
So, not using "?action=logout" in the RewriteRule in the second case seems to solve the problem.
Yes, the problem is solved, but I'd like to understand why. This is so puzzling.
Any help is appreciated. Thank you.
Your earlier rules are incorrect because QUERY_STRING cannot be matched in RewriteRule. RewriteRule only match request uri without query string.
So correct rules are:
RewriteCond %{QUERY_STRING} (^|&)action=logout(&|$)
RewriteRule ^wp-login\.php$ /not_found/? [R,L]
OR this to include both query parameters:
RewriteCond %{QUERY_STRING} (^|&)action=(login|logout)(&|$)
RewriteRule ^wp-login\.php$ /not_found/? [R,L]

removing one of parameters from adress with htaccess

I need to remove unnecessary parameter from the URL.
URL looks like: example.com/index.php?page=shop.product_details&product_id=11824&category_id=5 and I need to remove category_id parameter by htaccess 301 redirect because it doesn't change anything no matter of given number.
I tried several formulas, my last try, based on my findings here and elsewhere in google is:
RewriteCond %{REQUEST_URI} ^\?page=shop\.product
RewriteCond %{QUERY_STRING} category_id
RewriteRule (.*) /$1? [R=301,L]
But nothing works, adress stil stays the same.
Mod_rewrite is on, before this I'm making 301 redirects using RewriteRules and everything works smoothly.
You can use this rule:
RewriteEngine On
RewriteCond %{QUERY_STRING} ^(.+?&)?category_id=[^&]*(.*)$
RewriteRule ^(index\.php)?$ %{REQUEST_URI}?%1%2 [R=301,L]

mod_rewrite / redirection with ? in a query string

I'm diving into the uses of htaccess/mod rewrite for the first time and I'm having a little bit of trouble with a redirect/mask.
I have a test directory in my root folder called modrw, in that folder is a index.php file with a nice and simple:
<?php echo $_GET['name']; ?>
In the browser if I type www.domain.com/modrw/{word}/ then the word is echoed on the page, which is what I want.
If I type www.domain.com/modrw/name={word} then I am redirected to www.domain.com/modrw/{word}/ and the word is also echoed as I intended.
However, if I direct the browser to the URL www.domain.com/modrw/?name={word}/ the word is echoed but I am not redirected to www.domain.com/modrw/{word}/ like I hoped.
How is the ? causing troubles? In the RewriteRule code below the ? is included, I've tried it a couple different ways but can't get it working.
Here is my htaccess file:
RewriteEngine on
RewriteCond %{HTTP_HOST} !^www\.
RewriteRule ^(.*)$ http://www.%{HTTP_HOST}/$1 [R=301,L]
RewriteCond %{REQUEST_URI} ^/[^\.]+[^/]$
RewriteRule ^(.*)$ http://%{HTTP_HOST}/$1/ [R=301,L]
RewriteRule ^modrw/?name=([^/\.]+)/?$ http://www.domain.com/modrw/$1 [R]
RewriteRule ^modrw/([^/\.]+)/?$ modrw/?name=$1
What is causing the problem, is there a specific way to include the ?, does it not pick this up at all? Am I taking completely the wrong approach?
I've also tried using Options +FollowSymlinks but I'm not entirely sure what this does nor if it's needed at all...
Remember that RewriteRuleonly matches REQUEST_URI. To match query string you must use RewriteCond with variable %{QUERY_STRING}. For ex. in your case:
RewriteCond %{QUERY_STRING} ^name=(.*)(&|$) [NC]
RewriteRule ^modrw /modrw/%1? [L,R,NC]