A frequently ask question from people trying to send files from CGI scripts is:
"How do I specify a filename for download from a CGI script?"
Normally if you are attempting to secure WWW files so they are only available with your authorization, you would use server authentication. However, you may not understand how to do that or have access to the web server program to use encrypted passwords.
I experimented with specifying filenames with an experimental mime-type header called Content-disposition, but unfortunately that only works for Netscape.
This document explains a method to fake out any browser to use the proper name by using that name in the URL. However, this method has only been tested with the Apache webserver and should work equally as well on the NCSA httpd that Apache is based on. For other webservers you would need to determine if or how you can specify what file extensions should be treated as CGI scripts.
The method is simple. A link is provided to a file with the filename you want to download. However, that is not a file at all. It is a symbolic link to a CGI script. The CGI script looks at the name it was called as and sends a file of that same name from another directory if it passes your own authorization test. The actual files for download and/or authentication can be in directories not accessible by URL.
Note: Apache with suexec wrapper will only allow hard links (ln) to make sure that scripts run as you are secure. Without the suexec wrapper (scripts run as 'nobody'), you can use symbolic links (ln -s).
To carry this out you need to be able to specify what file extensions should be treated as CGI scripts. With Apache and NCSA this is typically done (if allowed) in a file in that directory called '.htaccess' (hidden file with leading dot). Note: .htaccess applies to the directory it is in and any directories under it. All you need for the .htaccess contents is one of the following strings:
This would allow 'some.wav', 'some.mid' or 'some.ra' symbolic links to run the real CGI script that they symlink to. Any other file extensions you want treated as CGI scripts are added as a space separated list.
If you want to do some sort of password authentication you could use a form that checks the password and generates a page with a link to the fake file. The authentication data could be passed as a query string on that link (if nothing else, you could just tack a question mark (?) and the raw form data onto the link). Then the script that the fake file links to could further check authorization, send a file of the same name from another directory if approved, then delete the password.
A content type of 'application/octet-stream' is used which should ask the user if they want to save the file (Netscape), but IE and other Mosaic based browsers ignore that, so you need instructions to make sure they right click or whatever else they have to do to download a linked file to disk.
To prove that it works, the demo below allows two downloads before the password expires and then there is no way to get that file by URL except by getting a new authorization code. For the demo you can get a new code by reloading the authorization form.
Unless you are only sending very large files that are larger than the server buffer, it is best to allow at least 2 download attempts. Short files are sent all at once and you have no way to determine if the file was received successfully (like pressing the wrong mouse button).