def tee_output():
    """Tee response output to cache storage.

    Internal.
    """
    # Used by CachingTool by attaching to request.hooks

    request = cherrypy.serving.request
    if 'no-store' in request.headers.values('Cache-Control'):
        return

    def tee(body):
        """Tee response.body into a list."""
        if 'no-cache' in response.headers.values(
            'Pragma',
        ) or 'no-store' in response.headers.values('Cache-Control'):
            for chunk in body:
                yield chunk
            return

        output = []
        for chunk in body:
            output.append(chunk)
            yield chunk

        # Save the cache data, but only if the body isn't empty.
        # e.g. a 304 Not Modified on a static file response will
        # have an empty body.
        # If the body is empty, delete the cache because it
        # contains a stale Threading._Event object that will
        # stall all consecutive requests until the _Event times
        # out
        body = b''.join(output)
        if not body:
            cherrypy._cache.delete()
        else:
            cherrypy._cache.put(
                (response.status, response.headers or {}, body, response.time),
                len(body),
            )

    response = cherrypy.serving.response
    response.body = tee(response.body)
Tee response output to cache storage.

    Internal.
    
cherrypy/lib/caching.py