Hi,
This is regarding my
http://issues.apache.org/bugzilla/show_bug.cgi?id=41484 suggested
enhancement. I am attaching the same patch in this mail.
I have a need to use caching to improve performance when delivering for
example banners. Since query-string parameters are used to associate
unique meta-information to each request mod_cache will treat each
request as a new request. Since mod_cache is run as a quick handler it
is not possible to use mod_rewrite to remove the query-string part of
the request.
I believe this should be considered a relevant scenario, and that an
option to disable this behaviour is motivated.
I don't see any drawbacks as a result of this option.
This is very much a real-life scenario, I am a doing this on behalf of a
leading European CDN and we need to use this in a highly distributed
environment to be able to scale efficiently.
PPP regards,
Fredrik Widlund
Plüm skrev:
-----Ursprüngliche Nachricht-----
Von: Fredrik Widlund
Gesendet: Freitag, 19. Januar 2007 12:30
An: dev@httpd.apache.org
Betreff: Re: mod_cache+mod_rewrite behaviour
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?
This is the right place for discussion. I would propose the following:
1. Create a bug report describing your problem and mark it as enhancement.
2. If you have a patch for CacheIgnoreQueryString attach it to the report.
3. Come back here with your problem (in this thread), refer to the report
and attach the patch for convenience.
4. Give some arguments why this is not only useful for you but for everyone
else.
And if there are any drawbacks as a result of your patch why it is worth
the tradeoff.
5. Be PPP (Patient, Polite, Persistent) :-). Keep on buging us from time to
time if the reaction to your proposal is only inactivity and not decline.
Regards
Rüdiger
--- cache_storage.c.orig Sun Jan 28 20:12:51 2007
+++ cache_storage.c Sun Jan 28 20:25:01 2007
@@ -331,10 +331,16 @@
apr_status_t cache_generate_key_default(request_rec *r, apr_pool_t* p,
char**key)
{
+ cache_server_conf *conf;
char *port_str, *hn, *lcs;
const char *hostname, *scheme;
int i;
+ /* Get the module configuration. We need this for the
CacheIgnoreQueryString
+ * below */
+ conf = (cache_server_conf *) ap_get_module_config(r->server->module_config,
+ &cache_module);
+
/*
* Use the canonical name to improve cache hit rate, but only if this is
* not a proxy request or if this is a reverse proxy request.
@@ -424,10 +430,14 @@
/* Use the server port */
port_str = apr_psprintf(p, ":%u", ap_get_server_port(r));
}
-
- /* Key format is a URI */
- *key = apr_pstrcat(p, scheme, "://", hostname, port_str,
- r->parsed_uri.path, "?", r->args, NULL);
+
+ /* Key format is a URI, optionally without the query-string */
+ if (conf->ignorequerystring)
+ *key = apr_pstrcat(p, scheme, "://", hostname, port_str,
+ r->parsed_uri.path, "?", NULL);
+ else
+ *key = apr_pstrcat(p, scheme, "://", hostname, port_str,
+ r->parsed_uri.path, "?", r->args, NULL);
return APR_SUCCESS;
}
--- mod_cache.c.orig Sun Jan 28 20:32:48 2007
+++ mod_cache.c Sun Jan 28 20:32:32 2007
@@ -433,7 +433,8 @@
/* 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->ignorequerystring &&
+ r->parsed_uri.query && exps == NULL) {
/* if query string present but no expiration time, don't cache it
* (RFC 2616/13.9)
*/
@@ -889,6 +890,8 @@
ps->no_last_mod_ignore = 0;
ps->ignorecachecontrol = 0;
ps->ignorecachecontrol_set = 0;
+ ps->ignorequerystring = 0;
+ ps->ignorequerystring_set = 0;
ps->store_private = 0;
ps->store_private_set = 0;
ps->store_nostore = 0;
@@ -929,6 +932,10 @@
(overrides->ignorecachecontrol_set == 0)
? base->ignorecachecontrol
: overrides->ignorecachecontrol;
+ ps->ignorequerystring =
+ (overrides->ignorequerystring_set == 0)
+ ? base->ignorequerystring
+ : overrides->ignorequerystring;
ps->store_private =
(overrides->store_private_set == 0)
? base->store_private
@@ -970,6 +977,19 @@
return NULL;
}
+static const char *set_cache_ignore_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->ignorequerystring = flag;
+ conf->ignorequerystring_set = 1;
+ return NULL;
+}
+
static const char *set_cache_store_private(cmd_parms *parms, void *dummy,
int flag)
{
@@ -1159,6 +1179,9 @@
AP_INIT_FLAG("CacheIgnoreCacheControl", set_cache_ignore_cachecontrol,
NULL, RSRC_CONF,
"Ignore requests from the client for uncached content"),
+ AP_INIT_FLAG("CacheIgnoreQueryString", set_cache_ignore_querystring,
+ NULL, RSRC_CONF,
+ "Ignore query-string when caching"),
AP_INIT_FLAG("CacheStorePrivate", set_cache_store_private,
NULL, RSRC_CONF,
"Ignore 'Cache-Control: private' and store private content"),
--- mod_cache.h.orig Sun Jan 28 20:26:16 2007
+++ mod_cache.h Sun Jan 28 20:27:29 2007
@@ -138,6 +138,9 @@
/** ignore client's requests for uncached responses */
int ignorecachecontrol;
int ignorecachecontrol_set;
+ /** ignore query-string when caching */
+ int ignorequerystring;
+ int ignorequerystring_set;
/** ignore Cache-Control: private header from server */
int store_private;
int store_private_set;