Commit 7a9edc3c authored by Geoff Simmons's avatar Geoff Simmons

Document the .sha256() method.

parent 0013bb4e
......@@ -26,16 +26,25 @@ SYNOPSIS
# File reader object
new <obj> = file.reader(STRING name [, STRING path] [, DURATION ttl])
# File contents
STRING <obj>.get()
VOID <obj>.synth()
BLOB <obj>.blob()
BOOL <obj>.error()
STRING <obj>.errmsg()
BOOL <obj>.deleted()
# File metadata
BYTES <obj>.size()
TIME <obj>.mtime()
DURATION <obj>.next_check()
BOOL <obj>.deleted()
# Digests that change when the file changes
BLOB <obj>.id()
BLOB <obj>.sha256()
# Error status
BOOL <obj>.error()
STRING <obj>.errmsg()
# VMOD version
STRING file.version()
......@@ -232,6 +241,22 @@ then the previously cached contents continue to be valid. If the file
has changed when a check is performed, it is re-read and the new
contents are cached, for access via the object's methods.
.. |.sha256()| replace:: ``.sha256()``
.. |.id()| replace:: ``.id()``
If ``enable_sha256`` is ``true``, then a SHA256 digest is computed for
the file's contents at initialization time, and whenever the file is
determined to have changed. This is done by the update check, not
during any request/response transaction, and hence does not affect
response times. The digest may then be retrieved with the |.sha256()|_
method. If ``enable_sha256`` is ``false``, then no SHA256 hash is
computed, and it is an error to invoke |.sha256()|_. Since the digest
may be expensive to compute, especially for large files, it may be
advantageous to leave SHA256 disabled, and use the less costly
|.id()|_ method instead; see the documentation of |.sha256()|_ for a
discussion. By default, ``enable_sha256`` is ``false``.
If an error is encountered when a check attempts to re-read the file,
then subsequent method calls attempting to access the contents invoke
VCL failure (see `ERRORS`_ below), with the ``VCL_Error`` message in
......@@ -281,9 +306,9 @@ Examples::
new synth_body = file.reader("synth_body.html", ttl=300s);
# A reader for the file on the given search path, with
# default TTL, and logging for update checks.
# default TTL, logging for update checks, and SHA256 enabled.
new bar = file.reader("bar", path="/var/run/d1:/var/run/d2",
log_checks=true);
log_checks=true, enable_sha256=true);
# A reader for the file with no update checks.
new baz = file.reader("baz", ttl=0s);
......@@ -454,6 +479,8 @@ Example::
set resp.http.Cache-Control = "public, max-age="
+ std.integer(duration=rdr.next_check());
.. _.id():
.. _xreader.id():
BLOB xreader.id()
......@@ -473,12 +500,64 @@ The contents of the BLOB returned by ``.id()`` are intentionally not
documented, and should not be relied on to extract information about
the file.
.. _.sha256():
.. _xreader.sha256():
BLOB xreader.sha256()
---------------------
XXX ...
Returns the SHA256 digest of the file's contents, if the
``enable_sha256`` flag was set to ``true`` in the constructor. Invokes
VCL failure if SHA256 was not enabled, or if the most recent update
check encountered an error.
Example::
import blob;
sub vcl_init {
new rdr = file.reader("/path/to/file", enable_sha256=true);
}
sub vcl_recv {
if (req.http.If-None-Match == blob.encode(BASE64, blob=rdr.sha256())) {
return (synth(304));
}
else {
return (synth(200));
}
}
sub vcl_synth {
set resp.http.ETag = blob.encode(BASE64, blob=rdr.sha256());
if (resp.status == 200) {
rdr.synth();
}
}
The ``.sha256()`` and ``.id()`` methods both return a digest for the
file, each of which changes when the file changes, and hence is
suitable for a header such as ``ETag``. In the typical case, the
``.id()`` method will lead to more efficient use of system resources.
This is because ``.id()`` is derived solely from the file's metadata
-- the fields obtained from ``stat(2)`` -- and when these change, the
file's contents typically have been changed as well.
If only the file metadata have been changed, but not the contents,
then the return value of ``.id()`` changes nevertheless. This may
happen for example if the modification time has been updated by
``touch(1)``, or if the file contents happen to be no different after
an update. In that case, using the ``.id()`` value for
``If-None-Match`` and ``ETag`` may lead to sending the response body
unnecessarily, when a 304 Not Modified response would have been
possible. The return value of ``.sha256()`` remains unchanged in such
a situation.
But if a change in the metadata without a change of the contents is
uncommon, then it makes more sense to disable SHA256 and use
``.id()``. Then the VMOD saves the effort of computing the SHA256
digest, and ``.id()`` is sufficient for a purpose such as ``ETag``.
.. _file.version():
......@@ -587,6 +666,10 @@ that the mapped file contents may be used imminently (using
reading ahead in the file mapping. But that decision is left to the
kernel.
If SHA256 is enabled, then the digest is computed after the file is
mapped. In that case, I/O for file reads is guaranteed to take place
before any request/response transaction.
SEE ALSO
========
......
......@@ -22,16 +22,25 @@ SYNOPSIS
# File reader object
new <obj> = file.reader(STRING name [, STRING path] [, DURATION ttl])
# File contents
STRING <obj>.get()
VOID <obj>.synth()
BLOB <obj>.blob()
BOOL <obj>.error()
STRING <obj>.errmsg()
BOOL <obj>.deleted()
# File metadata
BYTES <obj>.size()
TIME <obj>.mtime()
DURATION <obj>.next_check()
BOOL <obj>.deleted()
# Digests that change when the file changes
BLOB <obj>.id()
BLOB <obj>.sha256()
# Error status
BOOL <obj>.error()
STRING <obj>.errmsg()
# VMOD version
STRING file.version()
......@@ -218,6 +227,22 @@ then the previously cached contents continue to be valid. If the file
has changed when a check is performed, it is re-read and the new
contents are cached, for access via the object's methods.
.. |.sha256()| replace:: ``.sha256()``
.. |.id()| replace:: ``.id()``
If ``enable_sha256`` is ``true``, then a SHA256 digest is computed for
the file's contents at initialization time, and whenever the file is
determined to have changed. This is done by the update check, not
during any request/response transaction, and hence does not affect
response times. The digest may then be retrieved with the |.sha256()|_
method. If ``enable_sha256`` is ``false``, then no SHA256 hash is
computed, and it is an error to invoke |.sha256()|_. Since the digest
may be expensive to compute, especially for large files, it may be
advantageous to leave SHA256 disabled, and use the less costly
|.id()|_ method instead; see the documentation of |.sha256()|_ for a
discussion. By default, ``enable_sha256`` is ``false``.
If an error is encountered when a check attempts to re-read the file,
then subsequent method calls attempting to access the contents invoke
VCL failure (see `ERRORS`_ below), with the ``VCL_Error`` message in
......@@ -267,9 +292,9 @@ Examples::
new synth_body = file.reader("synth_body.html", ttl=300s);
# A reader for the file on the given search path, with
# default TTL, and logging for update checks.
# default TTL, logging for update checks, and SHA256 enabled.
new bar = file.reader("bar", path="/var/run/d1:/var/run/d2",
log_checks=true);
log_checks=true, enable_sha256=true);
# A reader for the file with no update checks.
new baz = file.reader("baz", ttl=0s);
......@@ -413,6 +438,8 @@ Example::
set resp.http.Cache-Control = "public, max-age="
+ std.integer(duration=rdr.next_check());
.. _.id():
$Method BLOB .id()
Returns a unique, opaque identifier for the state of the file as
......@@ -429,9 +456,61 @@ The contents of the BLOB returned by ``.id()`` are intentionally not
documented, and should not be relied on to extract information about
the file.
.. _.sha256():
$Method BLOB .sha256()
XXX ...
Returns the SHA256 digest of the file's contents, if the
``enable_sha256`` flag was set to ``true`` in the constructor. Invokes
VCL failure if SHA256 was not enabled, or if the most recent update
check encountered an error.
Example::
import blob;
sub vcl_init {
new rdr = file.reader("/path/to/file", enable_sha256=true);
}
sub vcl_recv {
if (req.http.If-None-Match == blob.encode(BASE64, blob=rdr.sha256())) {
return (synth(304));
}
else {
return (synth(200));
}
}
sub vcl_synth {
set resp.http.ETag = blob.encode(BASE64, blob=rdr.sha256());
if (resp.status == 200) {
rdr.synth();
}
}
The ``.sha256()`` and ``.id()`` methods both return a digest for the
file, each of which changes when the file changes, and hence is
suitable for a header such as ``ETag``. In the typical case, the
``.id()`` method will lead to more efficient use of system resources.
This is because ``.id()`` is derived solely from the file's metadata
-- the fields obtained from ``stat(2)`` -- and when these change, the
file's contents typically have been changed as well.
If only the file metadata have been changed, but not the contents,
then the return value of ``.id()`` changes nevertheless. This may
happen for example if the modification time has been updated by
``touch(1)``, or if the file contents happen to be no different after
an update. In that case, using the ``.id()`` value for
``If-None-Match`` and ``ETag`` may lead to sending the response body
unnecessarily, when a 304 Not Modified response would have been
possible. The return value of ``.sha256()`` remains unchanged in such
a situation.
But if a change in the metadata without a change of the contents is
uncommon, then it makes more sense to disable SHA256 and use
``.id()``. Then the VMOD saves the effort of computing the SHA256
digest, and ``.id()`` is sufficient for a purpose such as ``ETag``.
$Function STRING version()
......@@ -537,6 +616,10 @@ that the mapped file contents may be used imminently (using
reading ahead in the file mapping. But that decision is left to the
kernel.
If SHA256 is enabled, then the digest is computed after the file is
mapped. In that case, I/O for file reads is guaranteed to take place
before any request/response transaction.
SEE ALSO
========
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment