What does this code in HTACCESS say - .htaccess

I' am just a beginner trying to learn about HTACCESS but can't seem to find anything on Google that will explain what this code below means. I know it for making pretty URL's but what is the long description of it. Please can someone professional or experts can guide me in explaining this. Thanks!
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
</IfModule>

Let's look at it line by line
<IfModule mod_rewrite.c>
This says that whatever is between the tags should only be read if, and only if, mod_rewrite is installed and enabled on the target server.
RewriteEngine On
This turns the RewriteEngine on. Without it, no RewriteRules take effect. (docs)
RewriteBase /
RewriteBase is used when redirecting a request. As far as I am aware, it can never hurt to set it, even though sometimes it goes right automatically. (docs)
RewriteRule ^index\.php$ - [L]
This is the first RewriteRule. If a request is done to http://example.com/index.php (with or without a query string), the url is not rewritten. The [L] denotes that if this rule matches, it is the last rule that will be matched during this 'pass' through the file. Because the url is not rewritten, no further 'passes' through the .htaccess file are done.
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
If the previous rule didn't match, it will try to match this rule. This rule matches any url of at least 1 character. A request to http://example.com would not match this rule. If the first part of the RewriteRule matches, it will check the conditions. The first condition checks if the file that is requested (%{REQUEST_FILENAME}) is not an existing file (!-f). -f means "is an existing file" and the prefix ! negates that. The second condition is similar, but tests if the requested file is not an existing directory. If both conditions are true, the request will be internally rewritten to index.php. The [L] flag will stop rewriting for this pass, and during the next pass the first rule will match, and stop rewriting altogether.
See the documentation for more information about what is possible with RewriteCond and RewriteRule.

Related

Need Assistance for this Htaccess Rewrite Rule

I have a problem with my .htaccess, a short explanation I would like to set http://example.com/newest on my website. However, it always redirects to http://example.com/postname. Where I just need the exact "newest" page. Here is my code:
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteBase /
RewriteRule ^[^/]+$ %{REQUEST_URI}/ [L,R=301]
RewriteRule ^/category/(.*)$ page.php?f=$1
RewriteRule ^/search/(.*)$ search.php?f=$1
RewriteRule ^(.*)/$ post.php?f=$1 <- If this is removed, my post htaccess will not work
RewriteRule ^newest/$ index.php?f=newest <- I want to execute this code
I really don't know what this is called, I have been looking for the whole stackoverflow but I did not get any answer. Please remain me if this is a duplicate question.
As Mohammed implied in comments, your directives are in the wrong order. The line above your "newest" rewrite is a catch-all and rewrites all requests, so the last line will never match.
http://example.com/newest
Note that your rules imply that your URLs should end in a trailing slash. So, you should be linking to http://example.com/newest/ (with a trailing slash), not http://example.com/newest, otherwise your users will get a lot of unnecessary redirects.
However, you appear to be under the belief that the RewriteCond directive applies to all the directives that follow. This is not the case. It only applies to the first RewriteCond directive. You also need some L flags to prevent further processing.
You also have a slash prefix on the "category" and "search" rewrite patterns, so these would never match in a .htaccess context.
Try something like the following instead:
RewriteEngine On
RewriteBase /
# Don't process the request further if it maps to an existing file
RewriteCond %{REQUEST_FILENAME} -f
RewriteRule ^ - [L]
# Append trailing if omitted
# Although strictly speaking this only redirects if there are no slashes at all in the URL
RewriteRule ^[^/]+$ %{REQUEST_URI}/ [L,R=301]
RewriteRule ^category/(.*)$ page.php?f=$1 [L]
RewriteRule ^search/(.*)$ search.php?f=$1 [L]
RewriteRule ^newest/$ index.php?f=newest [L]
RewriteRule ^(.*)/$ post.php?f=$1 [L]

.htaccess issue with image handling

