Ultimate Htaccess Tutorial for .htaccess files
« Advanced .htaccess Tricks for Securing SitesPassword Protection Plugin Status »
Let’s look out how all of this plays out in mod_mime.c, which defines the file typing handler which emulates the NCSA server’s behavior of determining file types from suffixes. What we’ll be looking at, here, is the code which implements the AddType and AddEncoding commands. These commands can appear in .htaccess files, so they must be handled in the module’s private per-directory data, which in fact, consists of two separate tables for MIME types and encoding information, and is declared as follows:
table *forced_types; /* Additional AddTyped stuff */ table *encoding_types; /* Added with AddEncoding... */ mime_dir_config;
When the server is reading a configuration file, or
(If we are reading a .htaccess file, that resource pool is the per-request resource pool for the request; otherwise it is a resource pool which is used for configuration data, and cleared on restarts. Either way, it is important for the structure being created to vanish when the pool is cleared, by registering a cleanup on the pool if necessary).
For the MIME module, the per-dir config creation function just ap_pallocs the structure above, and a creates a couple of tables to fill it. That looks like this:
void *create_mime_dir_config (pool *p, char *dummy) mime_dir_config *new = (mime_dir_config *) ap_palloc (p, sizeof(mime_dir_config)); new->forced_types = ap_make_table (p, 4); new->encoding_types = ap_make_table (p, 4);
Now, suppose we’ve just read in a .htaccess file. We already have the per-directory configuration structure for the next directory up in the hierarchy. If the .htaccess file we just read in didn’t have any AddType or AddEncoding commands, its per-directory config structure for the MIME module is still valid, and we can just use it. Otherwise, we need to merge the two structures somehow.
To do that, the server invokes the module’s per-directory config merge function, if one is present. That function takes three arguments: the two structures being merged, and a resource pool in which to allocate the result. For the MIME module, all that needs to be done is overlay the tables from the new per-directory config structure with those from the parent:
void *merge_mime_dir_configs (pool *p, void *parent_dirv, void *subdirv) mime_dir_config *parent_dir = (mime_dir_config *)parent_dirv; mime_dir_config *subdir = (mime_dir_config *)subdirv; mime_dir_config *new = (mime_dir_config *)ap_palloc (p, sizeof(mime_dir_config)); new->forced_types = ap_overlay_tables (p, subdir->forced_types, parent_dir->forced_types); new->encoding_types = ap_overlay_tables (p, subdir->encoding_types, parent_dir->encoding_types);
As a note — if there is no per-directory merge function present, the server will just use the subdirectory’s configuration info, and ignore the parent’s. For some modules, that works just fine (e.g., for the includes module, whose per-directory configuration information consists solely of the state of the XBITHACK), and for those modules, you can just not declare one, and leave the corresponding structure slot in the module itself NULL.
Now that we have these structures, we need to be able to figure out how to fill them. That involves processing the actual AddType and AddEncoding commands. To find commands, the server looks in the module’s command table. That table contains information on how many arguments the commands take, and in what formats, where it is permitted, and so forth. That information is sufficient to allow the server to invoke most command-handling functions with pre-parsed arguments. Without further ado, let’s look at the AddType command handler, which looks like this (the AddEncoding command looks basically the same, and won’t be shown here):
char *add_type(cmd_parms *cmd, mime_dir_config *m, char *ct, char *ext) if (*ext == '.') ++ext; ap_table_set (m->forced_types, ext, ct);
This command handler is unusually simple. As you can see, it takes four arguments, two of which are pre-parsed arguments, the third being the per-directory configuration structure for the module in question, and the fourth being a pointer to a cmd_parms structure. That structure contains a bunch of arguments which are frequently of use to some, but not all, commands, including a resource pool (from which memory can be allocated, and to which cleanups should be tied), and the (virtual) server being configured, from which the module’s per-server configuration data can be obtained if required.
Another way in which this particular command handler is unusually simple is that there are no error conditions which it can encounter. If there were, it could return an error message instead of NULL; this causes an error to be printed out on the server’s stderr, followed by a quick exit, if it is in the main config files; for a .htaccess file, the syntax error is logged in the server error log (along with an indication of where it came from), and the request is bounced with a server error response (HTTP error status, code 500).
The MIME module’s command table has entries for these commands, which look like this:
command_rec mime_cmds[] =
{ "AddType", add_type, NULL, OR_FILEINFO, TAKE2, "a mime type followed by a file extension" },
{ "AddEncoding", add_encoding, NULL, OR_FILEINFO, TAKE2, "an encoding (e.g., gzip), followed by a file extension" },
The entries in these tables are:
Finally, having set this all up, we have to use it. This is ultimately done in the module’s handlers, specifically for its file-typing handler, which looks more or less like this; note that the per-directory configuration structure is extracted from the request_rec’s per-directory configuration vector by using the ap_get_module_config function.
The basic ideas behind per-server module configuration are basically the same as those for per-directory configuration; there is a creation function and a merge function, the latter being invoked where a virtual server has partially overridden the base server configuration, and a combined structure must be computed. (As with per-directory configuration, the default if no merge function is specified, and a module is configured in some virtual server, is that the base configuration is simply ignored).
The only substantial difference is that when a command needs to configure the per-server private module data, it needs to go to the cmd_parms data to get at it. Here’s an example, from the alias module, which also indicates how a syntax error can be returned (note that the per-directory configuration argument to the command handler is declared as a dummy, since the module doesn’t actually have per-directory config data):
« Advanced .htaccess Tricks for Securing Sites
Password Protection Plugin Status »
Pages: 1 2
Tags: .htaccess examples, Apache, Cache, caching, Files, FilesMatch, Google, Hacking, howto, htaccess, htaccess guide, htaccess help, htaccess howto, htaccess rewrite, htaccess tricks, htaccess tutorial, httpd, litespeed, mod_rewrite, Mod_Security, rewritecond, rewriterule, sample .htaccess, Security, SEO, seo secrets, SetEnvIf, ssl, ultimate htaccess
Please consider donating to support active development of the free software and articles here.![]()
The power of the Web is in its universality. Access by everyone regardless of disability is an essential aspect. Tim Berners-Lee
Hi,
Great page, but in your full .htaccess directives list you have included the following:
DirectoryLocationErrorLogI have found that in Apache 2.2 these directives are not allowed.
Very nice tutorial.
Just one note:
Since Apache 2.0.49 it’s possible to use wildcards for the mime type in ExpiresByType, see (search for PR#7991).
I tested it with Apache 2.2.9 and it works fine.
In my .htaccess I set the expiration time for all images with:
ExpiresByType image/* A2592000
Great resource, Thanks for sharing this great knowledge
Probably not the best place to ask this, but don’t where else.
Is there an htaccess comand(s) that would take ever call to any occurrence of wp-content\themes and make it read from \allthemes
The idea is to get several wp installs on same server to use common directories for their themes and plugins.
I have no success with ln -s symlinks but htaccess rewrites all seem fine.
(p.s. my odd email addie is legit)
help!
i can rewrite URLs just fine, but none of the images/css/js works anymore!
i just get a plain-html view of the new target page
here is the .htaccess:
RewriteEngine On RewriteBase / RewriteRule ^somedirectory/page17 /index.php?id=17
This a really informative post. Directory Protection with .htaccess files was all that i wanted.
Thank You
I always found myself getting back to this .htaccess tutorial and guide. Definitly the best and most complete one!
I realize this might be an older post, but I need some serious help. I have Wordpress MU installed in my root directory and Moodle installed in a subdirectory. These are interfering with each other. I’m getting Internal Server Errors in the Moodle install. I’m pretty sure it can be fixed with some .htaccess scripting. There is not a .htaccess file in the Moodle directory. I copied the .htaccess from the root directory over to the Moodle directory, but it didn’t do anything. Here’s what’s in the root directory. Is it possible the php.ini is causing the errors?
# Use PHP5 as default
AddHandler application/x-httpd-php5s .php
RewriteEngine On
RewriteBase /
#uploaded files
RewriteRule ^(.*/)?files/$ index.php [L]
RewriteCond %{REQUEST_URI} !.*wp-content/plugins.*
RewriteRule ^(.*/)?files/(.*) wp-content/blogs.php?file=$2 [L]
# add a trailing slash to /wp-admin
RewriteCond %{REQUEST_URI} ^.*/wp-admin$
RewriteRule ^(.+)$ $1/ [R=301,L]
RewriteCond %{REQUEST_FILENAME} -f [OR]
RewriteCond %{REQUEST_FILENAME} -d
RewriteRule . - [L]
RewriteRule ^([_0-9a-zA-Z-]+/)?(wp-.*) $2 [L]
RewriteRule ^([_0-9a-zA-Z-]+/)?(.*\.php)$ $2 [L]
RewriteRule . index.php [L]
SecFilterEngine Off
SecFilterScanPOST Off
Your site is absolutely great! I have been working on this for a week and I finally understand this. I do not have a directory index and I haven’t figured out quite how to do this yet. My webhosting site is Linux based so the code has to be either in Perl or Python.
I can access the .htaccess files but I can get past the first step of creating the path.
Please help.
Mia
Hi there,
Great article.. however I have a question, which I hope you don’t mind me asking.
I have built a web application and I have built a marketing site. The app is built on the .com while the marketing is currently on the .ie.
Anyhow, if somebody types domain.com I wish to redirect them to domain.ie
Once on the .ie, a button brings them to domain.com/login.
So I don’t wish to redirect everything…
I have attempted the following
Redirect /index.php http://www.domain.ie/index.php
However, unfortunately when you click on the button, it has changed to domain.ie/login which does not exist….
Any help would be much appreciated.
Regards and thanks,
Fiona
Very good, comprehensive guide to .htaccess!
Thank you for share a great and useful resource.
Awesome guide. I will point our users to this :)
Great job putting this together, thank you. You solved all my questions.
How to cloak a domain redirected to a folder from another hosting using .htaccess?
A wonderful htaccess guide and very distinct
Great idea… however got disapointed by the only example I tried (protecting whole wp-admin folder except for static files). Till now, I used to password protect whole wp-admin, which lead to some bad displays when a css from WP-admin is required (which is stupid, I thing)
Tried the example to protect whole wp-admin folder but the result in not as expected (still can’t access any CSS file behind /wp-admin/ and authentification not working at all).
Thus, I’m assuming that either ruleset is incorrect, or that there are some server specific stuff to take care off.
Thanks anyway for this unique guide.
Rgds
How Do I Make a Htaccess File? You talked about how Creating a Htaccess File, (without Htaccess Software) would work in Windows Explorer.. But what program do you use?
I love your Examples of Htaccess Files, this is the best Htaccess Tutorial, Htaccess Example, and resource IVe managed to find.
I’m having the same problem as Manasi. I don’t know enough to know what the
.htaccess files allowed [200]
error means or what to do about it. Either it’s something I can get my hosting provider to fix, fix myself, or bug my hosting provider into including the feature. But if I don’t know what to ask, I can’t ask. Tried finding this on Google, this is the page I got.
Thanks in advance for any help,
Rob
Thank you man, I’m looking forward to implement all this to improve my server’s security
Thanks for the best tutorial all in one. that’s great. I have problem with two .htaccess
If there are two different .htaccess file in two different directory, one that exists on root folder and other one exists in sub directory called htaccesssearch.
I want to redirect website from non-www to www with 301 and I have added code root .htaccess file as following
RewriteEngine on
Options +FollowSymlinks
Rewritecond %{http_host} ^baghel.in
Rewriterule ^(.*)$ http://www.baghel.in/$1 [r=301,nc]
This is working fine but if we access the /htaccesssearch/abc.html it is not redirect to /htaccesssearch/abc.html because there is another .htaccess in the htaccesssearch folder .
if we add the above code another .htaccess which is exist in htaccesssearch then whole site is not working .
Please suggest me what should I do !
Thanks in advance
Hi Dave
I found your site when I was researching a problem I have with broken permalinks on my blog. The article on .htaccess is excellent.
Basically, some of my backlinks are pointing to posts and have the format “postname.html” and they are giving “not found” errors. I would like the requests for the .html links to be redirected to the “clean” permalinks I am now using (i.e. “postname”). Could you please explain how I can do this through .htaccess?
Thanks
Tom
Hi, I have non-www to www redirect code as follows :
RewriteEngine On
##non-www to www
RewriteCond %{HTTP_HOST} !^(www\.example\.com)?$
RewriteRule (.*) http://www.example.com/$1 [R=301,L]
This works fine and redirects all non-www version of the url to its corresponding www version. However when I have a https://www.example.com/mypage.asp, it redirects the same to http://www.example.com/mypage.asp. How can I prevent urls beginning with https to be skipped by this re-write rule.
Fantastic site! Thanks! Still as a newbee I need some help… I would much appreciate if you could help me (eager to donate…) Here is my .htaccess code:
RewriteEngine On RewriteRule ^index.html$ index.php RewriteRule ^browse-(.*)-videos.html$ category.php?cat=$1 RewriteRule ^browse-(.*)-videos-([0-9]+)-(.*).html$ category.php?cat=$1&page=$2&sortby=$3 RewriteRule ^favorites.html(.*)$ favorites.php$1 RewriteRule ^favorites.html(.*)$ favorites.php$1 RewriteRule ^playlist/(.*)$ myfavorites.php?u=$1 RewriteRule ^memberlist.html(.*)$ memberlist.php$1 RewriteRule ^tags/([^/]+)/$ tag.php?t=$1&page=1 RewriteRule ^tags/([^/]+)/page-([0-9]+)(/)?$ tag.php?t=$1&page=$2 RewriteRule ^(.*)/(.*)-video_(.*).html$ musicvideo.php?vid=$3 RewriteRule ^rss.xml$ rss.php [L]
I want to have wild-subdomains (yes I have root access!). I want the user’s site to looks like http://user.domain.com (yes I have root access to my server! and I have already installed wild-subdomains for my other site)
Best Regards,
Macc
I am having problem on my WP blog and it has something to do with the htaccess. I installed the plugin but was not able to figure out the problem. The site was working fine but recently I am getting tons of
page not found
As ?p=xx is being added at the end of existing URL’s. It has something to do with permalink? URL Rewrite? Any hint as I am clueless at the moment, will appreciate!
My question is, I want to change the location of URL, to display example.com/myhtaccess.html in .htaccess. Help me out
Great htaccess things here askapache, keep up the Good Job ;)
Thank you
Hi, I hope you can help me, I would like for anyone who types site (also have subdomain) without the “WWW” for it to add it. I really hope you can help, I tried before but it went in a big rewrite loop.. added lots of WWW’s. Thanks
Hi thanks for the great info on creating a .htaccess file.
I just wanted to know, is it possible to use deny from all and at the same time allow php from the same server to write to the directory?
Thanks
Hi,
It’s a very nice tutorial, but i have got a problem with apache authentication modules. I have written an apache authentication module and given the authentication type as basic. But, whenever a GET request is coming, my authentication module is being invoked and for each GET request, authentication is happening. But i wnt it to be authenticated only once. how can i solve this problem and is there any relation of this problem with .htaccess file
Hello,
Any idea about what can be wrong with a Drupal .htaccess file that make it impossible to use my own error.php file on Dreamhost PS?
Dreamhost replied me that it must be because of the .htaccess file but that’s all.
Thanks a lot!
Exelente tutorial, he resuelt un complejo problema de cache gracias a las infinitas alternativas de los .htaccess, en particular gracias al mod_rewrite del apache y en ello este blog me ha sido de muchisima ayuda. Gracias a todos
Great tutorial, I have solved a complex problem because of the infinite cache of alternatives. Htaccess, particularly thanks to the Apache mod_rewrite and so this blog I have been extremely helpful. Thanks to all
Hi, Great htaccess tutorial, learned a lot, but like Emi, I want to redirect an affiliate link like site1.com/x.php?action=alink&id=15&link=3 to site2.com/newproduct/ Is this possible using a rewrite rule? Thanks for any advice
I am unsure if I am doing somethign wrong. I am hosted with Godaddy but when the checking script runs it displays some errors and I am unsure as to how to resolve them:
Error 1
.htaccess Capabilities
.htaccess files allowed [200] errors out and gives me:
HTTP/1.1 500 Internal Server Error Date: Wed, 19 Nov 2008 15:59:46 GMT Server: Apache Connection: close Content-Type: text/html; charset=iso-8859-1
The others items in this list also turn yellow ( not red like the first one but also give the same error )
Second Error:
HTTP Digest Authentication
Bummer… you don’t have digest capabilities.
Is this critically needed?
Third error:
Basic Authentication Encryption Algorithms
Basic Authentication Attempt using Crypt Encryption
Basic Authentication Attempt using MD5 Encryption
Basic Authentication Attempt using SHA1 Encryption
all three same error as above:
HTTP/1.1 500 Internal Server Error Date: Wed, 19 Nov 2008 15:59:46 GMT Server: Apache Connection: close Content-Type: text/html; charset=iso-8859-1
What am I missing?
It is the most comprehensive htaccess info page I ever read. Rich with lots of examples. Thumbs UP!
Our website has been illegally copied by a Chinese website, and as a result, when you type in our company name in Google, their illegal website shows up on the first spot but with a 100% copy of our content.
What is a good way to block this Chinese website from our content? Can we use htaccess files to do this?
Nice .htaccess article. It was very helpful for me.
Now this is a detailed guide on redirecting with the htaccess file… excellent!
It it possible to redirect a page when the url has spaces ie. example.com/htaccess file.html ?
I found your site about htaccess interesting and could help me from what I’m doing.
I just have some question regarding htaccess.
I need to edit a webpage that already has a ‘Contact Webpage’ which you can send some suggestion/comments.
It seems like this is the place where the post is directed. I checked the directory _vti_bin/ but it didn’t have shtml.exe
instead i found .htaccess file.
I’m not very familiar about htaccess much. Can you please help me how did htaccess directed to shtml.exe.
Hey, I am using the following code for redirecting non www url to www url. Please let me know what code to add?
Options +FollowSymLinks
RewriteEngine On
RewriteBase /
RewriteCond %{HTTP_HOST} !^www\.example\.com$ [NC]
RewriteRule ^(.*)$ http://www.example.com/$1 [R=301,L]
It work fine for the folowing url type example.com/restaurant.html, If I have to redirect the following non www url to www url example.com/cms/restaurant.html. When I hit this url I get the following response:
"The requested URL /index.php was not found on this server."
Thanks,
John
Now even more! Love it.
.htaccess rewrite mask external link,htaccess mod rewrite error page,how much does mod rewrite,.htaccess dynamic directories,htaccess rewrite url,htaccess url,htaccess hide url,mod rewrite php to htm
and
htaccess rewrite rule options,rewrite direct index link htaccess,htaccess rewriterule,.htaccess mod_rewrite rules,convert unix timestamp into date php,php to .html with htaccess
htaccess rewrite, htaccess mod rewrite, php url rewrite, .htaccess rewrite rule, .htaccess redirect post variables, mod rewrite htaccess, hotlink code, rewrite url .htaccess, htaccess allow indexes, htaccess tips tricks, .htaccess php require, .htaccess php.ini, rewrite htaccess, htaccess rewrite rule, .htaccess mod rewrite
Hey your home page is a little out of control
This is very useful and powerful htaccess. It does help improve the security of my wordpress. I will keep an eye of the updates.
Thanks for putting this up. This htaccess guide is complete and direct to the point. I like it!
After three frustrating phone calls to the idiots at 1&1 hosting, simply trying to help one of my clients get a redirect… I gave up and asked my website hosting company, DreamHost for help. Their article directed me to this site, which, solved the htaccess problem with my client’s site in a snap. Thank you so much for this!
very nice .htaccess doc, thank you man.
this does not seem to work ?
AuthName "htaccess password prompt" AuthUserFile /home/askapache.com/.htpasswd AuthType Basic Require valid-user Allow from 172.17.10.1 Satisfy Any
It lets me in from any ip address ? I’ve managed to get it to work like this (although may not be correct)
AuthName "htaccess password prompt" AuthUserFile /home/askapache.com/.htpasswd AuthType Basic Satisfy Any order deny,allow deny from all Require valid-user Allow from 172.17.10.1
I’m not sure if this is optimal however.
Great list, it helps clear up much of the htacess mystery and confusion that comes from creating such files.
Thanks for this article, it’s great.
So great that we’ve made it ‘sticky‘ on The Webmaster Forums.
Now we don’t have to repeat ourselves, just send people to this article!
That’s perfect summary, very valuable for my next job of doing SEO friendly urls through htaccess. Thank you.
It's very simple - you read the protocol and write the code. -Bill Joy
HTML | DCMI | GRDDL | XOXO | XDMP | XFN | DOM | XML | XHTML 1.1 Strict | CSS 2.1 | W3C | TLDP | WAI | DISA | ICSI | GIAC | SANS RR | GHOST | DEFCON | NIST | DHS CYBER | NIST | .:: Phrack Magazine ::.
↑ TOPExcept where otherwise noted, content on this site is licensed under a Creative Commons Attribution 3.0 License, just credit with a link.
This site is not supported or endorsed by The Apache Software Foundation (ASF). All software and documentation produced by The ASF is licensed. "Apache" is a trademark of The ASF. HTTPD based on NCSA HTTPd
This may seem like a very strange request, but i have know idea where to start in writing my htaccess file.
When i installed my version of WP about 3 months ago, i was unable to find my htaccess file, and i have looked many time and never found it. Came to the conclusion that their wasnt one. Did i have to write one myself?
Could you suggest some sites that give descriptions and code on how to effectively write a good secure htaccess file.
I will continue to read through ur site which will def. give me some ideas
Ben