void
ngx_md5_update(ngx_md5_t *ctx, const void *data, size_t size)
{
    size_t  used, free;
    used = (size_t) (ctx->bytes & 0x3f);
    ctx->bytes += size;
    if (used) {
        free = 64 - used;
        if (size < free) {
            ngx_memcpy(&ctx->buffer[used], data, size);
            return;
        }
        ngx_memcpy(&ctx->buffer[used], data, free);
        data = (u_char *) data + free;
        size -= free;
        (void) ngx_md5_body(ctx, ctx->buffer, 64);
    }
    if (size >= 64) {
        data = ngx_md5_body(ctx, data, size & ~(size_t) 0x3f);
        size &= 0x3f;
    }
    ngx_memcpy(ctx->buffer, data, size);
}
['static ngx_int_t\nngx_http_file_cache_read(ngx_http_request_t *r, ngx_http_cache_t *c)\n{\n    u_char                        *p;\n    time_t                         now;\n    ssize_t                        n;\n    ngx_str_t                     *key;\n    ngx_int_t                      rc;\n    ngx_uint_t                     i;\n    ngx_http_file_cache_t         *cache;\n    ngx_http_file_cache_header_t  *h;\n    n = ngx_http_file_cache_aio_read(r, c);\n    if (n < 0) {\n        return n;\n    }\n    if ((size_t) n < c->header_start) {\n        ngx_log_error(NGX_LOG_CRIT, r->connection->log, 0,\n                      "cache file \\"%s\\" is too small", c->file.name.data);\n        return NGX_DECLINED;\n    }\n    h = (ngx_http_file_cache_header_t *) c->buf->pos;\n    if (h->version != NGX_HTTP_CACHE_VERSION) {\n        ngx_log_error(NGX_LOG_INFO, r->connection->log, 0,\n                      "cache file \\"%s\\" version mismatch", c->file.name.data);\n        return NGX_DECLINED;\n    }\n    if (h->crc32 != c->crc32 || (size_t) h->header_start != c->header_start) {\n        ngx_log_error(NGX_LOG_CRIT, r->connection->log, 0,\n                      "cache file \\"%s\\" has md5 collision", c->file.name.data);\n        return NGX_DECLINED;\n    }\n    p = c->buf->pos + sizeof(ngx_http_file_cache_header_t)\n        + sizeof(ngx_http_file_cache_key);\n    key = c->keys.elts;\n    for (i = 0; i < c->keys.nelts; i++) {\n        if (ngx_memcmp(p, key[i].data, key[i].len) != 0) {\n            ngx_log_error(NGX_LOG_CRIT, r->connection->log, 0,\n                          "cache file \\"%s\\" has md5 collision",\n                          c->file.name.data);\n            return NGX_DECLINED;\n        }\n        p += key[i].len;\n    }\n    if ((size_t) h->body_start > c->body_start) {\n        ngx_log_error(NGX_LOG_CRIT, r->connection->log, 0,\n                      "cache file \\"%s\\" has too long header",\n                      c->file.name.data);\n        return NGX_DECLINED;\n    }\n    if (h->vary_len > NGX_HTTP_CACHE_VARY_LEN) {\n        ngx_log_error(NGX_LOG_CRIT, r->connection->log, 0,\n                      "cache file \\"%s\\" has incorrect vary length",\n                      c->file.name.data);\n        return NGX_DECLINED;\n    }\n    if (h->vary_len) {\n        ngx_http_file_cache_vary(r, h->vary, h->vary_len, c->variant);\n        if (ngx_memcmp(c->variant, h->variant, NGX_HTTP_CACHE_KEY_LEN) != 0) {\n            ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,\n                           "http file cache vary mismatch");\n            return ngx_http_file_cache_reopen(r, c);\n        }\n    }\n    c->buf->last += n;\n    c->valid_sec = h->valid_sec;\n    c->updating_sec = h->updating_sec;\n    c->error_sec = h->error_sec;\n    c->last_modified = h->last_modified;\n    c->date = h->date;\n    c->valid_msec = h->valid_msec;\n    c->body_start = h->body_start;\n    c->etag.len = h->etag_len;\n    c->etag.data = h->etag;\n    r->cached = 1;\n    cache = c->file_cache;\n    if (cache->sh->cold) {\n        ngx_shmtx_lock(&cache->shpool->mutex);\n        if (!c->node->exists) {\n            c->node->uses = 1;\n            c->node->body_start = c->body_start;\n            c->node->exists = 1;\n            c->node->uniq = c->uniq;\n            c->node->fs_size = c->fs_size;\n            cache->sh->size += c->fs_size;\n        }\n        ngx_shmtx_unlock(&cache->shpool->mutex);\n    }\n    now = ngx_time();\n    if (c->valid_sec < now) {\n        c->stale_updating = c->valid_sec + c->updating_sec >= now;\n        c->stale_error = c->valid_sec + c->error_sec >= now;\n        ngx_shmtx_lock(&cache->shpool->mutex);\n        if (c->node->updating) {\n            rc = NGX_HTTP_CACHE_UPDATING;\n        } else {\n            c->node->updating = 1;\n            c->updating = 1;\n            c->lock_time = c->node->lock_time;\n            rc = NGX_HTTP_CACHE_STALE;\n        }\n        ngx_shmtx_unlock(&cache->shpool->mutex);\n        ngx_log_debug3(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,\n                       "http file cache expired: %i %T %T",\n                       rc, c->valid_sec, now);\n        return rc;\n    }\n    return NGX_OK;\n}', 'static void\nngx_http_file_cache_vary(ngx_http_request_t *r, u_char *vary, size_t len,\n    u_char *hash)\n{\n    u_char     *p, *last;\n    ngx_str_t   name;\n    ngx_md5_t   md5;\n    u_char      buf[NGX_HTTP_CACHE_VARY_LEN];\n    ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,\n                   "http file cache vary: \\"%*s\\"", len, vary);\n    ngx_md5_init(&md5);\n    ngx_md5_update(&md5, r->cache->main, NGX_HTTP_CACHE_KEY_LEN);\n    ngx_strlow(buf, vary, len);\n    p = buf;\n    last = buf + len;\n    while (p < last) {\n        while (p < last && (*p == \' \' || *p == \',\')) { p++; }\n        name.data = p;\n        while (p < last && *p != \',\' && *p != \' \') { p++; }\n        name.len = p - name.data;\n        if (name.len == 0) {\n            break;\n        }\n        ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,\n                       "http file cache vary: %V", &name);\n        ngx_md5_update(&md5, name.data, name.len);\n        ngx_md5_update(&md5, (u_char *) ":", sizeof(":") - 1);\n        ngx_http_file_cache_vary_header(r, &md5, &name);\n        ngx_md5_update(&md5, (u_char *) CRLF, sizeof(CRLF) - 1);\n    }\n    ngx_md5_final(hash, &md5);\n}', 'void\nngx_md5_update(ngx_md5_t *ctx, const void *data, size_t size)\n{\n    size_t  used, free;\n    used = (size_t) (ctx->bytes & 0x3f);\n    ctx->bytes += size;\n    if (used) {\n        free = 64 - used;\n        if (size < free) {\n            ngx_memcpy(&ctx->buffer[used], data, size);\n            return;\n        }\n        ngx_memcpy(&ctx->buffer[used], data, free);\n        data = (u_char *) data + free;\n        size -= free;\n        (void) ngx_md5_body(ctx, ctx->buffer, 64);\n    }\n    if (size >= 64) {\n        data = ngx_md5_body(ctx, data, size & ~(size_t) 0x3f);\n        size &= 0x3f;\n    }\n    ngx_memcpy(ctx->buffer, data, size);\n}']