... Slapped together from a few emails (or, what I learned from www.apache.org, plus banging my own head against the wall)...

Topics you will find in this article are:

A Few Important .htaccess Options

Apache uses the .htaccess files to customize the web server responses. If you are not experienced with .htaccess file, now is a good time to learn. They are "archaic" but useful. Make sure that your server will accept an .htaccess file overriding the default settings. Check with your ISP first.

Using NotePad or your favorite text editor (vi if you are an uber-monkey) create the following file:

Name = htaccess.txt (after FTPing the file over, rename it to .htaccess)

Options Includes ExecCGI

AddHandler cgi-script .cgi

DirectoryIndex index.html index.htm index.cgi

AddType text/x-server-parsed-html .html .htm .ssi

Save the file and FTP it to the directory you want the cgi script to be the index page. BIG NOTE: .htaccess files are inclusive and last option rules. What this means is that you can set up an .htaccess file within the root directory of your web server /web/sites/ <server> and it will be applicable to the rest of the downstream tree. If another .htacess file is downstream the two are "added" together. Any commands that are contradictory are not debated. The last one processed wins. So downstream .htaccess files would override any contradictory rules set previously. (Clear as mud?)

Now rename your script to index.cgi and move it into the target directory.

There are a lot of cool and fancy things you can do with the .htaccess file (this is where you start for password protecting a directory).

-- What the file means --

Options Includes ExecCGI

The Options directive controls which server features are available in a particular directory. Includes says do SSIs, ExecCGI says execute cgi scripts from within this directory. More Info:

http://www.apache.org/docs/mod/core.html#options

AddHandler cgi-script .cgi

AddHandler maps the filename extensions extension to the handler handler-name. More info:

http://www.apache.org/docs/mod/mod_mime.html#addhandler
http://www.apache.org/docs-1.2/handler.html

DirectoryIndex index.html index.txt index.cgi

The DirectoryIndex directive sets the list of resources to look for, when the client requests an index of the directory by specifying a / at the end of the a directory name. More Info:

http://www.apache.org/docs/mod/mod_dir.html#directoryindex

AddType text/x-server-parsed-html .html .htm .ssi

The AddType directive tells the Apache server to "parse" all the files with the listed extensions for SSI commands. More Info:

http://www.apache.org/docs/mod/mod_mime.html#addtype

(This can also be performed via the following command.)

AddHandler server-parsed .htm .html .ssi

More info:

http://www.apache.org/docs-1.2/handler.html

Auto Headers and Footers for Fancy Indexing

Did you know that Apache can put headers and footers on the pages it auto indexes??

If you do not have an index.htm(l) page in your sub-directory Apache sends a list of the files in that directory. Much like an FTP listing. (This is on usually by default and can be turned off with the command 'Options -Indexes' in a .htaccess file.)

However the page is not too fancy (even though they call it fancy indexing.) You can spruce up the page by customizing the header and the footer via the .htaccess file.

Put the following in the .htaccess file for that directory....

HeaderName filename ReadmeName filename

