function _M.access()

in apisix/plugins/proxy-cache/memory_handler.lua [185:276]


function _M.access(conf, ctx)
    local cc = parse_directive_header(ctx.var.http_cache_control)

    if ctx.var.request_method ~= "PURGE" then
        local ret, msg = cacheable_request(conf, ctx, cc)
        if not ret then
            core.response.set_header("Apisix-Cache-Status", msg)
            return
        end
    end

    if not ctx.cache then
        ctx.cache = {
            memory = memory_strategy({shdict_name = conf.cache_zone}),
            hit = false,
            ttl = 0,
        }
    end

    local res, err = ctx.cache.memory:get(ctx.var.upstream_cache_key)

    if ctx.var.request_method == "PURGE" then
        if err == "not found" then
            return 404
        end
        ctx.cache.memory:purge(ctx.var.upstream_cache_key)
        ctx.cache = nil
        return 200
    end

    if err then
        if err == "expired" then
            core.response.set_header("Apisix-Cache-Status", "EXPIRED")

        elseif err ~= "not found" then
            core.response.set_header("Apisix-Cache-Status", "MISS")
            core.log.error("failed to get from cache, err: ", err)

        elseif conf.cache_control and cc["only-if-cached"] then
            core.response.set_header("Apisix-Cache-Status", "MISS")
            return 504

        else
            core.response.set_header("Apisix-Cache-Status", "MISS")
        end
        return
    end

    if res.version ~= CACHE_VERSION then
        core.log.warn("cache format mismatch, purging ", ctx.var.upstream_cache_key)
        core.response.set_header("Apisix-Cache-Status", "BYPASS")
        ctx.cache.memory:purge(ctx.var.upstream_cache_key)
        return
    end

    if conf.cache_control then
        if cc["max-age"] and time() - res.timestamp > cc["max-age"] then
            core.response.set_header("Apisix-Cache-Status", "STALE")
            return
        end

        if cc["max-stale"] and time() - res.timestamp - res.ttl > cc["max-stale"] then
            core.response.set_header("Apisix-Cache-Status", "STALE")
            return
        end

        if cc["min-fresh"] and res.ttl - (time() - res.timestamp) < cc["min-fresh"] then
            core.response.set_header("Apisix-Cache-Status", "STALE")
            return
        end
    else
        if time() - res.timestamp > res.ttl then
            core.response.set_header("Apisix-Cache-Status", "STALE")
            return
        end
    end

    ctx.cache.hit = true

    for key, value in pairs(res.headers) do
        if conf.hide_cache_headers == true and include_cache_header(key) then
            core.response.set_header(key, "")
        elseif overwritable_header(key) then
            core.response.set_header(key, value)
        end
    end

    core.response.set_header("Age", floor(time() - res.timestamp))
    core.response.set_header("Apisix-Cache-Status", "HIT")

    return res.status, res.body
end