URL rewrite : internal server error - apache

I have a little problem on Apache's rewrite rules
Here's my rules
Options +FollowSymLinks
RewriteEngine On
RewriteBase /
RewriteRule query/(.*) /php/query.php?name=$1 [L]
RewriteRule page/(.*) /php/page.php?page=$1 [L]
It works perfectly. But when I try to add the following rule to rewrite URL that not matches the two previous rules
RewriteRule .* /php/page.php?page=home
The server responds "Internal server error". Why ?

You can use RewriteLog to see what happends, but even with a [L] you can be sure a rewrited url is always re-checked on the set of rules (this is call internal redirect).
So add some RewriteCond before this final catch-all, or prevent it to be running on internal redirects, this way:
RewriteCond %{ENV:REDIRECT_STATUS} ^$
You could also add the [NS] or [nosubreq] tag on your final catch-all, which does the same.
But preventing your rule on internal redirection also means it will never be applied after any previous rule, and one day you might want it. So be careful with next rules.

Thanks !
Finally, here's my solution :
Options +FollowSymLinks
RewriteEngine On
RewriteBase /
RewriteRule query/(.*) /php/query.php?name=$1 [L]
RewriteRule page/(.*) /php/page.php?page=$1 [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^ page/home [L,R]
RewriteRule ^$ page/home [NS,R]

Related

Combine mod_rewrite rules

In my .htaccess I've got the usual rewrite rules but I need to add a HTTP to HTTPS rule. If I put the new rule after the existing rules it does not work but putting it before works but then I suspect the vanilla WordPress code does not work.
I've put the rules together by adding the last two lines of the second rule to the end of the first one but that does not work either. I'm not sure what I'm doing!
What is the best way to combine these two?
# BEGIN WordPress
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
</IfModule>
# END WordPress
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteCond %{SERVER_PORT} 80
RewriteRule ^(.*)$ https://127.0.0.1/$1 [R,L]
</IfModule>
The ruleset that's responsible for ensuring https is doing an external redirect, while the other one (wordpress) is doing internal rewrites.
It's often a good practice to first put the external redirects (if they don't depend on any previous internal rewrite).
Note the L flag:
The [L] flag causes mod_rewrite to stop processing the rule set. In most contexts, this means that if the rule matches, no further rules will be processed. This corresponds to the last command in Perl, or the break command in C. Use this flag to indicate that the current rule should be applied immediately without considering further rules.
If you put wordpress rewrite rules before the https ruleset, the rewrite engine will never get to the second ruleset. That's because of the L flag that instructs the rewrite engine to stop processing of any other rules. This reason aside, you don't want to rewrite the request to wordpress' index.php and then ensure that it's https using an external redirect (R flag), right?
So, you might want to try this:
<IfModule mod_rewrite.c>
RewriteEngine on
RewriteBase /
# HTTPS:
RewriteCond %{SERVER_PORT} 80
RewriteRule ^(.*)$ https://127.0.0.1/$1 [R,L]
# WordPress:
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
</IfModule>
Few final notes:
You only need one RewriteEngine on and one IfModule.
It's better to use a 301 redirect for https and www redirects. (R=301)

htaccess rewrite rule does not work

I am facing problem with rewrite rule in htaccess file. Please help.
This is my current htaccess file
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /product-project/
RewriteRule . index.php [L]
</IfModule>
Now I want to create a rewrite rule such as "product/category/id" should redirect to "product/profile?profile_id=id". For this I have used
RewriteRule ^product/.*/(.*)$ product/profile?profile_id=$1 [L,R]
which is working fine in some way.
1st problem -> It is redirecting properly, but URL also changes. It should stay as "product/category/10", if I use the id as 10. But when I use this, it is redirecting properly, but URL changes to "product/profile?profile_id=10". I read somewhere to use [L,P] instead of [L,R] , but it is giving as Server error.
2nd problem -> Now I want to create a new rewrite rule such as "product/id" should also redirect to "product/profile?profile_id=id". For this I have used
RewriteRule ^product/(.*)$ product/profile?profile_id=$1 [L,R]
Now this is not working & showing server error
3rd Problem -> Can I also create a new rewrite rule such as "/id" should also redirect to "product/profile?profile_id=id". Is this possible ?
4th Problem -> Can I also create a new rewrite rule such as "/id1/id2" should also redirect to "product/profile?profile_id=id1&serial_id=id2". Is this possible ?
Thanks in advance for your time.
Is this what you want please check.
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME}.php -f
RewriteRule ^([a-zA-Z0-9_-]+)/([a-zA-Z0-9_-]+)/([a-zA-Z0-9_-]+)$ $1/$2?profile_id=$3
for two id's
RewriteRule ^([a-zA-Z0-9_-]+)/([a-zA-Z0-9_-]+)/([a-zA-Z0-9_-]+)/([a-zA-Z0-9_-]+)$ $1/$2?profile_id=$3&id=$4
Use it..
Options All -Indexes
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ index.php/$1 [L]

shorten url using htaccess file?

