Handler: Hidden Downloads

The Hidden Downloads handler implements secure download mechanisms. This module allows to handle temporal URLs to serve hidden files.


Parameters Type Description



Required. Share secret between the handler and the script.



Optional. How long - in seconds - the URL will be valid.

Technical Description

The idea behind this handler is plain and simple. It will only serve a file if the URL has been generated by a dynamic execution script that you’ve previously written. If the script allows the user to access the file, it will generate a special encoded URL that Cherokee will handle through the Hidden Downloads module.

If the URL is invalid, is modified, or expires, Cherokee will not serve the file.

The encoding scheme is quite straightforward. It is basically the result of MD5-hash of: a shared secret string between Cherokee and the script, the relative path to the requested file (relative to the rule document root), and the current time:

'/' HEX (MD5 (Secret + URL + HEX(time))) '/' HEX(time) '/' URL

Here you have a reference implementation in Python:

 def secure_download (prefix, url, secret):
    import time, hashlib
    t = '%08x' % (time.time())
    return "/%s/%s" % (hashlib.md5(secret + url + t).hexdigest(), t + url)

The same function written in PHP would be:

function secure_download ($prefix, $url, $secret) {
  $time = sprintf('%08x', time());
  return "$prefix/".md5($secret.$url.$time)."/$time$url";

It is important to notice that the URLs are only valid for a period of time. If an URL expires, the server will return an error instead of the file contents. By default URLs last 60 seconds.

Please note that both sample implementations count on having an URL that starts with /.


Lets imagine you have a few ISO files that you want to distribute among a certain group of people.

First, and most importantly, the ISO files ought to be outside of the WWW directory root; otherwise, anybody would be able to download them. Let’s imagine those ISO files are located under: /mnt/isos/, and the server document root is located in /var/www/.

Now it is time to configure the /downloads web directory, so it is handled by Hidden Downloads. We set a shared secret string (Abracadabra), and the document root where the real ISO files are located (/mnt/isos):

Configuration for directory /downloads


Hidden Downloads

Document Root




Hidden downloads configuration

To summarize, its a four step process: - Configure a Directory rule. Let’s say: /downloads - Set the rule to use "Hidden Downloads" handler - Set the Document Root directory (this is important!) - Set the Secret string

Next step is to write the logic that will decide what is the user given access to. For instance, check out this Pyton example:

import time
    from hashlib import md5
except ImportError:
    from md5 import md5

SECRET = "Abracadabra"
DIR    = "downloads"

def secure_download (url, secret):
    t = "%08x"%(time.time())
    return '/'+ DIR +'/'+ md5(secret + url + t).hexdigest() +'/'+ t + url

# Example request
file = "test.txt"
host = "localhost"

hidden_url = secure_download('/%s'%(file), SECRET)
print "/%(DIR)s/%(file)s -> http://%(host)s%(hidden_url)s" %(locals())

According to this example, if a user tries to access /bar/foo/example.iso and access is granted, working URL such as this would be provided:


Since the /downloads web directory is configured with this "Hidden Downloads" handler, it will check the URL to ensure that it is valid and has not expired. Then, if everything was right, it would send the /mnt/isos/bar/foo/example.iso file to the client.