mirror of
https://github.com/apache/httpd.git
synced 2025-07-30 20:03:10 +03:00
mod_cache: Make sure Vary processing handles multivalued Vary headers and
multivalued headers referred to via Vary. git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@1478748 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
3
CHANGES
3
CHANGES
@ -1,6 +1,9 @@
|
|||||||
-*- coding: utf-8 -*-
|
-*- coding: utf-8 -*-
|
||||||
Changes with Apache 2.5.0
|
Changes with Apache 2.5.0
|
||||||
|
|
||||||
|
*) mod_cache: Make sure Vary processing handles multivalued Vary headers and
|
||||||
|
multivalued headers referred to via Vary. [Graham Leggett]
|
||||||
|
|
||||||
*) mod_cache: When serving from cache, only the last header of a multivalued
|
*) mod_cache: When serving from cache, only the last header of a multivalued
|
||||||
header was taken into account. Fixed. [Graham Leggett]
|
header was taken into account. Fixed. [Graham Leggett]
|
||||||
|
|
||||||
|
22
modules/cache/cache_storage.c
vendored
22
modules/cache/cache_storage.c
vendored
@ -220,6 +220,7 @@ int cache_select(cache_request_rec *cache, request_rec *r)
|
|||||||
case OK: {
|
case OK: {
|
||||||
char *vary = NULL;
|
char *vary = NULL;
|
||||||
int fresh, mismatch = 0;
|
int fresh, mismatch = 0;
|
||||||
|
char *last = NULL;
|
||||||
|
|
||||||
if (list->provider->recall_headers(h, r) != APR_SUCCESS) {
|
if (list->provider->recall_headers(h, r) != APR_SUCCESS) {
|
||||||
/* try again with next cache type */
|
/* try again with next cache type */
|
||||||
@ -245,25 +246,19 @@ int cache_select(cache_request_rec *cache, request_rec *r)
|
|||||||
*
|
*
|
||||||
* RFC2616 13.6 and 14.44 describe the Vary mechanism.
|
* RFC2616 13.6 and 14.44 describe the Vary mechanism.
|
||||||
*/
|
*/
|
||||||
vary = apr_pstrdup(r->pool, apr_table_get(h->resp_hdrs, "Vary"));
|
vary = cache_strqtok(
|
||||||
while (vary && *vary) {
|
apr_pstrdup(r->pool,
|
||||||
char *name = vary;
|
cache_table_getm(r->pool, h->resp_hdrs, "Vary")),
|
||||||
|
CACHE_SEPARATOR, &last);
|
||||||
|
while (vary) {
|
||||||
const char *h1, *h2;
|
const char *h1, *h2;
|
||||||
|
|
||||||
/* isolate header name */
|
|
||||||
while (*vary && !apr_isspace(*vary) && (*vary != ','))
|
|
||||||
++vary;
|
|
||||||
while (apr_isspace(*vary) || (*vary == ',')) {
|
|
||||||
*vary = '\0';
|
|
||||||
++vary;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* is this header in the request and the header in the cached
|
* is this header in the request and the header in the cached
|
||||||
* request identical? If not, we give up and do a straight get
|
* request identical? If not, we give up and do a straight get
|
||||||
*/
|
*/
|
||||||
h1 = apr_table_get(r->headers_in, name);
|
h1 = cache_table_getm(r->pool, r->headers_in, vary);
|
||||||
h2 = apr_table_get(h->req_hdrs, name);
|
h2 = cache_table_getm(r->pool, h->req_hdrs, vary);
|
||||||
if (h1 == h2) {
|
if (h1 == h2) {
|
||||||
/* both headers NULL, so a match - do nothing */
|
/* both headers NULL, so a match - do nothing */
|
||||||
}
|
}
|
||||||
@ -277,6 +272,7 @@ int cache_select(cache_request_rec *cache, request_rec *r)
|
|||||||
mismatch = 1;
|
mismatch = 1;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
vary = cache_strqtok(NULL, CACHE_SEPARATOR, &last);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* no vary match, try next provider */
|
/* no vary match, try next provider */
|
||||||
|
8
modules/cache/cache_util.c
vendored
8
modules/cache/cache_util.c
vendored
@ -27,8 +27,6 @@ extern APR_OPTIONAL_FN_TYPE(ap_cache_generate_key) *cache_generate_key;
|
|||||||
|
|
||||||
extern module AP_MODULE_DECLARE_DATA cache_module;
|
extern module AP_MODULE_DECLARE_DATA cache_module;
|
||||||
|
|
||||||
#define CACHE_SEPARATOR ", "
|
|
||||||
|
|
||||||
/* Determine if "url" matches the hostname, scheme and port and path
|
/* Determine if "url" matches the hostname, scheme and port and path
|
||||||
* in "filter". All but the path comparisons are case-insensitive.
|
* in "filter". All but the path comparisons are case-insensitive.
|
||||||
*/
|
*/
|
||||||
@ -862,7 +860,7 @@ CACHE_DECLARE(char *)ap_cache_generate_name(apr_pool_t *p, int dirlevels,
|
|||||||
* String tokenizer that ignores separator characters within quoted strings
|
* String tokenizer that ignores separator characters within quoted strings
|
||||||
* and escaped characters, as per RFC2616 section 2.2.
|
* and escaped characters, as per RFC2616 section 2.2.
|
||||||
*/
|
*/
|
||||||
static char *cache_strqtok(char *str, const char *sep, char **last)
|
char *cache_strqtok(char *str, const char *sep, char **last)
|
||||||
{
|
{
|
||||||
char *token;
|
char *token;
|
||||||
int quoted = 0;
|
int quoted = 0;
|
||||||
@ -871,6 +869,10 @@ static char *cache_strqtok(char *str, const char *sep, char **last)
|
|||||||
str = *last; /* start where we left off */
|
str = *last; /* start where we left off */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!str) { /* no more tokens */
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
/* skip characters in sep (will terminate at '\0') */
|
/* skip characters in sep (will terminate at '\0') */
|
||||||
while (*str && ap_strchr_c(sep, *str)) {
|
while (*str && ap_strchr_c(sep, *str)) {
|
||||||
++str;
|
++str;
|
||||||
|
7
modules/cache/cache_util.h
vendored
7
modules/cache/cache_util.h
vendored
@ -99,6 +99,7 @@ extern "C" {
|
|||||||
#define CACHE_LOCKNAME_KEY "mod_cache-lockname"
|
#define CACHE_LOCKNAME_KEY "mod_cache-lockname"
|
||||||
#define CACHE_LOCKFILE_KEY "mod_cache-lockfile"
|
#define CACHE_LOCKFILE_KEY "mod_cache-lockfile"
|
||||||
#define CACHE_CTX_KEY "mod_cache-ctx"
|
#define CACHE_CTX_KEY "mod_cache-ctx"
|
||||||
|
#define CACHE_SEPARATOR ", "
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* cache_util.c
|
* cache_util.c
|
||||||
@ -305,6 +306,12 @@ cache_provider_list *cache_get_providers(request_rec *r,
|
|||||||
const char *cache_table_getm(apr_pool_t *p, const apr_table_t *t,
|
const char *cache_table_getm(apr_pool_t *p, const apr_table_t *t,
|
||||||
const char *key);
|
const char *key);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* String tokenizer that ignores separator characters within quoted strings
|
||||||
|
* and escaped characters, as per RFC2616 section 2.2.
|
||||||
|
*/
|
||||||
|
char *cache_strqtok(char *str, const char *sep, char **last);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
Reference in New Issue
Block a user