The Download Servlet

A real coffee cup would be steaming...
Those were the days…when there had to be something coffee-related on every page about Java

The DownloadServlet is a small project showing how to deliver streamed (binary) contents in Java via Servlets in compressed form. I implemented it once ago to help tracking down somebody’s problem with GZip compression in correlation to several different browsers‘ behaviour, for Sun’s JSP-INTEREST mailing list. Despite its original ‚experimental‘ nature, quite a lot of people have downloaded the sources since then.

So I refined it a little bit, yet, it’s still simple enough to get a basic understanding of how things work. I just keep it here. There are several standard solutions (most of them implemented as Filters) shipped with today’s Java servers, and I recommend using those for production sites (note that the Java GZip libraries have a memory leak, so for heavy traffic, it might be a better idea to use the Apache Server’s mod_gzip, for example). Anyhow, the DownloadServlet is different, still: instead of compressing everything based on MIME type, it works on a directory basis. If that is what you need, feel free to make use of it, in whatever way you may. To give a brief overview over the DownloadServlet’s capabilites and options, I think it’s best to just provide a list of the configuration parameters:

Use GZip compression

This option enables compressed downloads. Compression is used if your browser claims to support it and the file size is beyond a certain limit, 100 kilobytes in this case. Otherwise, compression is switched off and a ’normal‘ download is performed. Note that compression can significantly reduce download times, but at the cost of a definite performance overhead on the server. Generally, compression only makes sense for large files that are not already compressed: compressing zip archives or .jpeg images twice obviously makes no real sense. So the Servlet maintains a blacklist of uncompressable file types as well.

Send file ‚inline‘

This option modifies the Content-Disposition header. Possible values are ‚inline‘ or ‚attachment‘. This selects the ‚inline‘ option.

Ignore MIME type

By default, the Servlet tries to automatically determine the requested file’s MIME type and sends that information downstream along with the response. Setting this option will skip that step and set the MIME type to something generic, currently, ‚application/x-msdownload‘. Could also have named it ‚Enable dumb mode‘. If you select this option, the contents will be handled as generic binary data.

Override Transfer-Encoding

This is a special option for HTTP 1.1. In HTTP 1.1, ‚chunked‘ Transfer-encoding is used by default, so you don’t have to specify a Content-Length header telling the browser how many bytes to expect. Unfortunately, headers have to be sent before sending any contents, but there’s no way of telling how large the compressed stream might be before actually compressing it. Theoretically, this could be circumvented by caching everything in memory first, but thats no viable option for really large files. So consider this option to be here just for experimental purposes. The Servlet will automatically check if your browser is a HTTP 1.0 one and generally disable compression in this case. If it’s an HTTP 1.1 model and you enable this checkbox, compression will be switched off, too. So selecting this option only makes sense if you have an HTTP 1.1 compliant client and uncompressed files. I left it here entirely for development purposes.