From: Graham Leggett
Date: Mon, 1 Feb 2010 20:43:01 +0000 (+0000)
Subject: Allow fine control over the removal of Last-Modified and ETag headers
X-Git-Tag: 2.3.6~534
X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=d9ea2d64c06df45e529bdc2aee10e448b354f20a;p=thirdparty%2Fapache%2Fhttpd.git
Allow fine control over the removal of Last-Modified and ETag headers
within the INCLUDES filter, making it possible to cache responses if
desired. Fix the default value of the SSIAccessEnable directive.
git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@905406 13f79535-47bb-0310-9956-ffa450edef68
---
diff --git a/CHANGES b/CHANGES
index af191baea33..7c29c5e81f8 100644
--- a/CHANGES
+++ b/CHANGES
@@ -2,6 +2,11 @@
Changes with Apache 2.3.6
+ *) Allow fine control over the removal of Last-Modified and ETag headers
+ within the INCLUDES filter, making it possible to cache responses if
+ desired. Fix the default value of the SSIAccessEnable directive.
+ [Graham Leggett]
+
*) Allow the Define directive to undefine a variable by prefixing the
argument with a '!'. PR 35350. [Stefan Fritsch]
diff --git a/docs/manual/mod/mod_include.xml b/docs/manual/mod/mod_include.xml
index e08204ccd3c..e9b3a8c8cc4 100644
--- a/docs/manual/mod/mod_include.xml
+++ b/docs/manual/mod/mod_include.xml
@@ -809,6 +809,84 @@ displayed
+
+SSIETag
+Controls whether ETags are generated by the server.
+SSIETag on|off
+SSIETag off
+directory.htaccess
+
+
+ Under normal circumstances, a file filtered by mod_include
+ may contain elements that are either dynamically generated, or that may
+ have changed independently of the original file. As a result, by default
+ the server is asked not to generate an ETag header for the
+ response by adding no-etag to the request notes.
+
+ The SSIETag directive suppresses this
+ behaviour, and allows the server to generate an ETag header.
+ This can be used to enable caching of the output. Note that a backend server
+ or dynamic content generator may generate an ETag of its own, ignoring
+ no-etag, and this ETag will be passed by
+ mod_include regardless of the value of this setting.
+ SSIETag can take on the following values:
+
+
+
+ off
+ no-etag will be added to the request notes, and the server
+ is asked not to generate an ETag. Where a server ignores the value of
+ no-etag and generates an ETag anyway, the ETag will be
+ respected.
+
+ on
+ - Existing ETags will be respected, and ETags generated by the server will
+ be passed on in the response.
+
+
+
+
+
+
+
+SSILastModified
+Controls whether Last-Modified headers are generated by the
+server.
+SSILastModified on|off
+SSILastModified off
+directory.htaccess
+
+
+ Under normal circumstances, a file filtered by mod_include
+ may contain elements that are either dynamically generated, or that may
+ have changed independently of the original file. As a result, by default
+ the Last-Modified header is stripped from the response.
+
+ The SSILastModified directive overrides this
+ behaviour, and allows the Last-Modified header to be respected
+ if already present, or set if the header is not already present. This can
+ be used to enable caching of the output. SSILastModified
+ can take on the following values:
+
+
+
+ off
+ - The
Last-Modified header will be stripped from responses,
+ unless the XBitHack directive
+ is set to full as described below.
+
+ on
+ - The
Last-Modified header will be respected if already
+ present in a response, and added to the response if the response is a
+ file and the header is missing. The
+ SSILastModified directive
+ takes precedence over XBitHack.
+
+
+
+
+
+
XBitHack
Parse SSI directives in files with the execute bit
@@ -846,7 +924,14 @@ set
group-execute bit is unset for every SSI script which might #include a CGI or otherwise produces different output on
each hit (or could potentially change on subsequent requests).
+
+ The SSILastModified
+ directive takes precedence over the
+ XBitHack directive when
+ SSILastModified is set to
+ on.
+
diff --git a/modules/filters/mod_include.c b/modules/filters/mod_include.c
index 8c91d331433..e3234e3907d 100644
--- a/modules/filters/mod_include.c
+++ b/modules/filters/mod_include.c
@@ -77,7 +77,9 @@ typedef struct {
const char *default_time_fmt;
const char *undefined_echo;
xbithack_t xbithack;
- const int accessenable;
+ int accessenable;
+ int lastmodified;
+ int etag;
} include_dir_config;
typedef struct {
@@ -417,6 +419,9 @@ static const char lazy_eval_sentinel;
#define DEFAULT_ERROR_MSG "[an error occurred while processing this directive]"
#define DEFAULT_TIME_FORMAT "%A, %d-%b-%Y %H:%M:%S %Z"
#define DEFAULT_UNDEFINED_ECHO "(none)"
+#define DEFAULT_ACCESSENABLE 0
+#define DEFAULT_LASTMODIFIED 0
+#define DEFAULT_ETAG 0
#ifdef XBITHACK
#define DEFAULT_XBITHACK XBITHACK_FULL
@@ -897,7 +902,7 @@ static int ssi_access(request_rec *r, ap_parse_node_t *current,
}
else {
current->value = 0;
- ap_log_rerror(APLOG_MARK, APLOG_DEBUG, rr->status, r,
+ ap_log_rerror(APLOG_MARK, APLOG_DEBUG, rr->status, r,
"mod_include: The tested "
"subrequest -A \"%s\" returned an error code.",
current->right->token.value);
@@ -2911,7 +2916,9 @@ static int includes_setup(ap_filter_t *f)
* We don't know if we are going to be including a file or executing
* a program - in either case a strong ETag header will likely be invalid.
*/
- apr_table_setn(f->r->notes, "no-etag", "");
+ if (!conf->etag) {
+ apr_table_setn(f->r->notes, "no-etag", "");
+ }
return OK;
}
@@ -3014,13 +3021,32 @@ static apr_status_t includes_filter(ap_filter_t *f, apr_bucket_brigade *b)
* a program which may change the Last-Modified header or make the
* content completely dynamic. Therefore, we can't support these
* headers.
- * Exception: XBitHack full means we *should* set the Last-Modified field.
+ *
+ * Exception: XBitHack full means we *should* set the
+ * Last-Modified field.
+ *
+ * SSILastModified on means we *should* set the Last-Modified field
+ * if not present, or respect an existing value if present.
*/
+ /* Must we respect the last modified header? By default, no */
+ if (conf->lastmodified) {
+
+ /* update the last modified if we have a valid time, and only if
+ * we don't already have a valid last modified.
+ */
+ if (r->finfo.valid & APR_FINFO_MTIME
+ && !apr_table_get(f->r->headers_out, "Last-Modified")) {
+ ap_update_mtime(r, r->finfo.mtime);
+ ap_set_last_modified(r);
+ }
+
+ }
+
/* Assure the platform supports Group protections */
- if ((conf->xbithack == XBITHACK_FULL)
+ else if (((conf->xbithack == XBITHACK_FULL)
&& (r->finfo.valid & APR_FINFO_GPROT)
- && (r->finfo.protection & APR_GEXECUTE)) {
+ && (r->finfo.protection & APR_GEXECUTE))) {
ap_update_mtime(r, r->finfo.mtime);
ap_set_last_modified(r);
}
@@ -3100,6 +3126,9 @@ static void *create_includes_dir_config(apr_pool_t *p, char *dummy)
result->default_time_fmt = DEFAULT_TIME_FORMAT;
result->undefined_echo = DEFAULT_UNDEFINED_ECHO;
result->xbithack = DEFAULT_XBITHACK;
+ result->accessenable = DEFAULT_ACCESSENABLE;
+ result->lastmodified = DEFAULT_LASTMODIFIED;
+ result->etag = DEFAULT_ETAG;
return result;
}
@@ -3252,6 +3281,14 @@ static const command_rec includes_cmds[] =
AP_INIT_FLAG("SSIAccessEnable", ap_set_flag_slot,
(void *)APR_OFFSETOF(include_dir_config, accessenable),
OR_LIMIT, "Whether testing access is enabled. Limited to 'on' or 'off'"),
+ AP_INIT_FLAG("SSILastModified", ap_set_flag_slot,
+ (void *)APR_OFFSETOF(include_dir_config, lastmodified),
+ OR_LIMIT, "Whether to set the last modified header or respect "
+ "an existing header. Limited to 'on' or 'off'"),
+ AP_INIT_FLAG("SSIEtag", ap_set_flag_slot,
+ (void *)APR_OFFSETOF(include_dir_config, etag),
+ OR_LIMIT, "Whether to allow the generation of ETags within the server. "
+ "Existing ETags will be preserved. Limited to 'on' or 'off'"),
{NULL}
};