Fredrik Widlund wrote:
Hi,
Thanks for the information. Tried the patch and it mends it the
behaviour, however it doesn't really help me of course since I indeed am
trying to rewrite the url before it's cached.
What are the chances of getting a patch that adds a
"CacheIgnoreQueryString" option accepted? Who/where do I ask this?
Kind regards,
Fredrik Widlund
Plüm wrote:
-----Ursprüngliche Nachricht-----
Von: Fredrik Widlund
Gesendet: Freitag, 19. Januar 2007 10:23
An: [email protected]
Betreff: mod_cache+mod_rewrite behaviour
I'm trying to get mod_cache to ignore the query_string part of the
request, since our customers use "clicktags" in references to static
banners. I need to cache these request to improve performance.
My idea was to "RewriteRule .* %{REQUEST_URI}?", however I
have learned
that mod_cache is run as a "quick_handler". However the actual
cache_create_entity() call run _after_ the url being rewritten,
resulting in the behaviour below (some debug calls have been added to
mod_cache). One can see that create_select use the unrewritten request
"http://1.2.3.4:80/index.html?ref=x", and create_select the rewritten
"http://1.2.3.4:80/index.html?". This clearly makes mod_cache and
mod_rewrite incompatible.
This is a known issue and fixed on trunk and proposed for backport to 2.2.x.
Please have a look at PR40805
(http://issues.apache.org/bugzilla/show_bug.cgi?id=40805)
You will find references to a patch there.
The fix is to use the *unmodified* URL / query string consistently.
Regards
Rüdiger
I already have a patch that we're using in production, attached are
patches for the 2.2 and trunk.
I was under the impression that there wasn't any interest in a patch
like this hence I've not opened an issue to get this integrated into the
main package.
The option is CacheStoreQueryString.
Regards,
Scott
Index: modules/cache/mod_cache.c
===================================================================
--- modules/cache/mod_cache.c (revision 497858)
+++ modules/cache/mod_cache.c (working copy)
@@ -446,7 +446,7 @@
/* if a Expires header is in the past, don't cache it */
reason = "Expires header already expired, not cacheable";
}
- else if (r->parsed_uri.query && exps == NULL) {
+ else if (!conf->store_querystring && r->parsed_uri.query && exps == NULL) {
/* if query string present but no expiration time, don't cache it
* (RFC 2616/13.9)
*/
@@ -905,6 +905,8 @@
ps->store_private_set = 0;
ps->store_nostore = 0;
ps->store_nostore_set = 0;
+ ps->store_querystring = 0;
+ ps->store_querystring_set = 0;
/* array of headers that should not be stored in cache */
ps->ignore_headers = apr_array_make(p, 10, sizeof(char *));
ps->ignore_headers_set = CACHE_IGNORE_HEADERS_UNSET;
@@ -950,6 +952,10 @@
(overrides->store_nostore_set == 0)
? base->store_nostore
: overrides->store_nostore;
+ ps->store_querystring =
+ (overrides->store_querystring_set == 0)
+ ? base->store_querystring
+ : overrides->store_querystring;
ps->ignore_headers =
(overrides->ignore_headers_set == CACHE_IGNORE_HEADERS_UNSET)
? base->ignore_headers
@@ -1009,6 +1015,19 @@
return NULL;
}
+static const char *set_cache_store_querystring(cmd_parms *parms, void *dummy,
+ int flag)
+{
+ cache_server_conf *conf;
+
+ conf =
+ (cache_server_conf *)ap_get_module_config(parms->server->module_config,
+ &cache_module);
+ conf->store_querystring = flag;
+ conf->store_querystring_set = 1;
+ return NULL;
+}
+
static const char *add_ignore_header(cmd_parms *parms, void *dummy,
const char *header)
{
@@ -1193,6 +1212,9 @@
AP_INIT_FLAG("CacheStoreNoStore", set_cache_store_nostore,
NULL, RSRC_CONF,
"Ignore 'Cache-Control: no-store' and store sensitive
content"),
+ AP_INIT_FLAG("CacheStoreQueryString", set_cache_store_querystring,
+ NULL, RSRC_CONF,
+ "Store content regardless of query string presence"),
AP_INIT_ITERATE("CacheIgnoreHeaders", add_ignore_header, NULL, RSRC_CONF,
"A space separated list of headers that should not be "
"stored by the cache"),
Index: modules/cache/mod_cache.h
===================================================================
--- modules/cache/mod_cache.h (revision 497858)
+++ modules/cache/mod_cache.h (working copy)
@@ -145,6 +145,9 @@
/** ignore Cache-Control: no-store header from client or server */
int store_nostore;
int store_nostore_set;
+ /** store content regardless of query string presence */
+ int store_querystring;
+ int store_querystring_set;
/** store the headers that should not be stored in the cache */
apr_array_header_t *ignore_headers;
/* flag if CacheIgnoreHeader has been set */
Index: modules/cache/mod_cache.c
===================================================================
--- modules/cache/mod_cache.c (revision 497856)
+++ modules/cache/mod_cache.c (working copy)
@@ -433,7 +433,7 @@
/* if a Expires header is in the past, don't cache it */
reason = "Expires header already expired, not cacheable";
}
- else if (r->args && exps == NULL) {
+ else if (!conf->store_querystring && r->args && exps == NULL) {
/* if query string present but no expiration time, don't cache it
* (RFC 2616/13.9)
*/
@@ -893,6 +893,8 @@
ps->store_private_set = 0;
ps->store_nostore = 0;
ps->store_nostore_set = 0;
+ ps->store_querystring = 0;
+ ps->store_querystring_set = 0;
/* array of headers that should not be stored in cache */
ps->ignore_headers = apr_array_make(p, 10, sizeof(char *));
ps->ignore_headers_set = CACHE_IGNORE_HEADERS_UNSET;
@@ -937,6 +939,10 @@
(overrides->store_nostore_set == 0)
? base->store_nostore
: overrides->store_nostore;
+ ps->store_querystring =
+ (overrides->store_querystring_set == 0)
+ ? base->store_querystring
+ : overrides->store_querystring;
ps->ignore_headers =
(overrides->ignore_headers_set == CACHE_IGNORE_HEADERS_UNSET)
? base->ignore_headers
@@ -996,6 +1002,19 @@
return NULL;
}
+static const char *set_cache_store_querystring(cmd_parms *parms, void *dummy,
+ int flag)
+{
+ cache_server_conf *conf;
+
+ conf =
+ (cache_server_conf *)ap_get_module_config(parms->server->module_config,
+ &cache_module);
+ conf->store_querystring = flag;
+ conf->store_querystring_set = 1;
+ return NULL;
+}
+
static const char *add_ignore_header(cmd_parms *parms, void *dummy,
const char *header)
{
@@ -1165,6 +1184,9 @@
AP_INIT_FLAG("CacheStoreNoStore", set_cache_store_nostore,
NULL, RSRC_CONF,
"Ignore 'Cache-Control: no-store' and store sensitive
content"),
+ AP_INIT_FLAG("CacheStoreQueryString", set_cache_store_querystring,
+ NULL, RSRC_CONF,
+ "Store content regardless of query string presence"),
AP_INIT_ITERATE("CacheIgnoreHeaders", add_ignore_header, NULL, RSRC_CONF,
"A space separated list of headers that should not be "
"stored by the cache"),
Index: modules/cache/mod_cache.h
===================================================================
--- modules/cache/mod_cache.h (revision 497856)
+++ modules/cache/mod_cache.h (working copy)
@@ -144,6 +144,9 @@
/** ignore Cache-Control: no-store header from client or server */
int store_nostore;
int store_nostore_set;
+ /** store content regardless of query string presence */
+ int store_querystring;
+ int store_querystring_set;
/** store the headers that should not be stored in the cache */
apr_array_header_t *ignore_headers;
/* flag if CacheIgnoreHeader has been set */