/* Licensed to the Apache Software Foundation (ASF) under one or more *contributorlicenseagreements.SeetheNOTICEfiledistributedwith *thisworkforadditionalinformationregardingcopyrightownership. *TheASFlicensesthisfiletoYouundertheApacheLicense,Version2.0 *(the"License");youmaynotusethisfileexceptincompliancewith *theLicense.YoumayobtainacopyoftheLicenseat * *http://www.apache.org/licenses/LICENSE-2.0 * *Unlessrequiredbyapplicablelaworagreedtoinwriting,software *distributedundertheLicenseisdistributedonan"ASIS"BASIS, *WITHOUTWARRANTIESORCONDITIONSOFANYKIND,eitherexpressorimplied. *SeetheLicenseforthespecificlanguagegoverningpermissionsand *limitationsundertheLicense.
*/
/* Remove the stale cache entry if present. If not, we're *beingcalledfromoutsideofarequest;removethe *non-stalehandle.
*/
h = cache->stale_handle ? cache->stale_handle : cache->handle; if (!h) { return OK;
}
ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(00691) "cache: Removing url %s from the cache", h->cache_obj->key);
/* for each specified cache type, delete the URL */ while (list) {
list->provider->remove_url(h, r);
list = list->next;
} return OK;
}
if (!cache) { /* This should never happen */
ap_log_rerror(APLOG_MARK, APLOG_ERR, APR_EGENERAL, r, APLOGNO(00692) "cache: No cache request information available for key" " generation"); return APR_EGENERAL;
}
if (!cache->key) {
rv = cache_generate_key(r, r->pool, &cache->key); if (rv != APR_SUCCESS) { return rv;
}
}
list = cache->providers; /* for each specified cache type, delete the URL */ while (list) { switch (rv = list->provider->create_entity(h, r, cache->key, size, in)) { case OK: {
cache->handle = h;
cache->provider = list->provider;
cache->provider_name = list->provider_name; return OK;
} case DECLINED: {
list = list->next; continue;
} default: { return rv;
}
}
} return DECLINED;
}
/* If the cache gave us a Last-Modified header, we can't just *passitonblindlybecauseofrestrictionsonfuturevalues.
*/
v = apr_table_get(r->headers_out, "Last-Modified"); if (v) {
ap_update_mtime(r, apr_date_parse_http(v));
ap_set_last_modified(r);
}
if (!cache) { /* This should never happen */
ap_log_rerror(APLOG_MARK, APLOG_ERR, APR_EGENERAL, r, APLOGNO(00693) "cache: No cache request information available for key" " generation"); return DECLINED;
}
/* if no-cache, we can't serve from the cache, but we may store to the *cache.
*/ if (!ap_cache_check_no_cache(cache, r)) { return DECLINED;
}
if (!cache->key) {
rv = cache_generate_key(r, r->pool, &cache->key); if (rv != APR_SUCCESS) { return DECLINED;
}
}
/* go through the cache types till we get a match */
h = apr_palloc(r->pool, sizeof(cache_handle_t));
list = cache->providers;
while (list) { switch ((rv = list->provider->open_entity(h, r, cache->key))) { case OK: { char *vary = NULL; int mismatch = 0; char *last = NULL;
if (list->provider->recall_headers(h, r) != APR_SUCCESS) { /* try again with next cache type */
list = list->next; continue;
}
/* Is our cached response fresh enough? */ if (mismatch || !cache_check_freshness(h, cache, r)) { constchar *etag, *lastmod;
/* Cache-Control: only-if-cached and revalidation required, try *thenextprovider
*/ if (cache->control_in.only_if_cached) { /* try again with next cache type */
list = list->next; continue;
}
/* set aside the stale entry for accessing later */
cache->stale_headers = apr_table_copy(r->pool,
r->headers_in);
cache->stale_handle = h;
/* if no existing conditionals, use conditionals of our own */ if (!mismatch) {
/* ready to revalidate, pretend we were never here */ return DECLINED;
}
/* Okay, this response looks okay. Merge in our stuff and go. */
cache_accept_headers(h, r, h->resp_hdrs, r->headers_out, 0);
cache->handle = h; return OK;
} case DECLINED: { /* try again with next cache type */
list = list->next; continue;
} default: { /* oo-er! an error */ return rv;
}
}
}
/* if Cache-Control: only-if-cached, and not cached, return 504 */ if (cache->control_in.only_if_cached) {
ap_log_rerror(APLOG_MARK, APLOG_DEBUG, APR_SUCCESS, r, APLOGNO(00696) "cache: 'only-if-cached' requested and no cached entity, " "returning 504 Gateway Timeout for: %s", r->uri); return HTTP_GATEWAY_TIME_OUT;
}
/* *Usethecanonicalnametoimprovecachehitrate,butonlyifthisis *notaproxyrequestorifthisisareverseproxyrequest. *Weneedtohandlebothcasesinthesamemannerasforthereverseproxy *casewehavethefollowingsituation: * *Ifacachedentryislookedupbymod_cache'squickhandlerr->proxyreq *isstillunsetinthereverseproxycaseasitonlygetssetinthe *translatenamehook(eitherbyProxyPassormod_rewrite)whichisrun *afterthequickhandlerhook.Thisisdifferenttotheforwardproxy *casewhereitgetssetbeforethequickhandlerisrun(inthe *post_read_requesthook). *IfacacheentryiscreatedbytheCACHE_SAVEfilterwealwayshave *r->proxyreqsetcorrectly. *Sowemustensurethatinthereverseproxycaseweusethesamecode *pathandusingthecanonicalnameseemstobetherightthingtodo *inthereverseproxycase.
*/ if (!r->proxyreq || (r->proxyreq == PROXYREQ_REVERSE)) { if (conf->base_uri && conf->base_uri->hostname) {
hostname = conf->base_uri->hostname;
} else { /* Use _default_ as the hostname if none present, as in mod_vhost */
hostname = ap_get_server_name(r); if (!hostname) {
hostname = "_default_";
}
}
} elseif (parsed_uri->hostname) { /* Copy the parsed uri hostname */
hn = apr_pstrdup(p, parsed_uri->hostname);
ap_str_tolower(hn); /* const work-around */
hostname = hn;
} else { /* We are a proxied request, with no hostname. Unlikely
* to get very far - but just in case */
hostname = "_default_";
}
/* *Inordertoavoidsubkeymatching(PR48401)prepend *identifierwitha'&'andappenda'='
*/
complete = apr_pstrcat(p, "&", *identifier, "=", NULL);
param = ap_strstr_c(kquery, complete); /* If we found something we are sitting on the '&' */ if (param) {
param++;
}
} if (param) { constchar *amp; char *dup = NULL;
/* Key format is a URI, optionally without the query-string (NULL *peraboveifconf->ignorequerystring)
*/
*key = apr_pstrcat(p, scheme, "://", hostname, port_str,
kpath, "?", kquery, NULL);
if (!cache) { /* This should never happen */
ap_log_rerror(
APLOG_MARK, APLOG_ERR, APR_EGENERAL, r, APLOGNO(00697) "cache: No cache request information available for key" " generation"); return DECLINED;
}
if (!cache->key) {
rv = cache_generate_key(r, r->pool, &cache->key); if (rv != APR_SUCCESS) { return DECLINED;
}
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.