I am seeing that even though this snippet below unsets the conditional headers, something about r->status being 304 at the start of the internal redirect causes the 304 to be returned I set r->status to 333 as a stupid test right after unsetting conditionals and could see the 333 being traced as a response code in the same path -- so the 304 is not due to the r->headers_in but some lingering r->status. if (reason && r->status == HTTP_NOT_MODIFIED && cache->stale_handle) { ap_log_rerror(APLOG_MARK, APLOG_INFO, 0, r, APLOGNO(02473) "cache: %s responded with an uncacheable 304, " "retrying the request. Reason: %s", r->unparsed_uri, reason); /* we've got a cache conditional miss! tell anyone who cares */ cache_run_cache_status(cache->handle, r, r->headers_out, AP_CACHE_MISS, apr_psprintf(r->pool, "conditional cache miss: 304 was uncacheable, entity removed: %s", reason)); /* remove the cached entity immediately, we might cache it again */ ap_remove_output_filter(cache->remove_url_filter); cache_remove_url(cache, r); /* let someone else attempt to cache */ cache_remove_lock(conf, cache, r, NULL); /* remove this filter from the chain */ ap_remove_output_filter(f); /* retry without the conditionals */ apr_table_unset(r->headers_in, "If-Match"); apr_table_unset(r->headers_in, "If-Modified-Since"); apr_table_unset(r->headers_in, "If-None-Match"); apr_table_unset(r->headers_in, "If-Range"); apr_table_unset(r->headers_in, "If-Unmodified-Since"); ap_internal_redirect(r->unparsed_uri, r); return APR_SUCCESS;
FWIW: In my case the contradiction is intersting too. I am caching a recently created static file that gets a weak etag at startup, then when it expires, httpd generates the same etag but without the W/ prefix.
Created attachment 31937 [details] loglevel trace8 debug + a little added trace of the client that gets a 304 to unconditional request. Before the expiration, the static file got a weak etag, and now it does not have the weak prefix (not traced but clear from logs)
It looks like r->status = HTTP_OK before the internal redirect does the trick. I confirmed the internal redirect could actually return different contents then the state cache thing, and even non-success after this, although I still can't see who short-circuits over r->status != HTTP_OK.
Fixed in 2.4.11 with r1627745.