shorten url using htaccess file? - apache

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.

Related

Apache2 RewriteRule 500 Internal Server Error

I'm attempting to rewrite my URL's and some are working but another (which is an extra directory level deep) produces a 500 internal server error. I'm not sure why this is happening and for various reasons am unable to turn on logging.
My .htaccess file looks like this:
Options +FollowSymLinks
RewriteEngine On
# Rewrite account/order.php
RewriteRule ^account/order/([a-z0-9]+)/.+$ /account/order.php?order_id=$1 [L]
# Rewrite advertiser.php
RewriteRule ^advertiser/([a-z0-9]+)/.+$ /advertiser.php?advertiser_id=$1 [L]
# Remove .php from URL
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME}\.php -f
RewriteRule ^(.*)$ $1.php
The URL for the rewrite rule for advertiser.php might look like this: http://domain.com/advertiser/1234
This works just fine.
However, my rewrite rule for account/order.php doesn't. It produces a 500 error. The URL might look like this: http://domain.com/account/order/1234
The only difference that I can see is that the rewrite rule has another directory in it that the working one does not. What am I missing that might cause this error?
Thanks!
Not sure why you have extra .+ in the end of patterns. Try this code:
ErrorDocument 404 default
Options +FollowSymLinks
RewriteEngine On
# Rewrite account/order.php
RewriteRule ^account/order/([a-z0-9]+)/?$ account/order.php?order_id=$1 [L,QSA,NC]
# Rewrite advertiser.php
RewriteRule ^advertiser/([a-z0-9]+)/?$ advertiser.php?advertiser_id=$1 [L,QSA,NC]
# Remove .php from URL
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME}\.php -f
RewriteRule ^(.*)$ $1.php [L]

htaccess cannot match the whole URL

I am accessing the following URL:
http://example.com/welcome
Where I have the following .htaccess
RewriteEngine On
RewriteRule ^(.*)$ /index.php?package=base&page=$1 [L]
I am expecting to return
package=base
page=welcome
But instead is giving me a "500 Internal Server Error".
If I change the htaccess to
RewriteEngine On
RewriteRule ^we(.*)$ /index.php?package=base&page=$1 [L]
It returns:
package=base
page=lcome
As expected, and if I change the htaccess to
RewriteEngine On
RewriteRule ^(.*)me$ /index.php?package=base&page=$1 [L]
It returns:
package=base
page=welco
As I was expecting as well.
Now the question is... why it does not math the whole URL? What I am missing here? How can I say "take everything the user passes and put it on a variable"?
Thanks!
The rewrite engine loops, so without some sort of conditions, the regex ^(.*)$ matches index.php and so on. Try
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ /index.php?package=base&page=$1 [L]

How to check time spent by mod_rewrite when rewrite urls?

My question is simple:
Is it possible to know the time elapsed when apache mod_rewrite rewrite urls ?
My site has about 20 million requests/month.
In this case, I want to know the time spent in these rules.
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
# Remove Multiple slashes in betweeen
RewriteCond %{REQUEST_URI} ^(.*)//(.*)$
RewriteRule . %1/%2 [R=301,L]
# Send everything to index.php
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ some_path/index.php/$1 [L]
</IfModule>
Thanks in advance
Move rewriting to VirtualHost configuration if possible, so regular expressions are not compiled for each request in .htaccess.
For example, for Apache, in httpd.conf place your content of .htaccess like this:
<Directory /www/htdocs/example>
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
# Remove Multiple slashes in betweeen
RewriteCond %{REQUEST_URI} ^(.*)//(.*)$
RewriteRule . %1/%2 [R=301,L]
# Send everything to index.php
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ some_path/index.php/$1 [L]
</IfModule>
</Directory>
You could check the "waiting" time in Firebug or other Browser tools to check how much time is spent between the request and your browser actually receives data.
Redirecting to static ressources would of course be better to avoid evaluating the time PHP takes to process the request.
Of coure it will still include the time Apache normally spends treating the request and you probably want to test both scenarios: with redirect and without.
BTW, if you're looking to optimize these, you could try replacing this :
RewriteCond %{REQUEST_URI} ^(.*)//(.*)$
RewriteRule . %1/%2 [R=301,L]
With this :
RewriteRule ^(.*)//(.*)$ $1/$2 [R=301,L]
There's no real need to use this kind of rewritecond alone, a more complex rewrite rule is enough.
Also,
RewriteRule ^(.*)$ some_path/index.php/$1 [L]
Can be replaced with
RewriteRule (.*) some_path/index.php/$1 [L]
Starting and ending character won't be sent in $1 so it can be included in the rule, hence simplifying it.

URL rewrite : internal server error

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]

subdomain htaccess

I have here a subdomain which i wish to pass on.
here the example of url : http://subdomain.domain.com/login
and it should point to : http://subdomain.domain.com/index.php/login
i write a simple htaccess
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond $1 !^(index\.php|images|robots\.txt|css|javascript)
RewriteRule ^(.*)$ index.php/$1 [L]
but i always get 500 server error. any body have idea where i wrong?
thanks for any help
It's normal, you go to http://subdomain.domain.com/login, get redirected to http://subdomain.domain.com/index.php/login, then to http://subdomain.domain.com/index.php/index.php/login and so on because you RewriteRule always match.
You can write `RewriteRule ^([^/]*)$ index.php/$1 [L]
Make sure Apache rewrite module is active and your .htaccess file has the following line before any rewrite rule:
RewriteEngine On
Assuming you have mod_rewrite enabled, your RewriteRule causes an infinite redirection loop, which exceeds the maximum number of redirects and causes an internal server error.
You need to condition your rule so it only rewrites once. For example, this should work:
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*)$ index.php/$1 [L]