Sophie

Sophie

distrib > Fedora > 14 > x86_64 > by-pkgid > 0c336499d2cce64b5aa2e42184f43f9e > files > 1391

cherokee-1.2.101-1.fc14.x86_64.rpm

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
                "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
  <head>
    <meta http-equiv="Content-type" content="text/html; charset=utf-8" />
    <meta http-equiv="Content-Language" content="en-us" />
    <meta name="ROBOTS" content="ALL" />
    <meta http-equiv="imagetoolbar" content="no" />
    <meta name="MSSmartTagsPreventParsing" content="true" />
    <meta name="Keywords" content="cherokee web server httpd http" />
    <meta name="Description" content="Cherokee is a flexible, very fast, lightweight Web server. It is implemented entirely in C, and has no dependencies beyond a standard C library. It is embeddable and extensible with plug-ins. It supports on-the-fly configuration by reading files or strings, TLS/SSL (via GNUTLS or OpenSSL), virtual hosts, authentication, cache friendly features, PHP, custom error management, and much more." />
    <link href="media/css/cherokee_doc.css" rel="stylesheet" type="text/css" media="all" />
  </head>
<body>
<h2 id="_a_href_index_html_index_a_8594_a_href_modules_html_modules_a_8594_a_href_modules_handlers_html_handlers_a"><a href="index.html">Index</a> &#8594; <a href="modules.html">Modules</a> &#8594; <a href="modules_handlers.html">Handlers</a></h2>
<div class="sectionbody">
</div>
<h2 id="_handler_hidden_downloads">Handler: Hidden Downloads</h2>
<div class="sectionbody">
<div class="paragraph"><p>The <strong>Hidden Downloads</strong> handler implements secure download mechanisms.
This module allows to handle temporal URLs to serve hidden files.</p></div>
<h3 id="parameters">Parameters</h3><div style="clear:left"></div>
<div class="tableblock">
<table rules="all"
width="100%"
frame="border"
cellspacing="0" cellpadding="4">
<col width="20%" />
<col width="10%" />
<col width="70%" />
<thead>
<tr>
<th align="left" valign="top">Parameters </th>
<th align="left" valign="top">Type   </th>
<th align="left" valign="top">Description</th>
</tr>
</thead>
<tbody>
<tr>
<td align="left" valign="top"><p class="table"><tt>secret</tt></p></td>
<td align="left" valign="top"><p class="table">String</p></td>
<td align="left" valign="top"><p class="table">Required. Share secret between the handler and
                     the script.</p></td>
</tr>
<tr>
<td align="left" valign="top"><p class="table"><tt>timeout</tt></p></td>
<td align="left" valign="top"><p class="table">number</p></td>
<td align="left" valign="top"><p class="table">Optional. How long - in seconds - the URL will
                     be valid.</p></td>
</tr>
</tbody>
</table>
</div>
<h3 id="technical">Technical Description</h3><div style="clear:left"></div>
<div class="paragraph"><p>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&#8217;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 <strong>Hidden Downloads</strong> module.</p></div>
<div class="paragraph"><p>If the URL is invalid, is modified, or expires, Cherokee will not
serve the file.</p></div>
<div class="paragraph"><p>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:</p></div>
<div class="literalblock">
<div class="content">
<pre><tt>'/' HEX (MD5 (Secret + URL + HEX(time))) '/' HEX(time) '/' URL</tt></pre>
</div></div>
<div class="paragraph"><p>Here you have a reference implementation in Python:</p></div>
<div class="listingblock">
<div class="content">
<pre><tt> def secure_download (prefix, url, secret):
    import time, hashlib
    t = '%08x' % (time.time())
    return "/%s/%s" % (hashlib.md5(secret + url + t).hexdigest(), t + url)</tt></pre>
</div></div>
<div class="paragraph"><p>The same function written in PHP would be:</p></div>
<div class="listingblock">
<div class="content">
<pre><tt>function secure_download ($prefix, $url, $secret) {
  $time = sprintf('%08x', time());
  return "$prefix/".md5($secret.$url.$time)."/$time$url";
}</tt></pre>
</div></div>
<div class="paragraph"><p>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.</p></div>
<div class="admonitionblock">
<table><tr>
<td class="icon">
<div class="title">Note</div>
</td>
<td class="content">Please note that both sample implementations count on having an
URL that starts with <tt>/</tt>.</td>
</tr></table>
</div>
<h3 id="examples">Examples</h3><div style="clear:left"></div>
<div class="paragraph"><p>Lets imagine you have a few ISO files that you want to distribute
among a certain group of people.</p></div>
<div class="paragraph"><p>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&#8217;s imagine those ISO files are located under: <tt>/mnt/isos/</tt>, and
the server document root is located in <tt>/var/www/</tt>.</p></div>
<div class="paragraph"><p>Now it is time to configure the <tt>/downloads</tt> web directory, so it is
handled by <strong>Hidden Downloads</strong>. We set a shared secret string
(<tt>Abracadabra</tt>), and the document root where the real ISO files are
located (<tt>/mnt/isos</tt>):</p></div>
<div class="tableblock">
<table rules="all"
width="100%"
frame="border"
cellspacing="0" cellpadding="4">
<caption class="title">Configuration for directory /downloads</caption>
<col width="50%" />
<col width="50%" />
<tbody>
<tr>
<td align="left" valign="top"><p class="table">Handler</p></td>
<td align="left" valign="top"><p class="table"><tt>Hidden Downloads</tt></p></td>
</tr>
<tr>
<td align="left" valign="top"><p class="table">Document Root</p></td>
<td align="left" valign="top"><p class="table">/mnt/isos</p></td>
</tr>
<tr>
<td align="left" valign="top"><p class="table">Secret</p></td>
<td align="left" valign="top"><p class="table">Abracadabra</p></td>
</tr>
</tbody>
</table>
</div>
<div class="imageblock">
<div class="content">
<img src="media/images/admin_handler_secdownload.png" alt="media/images/admin_handler_secdownload.png" />
</div>
<div class="image-title">Hidden downloads configuration</div>
</div>
<div class="paragraph"><p>To summarize, its a four step process:
 - Configure a Directory rule. Let&#8217;s say: /downloads
 - Set the rule to use "Hidden Downloads" handler
 - Set the Document Root directory (this is important!)
 - Set the Secret string</p></div>
<div class="paragraph"><p>Next step is to write the logic that will decide what is the user
given access to. For instance, check out this Pyton example:</p></div>
<div class="listingblock">
<div class="content">
<pre><tt>import time
try:
    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 -&gt; http://%(host)s%(hidden_url)s" %(locals())</tt></pre>
</div></div>
<div class="paragraph"><p>According to this example, if a user tries to access
<tt>/bar/foo/example.iso</tt> and access is granted, working URL such as this
would be provided:</p></div>
<div class="literalblock">
<div class="content">
<pre><tt>/downloads/ac003ebbb88c4fc9a75687223c72c6da/49b40a43/bar/foo/example.iso</tt></pre>
</div></div>
<div class="paragraph"><p>Since the <tt>/downloads</tt> 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
<tt>/mnt/isos/bar/foo/example.iso</tt> file to the client.</p></div>
</div>
<div id="footer">
<div id="footer-text">
</div>
</div>
</body>
</html>