I'm trying to redirect:
All pages to index.php (this is working).
/products/large/12345.jpg to /classes/watermark/handler.php?size=large&photo=12345.jpg (this is not).
### OPTIONS ###
Options +FollowSymLinks -Indexes -MultiViews
AddDefaultCharset UTF-8
### REWRITE ###
RewriteEngine On
RewriteBase /
### CONDITIONS ###
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
### RULES ###
RewriteRule ^([^?]*)$ /index.php?path=$1 [NC,QSA]
RewriteRule ^/products/(.*)/(.*)$ /classes/watermark/handler.php?size=$1&photo=$2
The issue is that apache returns internal redirect error.
You have the directives in the wrong order. You need to have the more specific rule first. Like you say, you are rewriting "all pages to index.php". If you have already written to index.php, how are you expected to rewrite /products/....?
However, you also have an error in your RewriteRule pattern. In .htaccess, the URL-path matched does not start with a slash. So, this will never match anyway.
Note also that RewriteCond directives only apply to the first RewriteRule that follows. RewriteCond and RewriteRule directives together form a single "rule". You shouldn't necessarily separate conditions and RewriteRule directives, they work together (and can "talk" to each other).
Try something like this instead:
# Rewrite images
RewriteRule ^products/(.*)/(.*)$ /classes/watermark/handler.php?size=$1&photo=$2 [L]
# Rewrite all other pages
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ /index.php?path=$1 [QSA,L]
Note I've also added the L (last) flag to prevent the following directive being processed.
Not sure why you had [^?]* as your pattern? The query string is not matched by the RewriteRule pattern. So, this can probably be simplified to .* (as above).
Depending on your URL structure, you might also want to confirm that an image is being requested? ie. a request for a URL ending .jpg? Rather than something like /products/large/<something>. You could also validate the "size" ie. (small|medium|large).
The issue is that apache returns internal redirect error.
Well, I can't see where that would be happening in the code you posted? (As mentioned, in the code you posted, that additional directive wouldn't have done anything.)

htaccess redirection dynamic

I am trying to redirect /en/news/12345 to http://www.xyz.com/en/newsletters/12345
the only thing is that "en" and "12345" can change but "news" is always the same.
I have the following so far:
RewriteRule /^(.)/news/(.)$ http://www.xyz.com/$1/news/$2 [R=301,L]
but if i go to mydomain/wp-admin then i get an endless redirect?? Any ideas why this is happening?
Thanks
Options +FollowSymlinks
RewriteEngine on
RewriteRule ^en/news/([0-9]) http://www.xyz.com/en/newsletters/$1 [NC]
Please try this, hope it will solve your problem
I think I found the problem in your .htaccess file. Initially you had two conditions that prevented RewriteRule . /swissfil3/index.php [L] (catch-all) from redirecting when the path pointed to an existing file or folder (ignore-on-file):
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond only applies to the rule directly followed by the condition.
When you added a new rule directly below these directives, the catch-all rule was not prevented from redirecting existing files or directories like /wp-admin. I.e. every request not matching any rules before catch-all would be redirected to /swissfin/3/index.php.
In additoin you used (.) to capture each part of the path. This would match one arbitrary character, but no more, so your redirect would be limited to /X/news/Y, instead of /XX/news/YYYY..., to fix this you can use (.+) which will match zero or more chars, or even better ([^/]*) which will match zero or more characters not equal to /.
You should be able to avoid these problems by using the following code (where the catch-all directive has been moved directly below ignore-on-file, and the rewrite rule matches zero or more chars not equal to /):
# ...
RewriteRule ^([^/]*)/news/([^/]*)$ http://www.xyz.com/$1/news/$2 [R=301,L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /swissfin3/index.php [L]
Here you match every URL that contains a char

mod_rewrite rule to match exact URL only

