const char *etag, *lastmod;
/* Make response into a conditional */
+ cache->stale_headers = apr_table_copy(r->pool,
+ r->headers_in);
+
+ /* We can only revalidate with our own conditionals: remove the
+ * conditions from the original request.
+ */
+ 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");
- /* FIXME: What if the request is already conditional? */
etag = apr_table_get(h->resp_hdrs, "ETag");
lastmod = apr_table_get(h->resp_hdrs, "Last-Modified");
if (etag || lastmod) {
- /* If we have a cached etag and/or Last-Modified */
+ /* If we have a cached etag and/or Last-Modified add in
+ * our own conditionals.
+ */
- cache->stale_headers = apr_table_copy(r->pool,
- r->headers_in);
if (etag) {
apr_table_set(r->headers_in, "If-None-Match", etag);
}
/* Did we just update the cached headers on a revalidated response?
*
- * If so, we can now decide what to serve to the client:
- * - If the original request was conditional and is satisified, send 304.
- * - Otherwise, send the cached body.
- */
+ * If so, we can now decide what to serve to the client. This is done in
+ * the same way as with a regular response, but conditions are now checked
+ * against the cached or merged response headers.
+ */
if (rv == APR_SUCCESS && cache->stale_handle) {
apr_bucket_brigade *bb;
apr_bucket *bkt;
+ int status;
bb = apr_brigade_create(r->pool, r->connection->bucket_alloc);
- /* Were we initially a conditional request? */
- if (ap_cache_request_is_conditional(cache->stale_headers)) {
- /* FIXME: We must ensure that the request meets conditions. */
-
- /* Set the status to be a 304. */
- r->status = HTTP_NOT_MODIFIED;
+ /* Restore the original request headers and see if we need to
+ * return anything else than the cached response (ie. the original
+ * request was conditional).
+ */
+ r->headers_in = cache->stale_headers;
+ status = ap_meets_conditions(r);
+ if (status != OK) {
+ r->status = status;
bkt = apr_bucket_flush_create(bb->bucket_alloc);
APR_BRIGADE_INSERT_TAIL(bb, bkt);