I am completely beginner to htaccess, I am trying to shorten my following url..
From
http://website.com/index.php?student-name=john
http://website.com/index.php?teacher-name=amy
http://website.com/index.php?class=xxx
To
http://website.com/john
http://website.com/amy
http://website.com/xxx
I have tried following .htaccess code,
Options +FollowSymlinks
RewriteEngine On
RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^([^/]+)/?$ /index.php?student-name=$1 [L]
RewriteRule ^([^/]+)/?$ /index.php?teacher-name=$2 [L]
RewriteRule ^([^/]+)/?$ /index.php?class=$3 [L]
but, i shows "500-Internal servor error"....
EDIT :
when i am trying to use one rewrite_rule, its works fine. Like
RewriteRule ^([^/]+)/?$ /index.php?student-name=$1 [L]
(or)
RewriteRule ^student/([^/]+)/?$ /index.php?student-name=$1 [L]
when i am trying to use two or more rewrite_rule, its shows "500-Internal servor error". Like
RewriteRule ^([^/]+)/?$ /index.php?student-name=$1 [L]
RewriteRule ^teacher/([^/]+)/?$ /index.php?teacher-name=$1 [L]
(or)
RewriteRule ^student/([^/]+)/?$ /index.php?student-name=$1 [L]
RewriteRule ^teacher/([^/]+)/?$ /index.php?teacher-name=$1 [L]
Its shows error log is: "Request exceeded the limit of 10 internal redirects due to probable configuration error. Use 'LimitInternalRecursion' to increase the limit if necessary. Use 'LogLevel debug' to get a backtrace."
what's that mean?
This is a bad idea. Why? How does Apache know if the string in the first path segment is a student, teacher or class? It doesn't, so it will always rewrite to a student-name.
Instead use urls like:
http://example.com/student/john
http://example.com/teacher/amy
http://example.com/class/xxx
Now the rewrite is trivial, since each group has a common prefix.
Options +FollowSymLinks
RewriteEngine On
RewriteBase /
RewriteRule ^student/([^/]+)/?$ /index.php?student-name=$1 [L]
RewriteRule ^teacher/([^/]+)/?$ /index.php?teacher-name=$1 [L]
RewriteRule ^class/([^/]+)/?$ /index.php?class=$1 [L]
As for the 500 internal server error you need to check your Apache error log. Make sure that mod_rewrite is enabled, and that you restarted your Apache after you did this. Besides the rules, I changed the lowercase l in FollowSymLinks into an uppercase L, but I am unsure if this can cause any problems.

.htaccess is concatenating rules

I have a .htaccess file:
Options +FollowSymLinks
RewriteEngine on
RewriteRule ^([a-zA-Z-]+)\/([0-9]*)\/?$ ler.php?categoria=$1&id=$2
this is working for http://www.domain.com/frases/13571/
The point is that I need to redirect all HTTP to HTTPS after this rule is already applied.
So I write this:
Options +FollowSymLinks
RewriteEngine on
RewriteRule ^([a-zA-Z-]+)\/([0-9]*)\/?$ ler.php?categoria=$1&id=$2
RewriteCond %{HTTPS} off
RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI} [R=301,L]
But isn't working like I supposed to. I'm getting this when I perform a HTTP request:
https://www.domain.com/frases/13571/?categoria=frases&id=13571
What is the right code that just change the protocols without modify the others parts of url?
I think that my code is doing 2 requests in the first rules and that is generating this wrong url.
L flag must be applied to your rewrite rule.
You can use this code instead
Options +FollowSymLinks
RewriteEngine on
RewriteCond %{HTTPS} off
RewriteRule ^(.*)$ https://%{HTTP_HOST}/$1 [R=301,L]
RewriteRule ^([^/]+)/([^/]+)/$ /ler.php?categoria=$1&id=$2 [L]
Note:
you don't need to escape slashes (\/ can be /)
you'll need to clear your browser's cache before trying again with this code. Your old rule is now in cache and you won't see the new code working if you don't clear it.
RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI} [R=301,L]
You rewrite from the original REQUEST_URI, the current is what you have captured, so try:
RewriteRule (.*) https://%{HTTP_HOST}$1 [R=301,L]
or
RewriteRule (.*) https://$1 [R=301,L]
If not working, rewrite log could be useful.

Simple mod_rewrite rule for adding /

I have an URL http://domain.com/test/main/getbts?_dc=13 and would like to add a / before the ?-mark in order for the URL to look: https://domain.net/test/main/getbts/?_dc=13
I tried the following Rewrite Rule:
RewriteRule ^test/main/getbts/\?_dc\=([^/]*)$ /test/main/getbts?_dc=$1 [L]
But it does not seem to work. My other rewrite rules (I have not used at the time I tested my first rule) are:
RewriteEngine On
RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ index.php [L]
Could anyone give me a hint where to look or how to rewrite my rules?
Thank you very much in advance!
You can't match against the query string in a RewriteRule, just the URI. And in this case, you can just ignore it since it'll automatically get appended to the end. You just need:
RewriteRule ^admin/main/getcbts$ /admin/main/getcbts/ [L,R=301]
This redirects the browser so they see a / at the end of the URI in the location bar.