I'm having an issue with mod_rewrite where I want to match—and replace—a specific URL. The URL I want to rewrite is:
http://example.com/rss to http://example.com/rss.php
That means, if some one were to append anything after rss a 404 Not Found response be sent. Currently I'm using this mod_rewrite snippet:
Options -Indexes
RewriteEngine on
RewriteBase /
# pick up request for RSS feed
RewriteRule ^rss/?$ rss.php [L,NC]
# pass any other request through CMS
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.+) index.php/$1
But this matches rss and rss with anything else added to the end. How can I re-write the above to acces only http://example.com/rss as the pattern for mod_rewrite to match against?
You are getting this error because /rss is being redirected twice in your rules by both RewriteRules. Have your rules like this:
Options +FollowSymlinks -MultiViews -Indexes
RewriteEngine On
RewriteBase /
# pick up request for RSS feed
RewriteRule ^rss/?$ /rss.php [L,NC]
# pass any other request through CMS
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule (?!^rss\.php$)^(.*)$ /index.php/$1 [L,NC]
So with above rules it will redirect /rss OR rss/ URIs to /rss.php however /rss/foo will be redirected to /index.php since your 2nd rule is forwarding everything to /index.php
I was suprised to see that your rules just don't work, because in my first attempt I would have come to a very similar solution. But looking at the rewrite log revealed the real issue.
As discribed here the server prefers real files over directories. So internally rss/something becomes rss.php/something when applying the rewrite rules and things get weird.
So, one solution is to check if the Option MultiViews is enabled for the web directory either in .htaccess or in the vhost configuration. If so, remove it - which is what worked for me in this example.
If you need MultiViews, then I guess the only chance is to rename rss.php to rss-content.php and change the rule accordingly.
One additional note: you might want to add the following line after the # ... CMS block to prevent endless recursive calls.
RewriteRule ^index\.php/.* - [PT,L]
I hope this solves your rewrite problem.

.htaccess rule conflicts help

Hey guys, I'm trying to implement one of the answers I got to another question I asked on here a couple days ago. You can find the original question here: Mod_rewrite clarification question. Only for dynamic urls?
The most helpful answer and the one I'm modeling the implementation after is as follows:
I'm guessing the answer meder gave is the one you're looking for but technically you can create a static map file to redirect a set of title strings to ids and it doesn't have to execute an external prg executable:
RewriteMap static-title-to-id txt:/tmp/title_to_id.txt
RewriteRule ^/health-and-fitness-tips/(.*)/ /health-and-fitness-tips/${static-title-to-id:$1}/ [L]
with the contents of the /tmp/title_to_id.txt file something like this:
how-do-I-lose-10kg-in-12-weeks 999
some-other-title 988
and-another 983
Ok enough background. My .htaccess file currently has the following in it:
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
</IfModule>
Its a typical wordpress permalink customization. However, when I try to add rules similar to those presented in the selected answer above, I get an internal server error.
This is my .htaccess file when I get the internal server error:
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
RewriteMap static-title-to-id txt:/tmp/title_to_id.txt
RewriteRule ^/health-and-fitness-tips/(.*)/ /health-and-fitness-tips/${static-title-to-id:$1}/ [L]
</IfModule>
I'm hoping my problem is something simple, like a rule conflict. If you can see an error or can provide some direction here, it would be much appreciated.
There are four errors in your code:
The RewriteMap direction can only be used in the server configuration or virtual host context.
When using mod_rewrite in an .htaccess file, mod_rewrites first removes the per-directory prefix from the URL path before testing the rules and reappended after applying a rule. In the case the .htaccess is in the root directory, the path prefix would be / that’s removed. So you need to specify the path pattern without that prefix:
RewriteRule ^health-and-fitness-tips/(.*)/ /health-and-fitness-tips/${static-title-to-id:$1}/ [L]
The substitution of your rule would also be matched by that same rule. That would lead to an infinite loop. So you need to either change the pattern or the substitution to avoid that. In your case changing the pattern would be better, for example:
RewriteRule ^health-and-fitness-tips/([a-zA-Z]+[a-zA-Z0-9]+|[a-zA-Z0-9]+[a-zA-Z]+)/ /health-and-fitness-tips/${static-title-to-id:$1}/ [L]
Your should also specify the end of the URL path:
RewriteRule ^health-and-fitness-tips/([a-zA-Z]+[a-zA-Z0-9]+|[a-zA-Z0-9]+[a-zA-Z]+)/$ /health-and-fitness-tips/${static-title-to-id:$1}/ [L]
As I assume that those URLs can not be directly mapped to existing files or directories, your first rule will catch them before you rewrite them. So you should change the order of that rules to have the specific rule applied before the catch-all one:
RewriteRule ^health-and-fitness-tips/([a-zA-Z]+[a-zA-Z0-9]+|[a-zA-Z0-9]+[a-zA-Z]+)/$ /health-and-fitness-tips/${static-title-to-id:$1}/
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]

Resources