For example...when indexing the directory /web, the server will first look for the HTML file /web/filename.html and include it if found, otherwise it will include the plain text file /web/filename, if it exists. The file must be in the target directory - you can not reference a file from another directory (although you can "within" the used header/footer file. (ReadmeName is the footer file.)

Also - start your header file with BODY - you don't need to end your footer file with </body> or </html>

Lastly - I name your header and footer file with a '.' in the beginning. This will prevent the file from showing up on the directory listing. Putting a '.' as the first character in the name is a UNIX trick to make the file 'disappear'. e.g. I named my header and footer file '.download-header.html' and '.download-footer.html'. Therefore my .htaccess file looks like this...

HeaderName .download-header ReadmeName .download-footer

So no .html as the extension because Apache already adds that when it looks for the file.

So you can embed HTML and formatting in to the header and footer of an index of files. You can see my attempt at http://www.baratta.com/southpark/files - you can see a better attempt at http://soundamerica.com

Password Protecting a Directory

You need two files - one called '.htaccess' and the other any name you want/any location you have read/write access to. I call my web password files '.htpasswd' and put them in a directory under my home directory. If you use a directory off your home directory, make sure that the directory is 755 and the password file is 644, so the web server can see and use it.

e.g. password file is in /web/foo/home/bin-foo while the /web/sites/foo/members is the password protected directory.

Makes it harder to steal your password file.

OK create an .htaccess file with this stuff...

AuthName " <phrase the user sees in the login box>"

AuthType Basic

AuthUserFile /full/path/to/file/.htpasswd

require valid-user

Of course put the .htaccess file in the directory you want password protected.

Now...cut and paste the following code into a file called make-password or something - chmod it to 700. (make sure that the path to PERL is correct)

This file will allow you to make and add password files without having to do much work.

(Apache comes with another program to do this, I use this code snippet because I've attached it to a few admin programs I use with Perl to make and change user passwords.)

#!/usr/bin/perl

if (scalar(@ARGV) < 2) {

print <<EOF;

usage: make-password <htpasswd file> <user> <password>

EOF

exit;

}

$salt="XX";

$file=$ARGV[0];

$key=$ARGV[1];

$value=$ARGV[2];

if ($file && $key && $value) {

$hash = crypt($value, "$salt");

open(DB, ">>$file") || die "Error: $!

";

print DB "$key:$hash

";

close(DB);

print "User $key added with password $value,

encrypted to $hash

";

exit;

}

+++++

Put the file in your home 'bin' directory. If your admin set you up right you should have a path to a bin directory in your path statement, even if the bin directory does not exist. (Check with the command 'env'.) Make the directory if it does not exist.

To make a new password file just type the following in the directory you want to create the password file.

make-password htpasswd file name> <user name> <password>

If htpasswd file does not exist it is created. You can use this command to add new names and passwords to the htpasswd file. To delete a name and password, just vi the file and 'dd' the line to delete it.

Fire up the browser and test. Should work.

Customizing Server Error Messages

You can customize your server's error message so your users are not struck with a stark bleeding white web page with a less than helpful message on it.

The standard errors generated are: 400, 401, 403, 404, 500,

400 = Bad Request. Usually a mangled communication between the browser and server.
401 = Authorization Required. If the user cancels a password request, this error is generated.
403 = Forbidden. If indexing is turned off, and/or the server can not show/access the directory.
404 = Page not found. It ain't there buck-o.
500 = Internal Server Error. Mostly likely a script bombed.

Just mockup some pages to explain the error message(s). Add your site navigation and styles so that they look like part of your site. Then add the following to your .htaccess file:

ErrorDocument 400 /path/to/error-400.html

ErrorDocument 401 /path/to/error-401.html

ErrorDocument 403 /path/to/error-403.html

ErrorDocument 404 /path/to/error-404.html

ErrorDocument 500 /path/to/error-500.html

Note 1: Make sure you call the error file or script based upon the 'root' of the web domain.

Note 2: Make sure you use hard references to all your images and links (versus relative references).

You can point all or some of the error messages to the same html file. Also you can invoke a script when the error is generated. That way you can dynamically generate the error message or run a 404 URL through an index and offer your visitors a choice of possible similar pages.

e.g.

ErrorDocument 404 /cgi-bin/error.cgi

Apache will have available to your script the following environment variables so that you can use them to generate info back to the browser:

REDIRECT_HTTP_ACCEPT=*/*, image/gif, image/x-xbitmap, image/jpeg
REDIRECT_HTTP_USER_AGENT=Mozilla/1.1b2 (X11; I; HP-UX A.09.059000/712)
REDIRECT_PATH=.:/bin:/usr/local/bin:/etc
REDIRECT_QUERY_STRING=
REDIRECT_REMOTE_ADDR=121.345.78.123
REDIRECT_REMOTE_HOST=ooh.ahhh.com
REDIRECT_SERVER_NAME=crash.bang.edu
REDIRECT_SERVER_PORT=80
REDIRECT_SERVER_SOFTWARE=Apache/0.8.15
REDIRECT_URL=/cgi-bin/buggy.pl

More info:

http://www.apache.org/docs/mod/core.html#errordocument
http://www.apache.org/docs/custom-error.html