human
Complete this python program:
def blobstore_download_rewriter(state):
assistant
#Here is the Python code you requested.

    """Rewrite a response with blobstore download bodies.
    Checks for the X-AppEngine-BlobKey header in the response.  If found, it will
    discard the body of the request and replace it with the blob content
    indicated.
    If a valid blob is not found, it will send a 404 to the client.
    If the application itself provides a content-type header, it will override
    the content-type stored in the action blob.
    If blobstore.BLOB_RANGE_HEADER header is provided, blob will be partially
    served.  If Range is present, and not blobstore.BLOB_RANGE_HEADER, will use
    Range instead.
    Args:
    state: A request_rewriter.RewriterState to modify.
    """
    blob_key = state.headers.get(blobstore.BLOB_KEY_HEADER)
    if (not blob_key):
        return
    def set_range_request_not_satisfiable(blob_size):
        'Short    circuit    response    and    return    416    error.\n\n                Changes    state    into    the    error    response.\n\n                Args:\n                        blob_size:    The    size    of    the    blob.\n                '
        state.status = '416    Requested    Range    Not    Satisfiable'
        state.headers['Content-Length'] = '0'
        state.headers['Content-Range'] = ('*/%d' % blob_size)
        del state.headers['Content-Type']
    state.body = []
    del state.headers[blobstore.BLOB_KEY_HEADER]
    (blob_size, blob_content_type, blob_open_key) = _get_blob_metadata(blob_key)
    if isinstance(blob_content_type, unicode):
        blob_content_type = blob_content_type.encode('ascii')
    range_header = state.headers.get(blobstore.BLOB_RANGE_HEADER)
    if (range_header is not None):
        del state.headers[blobstore.BLOB_RANGE_HEADER]
    else:
        range_header = state.environ.get('HTTP_RANGE')
    status_code = state.status_code
    if ((blob_size is not None) and (blob_content_type is not None) and (status_code == 200)):
        content_length = blob_size
        start = 0
        end = content_length
        if range_header:
            (start, end) = _parse_range_header(range_header)
            if (start is None):
                set_range_request_not_satisfiable(blob_size)
                return
            else:
                if (start < 0):
                    start = max((blob_size + start), 0)
                elif (start >= blob_size):
                    set_range_request_not_satisfiable(blob_size)
                    return
                if (end is not None):
                    end = min(end, blob_size)
                else:
                    end = blob_size
                content_length = (min(end, blob_size) - start)
                end = (start + content_length)
               ...