Conditional HTTP

Pyramid requests and responses support conditional HTTP requests via the ETag and Last-Modified header. It is useful to enable this for an entire site to save on bandwidth for repeated requests. Enabling ETag support for an entire site can be done using a tween:

 1def conditional_http_tween_factory(handler, registry):
 2    def conditional_http_tween(request):
 3        response = handler(request)
 4
 5        # If the Last-Modified header has been set, we want to enable the
 6        # conditional response processing.
 7        if response.last_modified is not None:
 8            response.conditional_response = True
 9
10        # We want to only enable the conditional machinery if either we
11        # were given an explicit ETag header by the view or we have a
12        # buffered response and can generate the ETag header ourself.
13        if response.etag is not None:
14            response.conditional_response = True
15        elif (isinstance(response.app_iter, collections.abc.Sequence) and
16                len(response.app_iter) == 1):
17            response.conditional_response = True
18            response.md5_etag()
19
20        return response
21    return conditional_http_tween

The effect of this tween is that it will first check the response to determine if it already has a Last-Modified or ETag header set. If it does, then it will enable the conditional response processing. If the response does not have an ETag header set, then it will attempt to determine if the response is already loaded entirely into memory (to avoid loading what might be a very large object into memory). If it is already loaded into memory, then it will generate an ETag header from the MD5 digest of the response body, and again enable the conditional response processing.