Skip to content

CACHE_LOOKUP_HIT_FRESH status for POST request is not good #8539

@fdiary

Description

@fdiary

Hi !

If ATS receives a POST request to 'fresh cache existing' URL, we have CACHE_LOOKUP_HIT_FRESH status. But ATS will never return such fresh cache unless proxy.config.http.cache.post_method is 1, regardless if POST request (that should be always sent to the backend) succeeds or not. I believe the status should be something else for such 'fresh cache exists but it will not be served' case, by the following reason.

[background]

I am writing a Lua plugin script, that modifies response body. To do that, I want uncompressed response from the backend, thus I use compress plugin, later than lua plugin in plugin.config, to 'remove Accept-Encoding sent to the backend' and 'compress response from ATS'.

  • plugin.config
tslua.so modify_body.lua
compress.so compress.config
  • modify_body.lua
function do_global_read_response()
    ts.hook(TS_LUA_HOOK_SEND_RESPONSE_HDR, modify_body)
end

function do_global_cache_lookup_complete()
    if ts.http.get_cache_lookup_status() == TS_LUA_CACHE_LOOKUP_HIT_FRESH then
        ts.hook(TS_LUA_HOOK_SEND_RESPONSE_HDR, modify_body)
    end
end

function modify_body(data, end_of_stream)
    ...
end
  • compress.config
cache false
remove-accept-encoding true
compressible-content-type text/*

In case of GET request having fresh cache,

  1. (lua) cache_lookup_complete; register transform hook to modify body, because of CACHE_LOOKUP_HIT_FRESH status
  2. (compress) cache_lookup_complete: register transform hook to compress response, because of CACHE_LOOKUP_HIT_FRESH status

case TS_EVENT_HTTP_CACHE_LOOKUP_COMPLETE: {
int obj_status;
if (TS_ERROR != TSHttpTxnCacheLookupStatusGet(txnp, &obj_status) && (TS_CACHE_LOOKUP_HIT_FRESH == obj_status)) {
if (hc != nullptr) {
info("handling compression of cached object");
if (transformable(txnp, false, hc, &compress_type, &algorithms)) {
compress_transform_add(txnp, hc, compress_type, algorithms);

So transform is invoked 1. -> 2. order, that is good.

In case of GET/POST request without fresh cache,

  1. (lua) cache_lookup_complete; do nothing, because of non-CACHE_LOOKUP_HIT_FRESH status
  2. (compress) cache_lookup_complete: do nothing, because of non-CACHE_LOOKUP_HIT_FRESH status
  3. (lua) read_response; register transform hook to modify body
  4. (compress) read_response: register transform hook to compress response

So transform is invoked 3. -> 4. order, that is good.

in case of POST request having fresh cache, the following will happen,

  1. (lua) cache_lookup_complete; register transform hook to modify body, because of CACHE_LOOKUP_HIT_FRESH status, but it is not used as we will anyway have another response from the backend
  2. (compress) cache_lookup_complete: register transform hook to compress response, because of CACHE_LOOKUP_HIT_FRESH status
  3. (lua) read_response; register transform hook to modify body
  4. (compress) read_response: compress plugin does NOT register transform hook, if it is done in cache_lookup_complete stage.

So transform is invoked 2. -> 3. order for the final response, that is NOT good, i.e. for the 'response from the backend to this POST request', compress plugin's compress transform is invoked first, thus Lua script's modify_body function gets compressed result.

(also compress plugin does nothing in send_request timing if transform is registered in cache_lookup_complete timing, remove-access-encoding true is not effective for this case)

To avoid this issue, I patched compress plugin so that it does NOT register transform hook in cache_lookup_complete timing, in case of POST request. But similar issue can happen for any plugin and it breaks expected hook timing order by plugin order in plugin.config.

This is why I would like to propose another status than CACHE_LOOKUP_HIT_FRESH for 'fresh cache exists but it will not be served' case.

Thanks in advance !
Kazuhiko

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions