Bug 65285 - mod_expires adds extra Cache-Control header
Summary: mod_expires adds extra Cache-Control header
Status: NEW
Alias: None
Product: Apache httpd-2
Classification: Unclassified
Component: mod_expires (show other bugs)
Version: 2.4.46
Hardware: PC Linux
: P2 minor (vote)
Target Milestone: ---
Assignee: Apache HTTPD Bugs Mailing List
Depends on:
Reported: 2021-05-03 14:41 UTC by jaroslav
Modified: 2021-05-03 14:41 UTC (History)
0 users


Note You need to log in before you can comment on or make changes to this bug.
Description jaroslav 2021-05-03 14:41:41 UTC
One of our clients encountered this behaviour when setting Cache-Control in his PHP script:

header("Content-Type: text/html; charset=utf-8");
header("Cache-Control: max-age=30, must-revalidate", false);

However, server is set to have default expiration of 2 hours for text/html documents:

ExpiresActive On
ExpiresByType text/html "access plus 120 minutes"

This results in these response headers:

  Cache-Control: max-age=30, must-revalidate
  Cache-Control: max-age=7200
  Expires: Mon, 03 May 2021 16:18:24 GMT

This is sort of in accordance with documentation at https://httpd.apache.org/docs/2.4/mod/mod_expires.html which states "When the Expires header is already part of the response generated by the server, for example when generated by a CGI script or proxied from an origin server, this module does not change or add an Expires or Cache-Control header." Indeed, there is no Expires header in response generated by CGI script, but there is a Cache-Control header which gets duplicated (with different value) by mod_expires.

I believe such a behaviour is a bug - server should not add its own Cache-Control header if one is already provided by the application. I understand that can result in final response with different expiration times in Expires (added by mod_expires) and Cache-Control max-age (added by the application), but according to RFC 7234 (section 5.3, https://tools.ietf.org/html/rfc7234#section-5.3 ) this should not pose s problem as Cache-Control takes precedence.

Obviously, workaround exists in the form of

header("Expires: date")

Tested with Apache 2.4.38 from Debian Buster and Apache 2.4.46 from Debian Bullseye.