cache_storage.c revision f86a86eea994dc0d186331bec991eed99d108056
2521N/A/* Licensed to the Apache Software Foundation (ASF) under one or more 2521N/A * contributor license agreements. See the NOTICE file distributed with 2521N/A * this work for additional information regarding copyright ownership. 2521N/A * The ASF licenses this file to You under the Apache License, Version 2.0 2521N/A * (the "License"); you may not use this file except in compliance with 2521N/A * the License. You may obtain a copy of the License at 2521N/A * Unless required by applicable law or agreed to in writing, software 2521N/A * distributed under the License is distributed on an "AS IS" BASIS, 2521N/A * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 2521N/A * See the License for the specific language governing permissions and 2521N/A * limitations under the License. 2521N/A/* -------------------------------------------------------------- */ 2521N/A * delete all URL entities from the cache 2521N/A /* Remove the stale cache entry if present. If not, we're 2521N/A * being called from outside of a request; remove the 2521N/A /* for each specified cache type, delete the URL */ * create a new URL entity in the cache * It is possible to store more than once entity per URL. This * function will always create a new entity, regardless of whether * other entities already exist for the same URL. * The size of the entity is provided so that a cache module can * decide whether or not it wants to cache this particular entity. * If the size is unknown, a size of -1 should be set. /* for each specified cache type, delete the URL */ * Take headers from the cache, and overlap them over the existing response * Also unset possible Content-Type headers in r->headers_out and * r->err_headers_out as they may be different to what we have received * Actually they are not needed as r->content_type set by * ap_set_content_type above will be used in the store_headers functions * of the storage providers as a fallback and the HTTP_HEADER filter * does overwrite the Content-Type header with r->content_type anyway. /* If the cache gave us a Last-Modified header, we can't just * pass it on blindly because of restrictions on future values. /* The HTTP specification says that it is legal to merge duplicate * headers into one. Some browsers that support Cookies don't like * merged headers and prefer that each Set-Cookie header is sent * separately. Lets humour those browsers by not merging. * select a specific URL entity in the cache * It is possible to store more than one entity per URL. Content * negotiation is used to select an entity. Once an entity is * selected, details of it are stored in the per request * config to save time when serving the request later. * This function returns OK if successful, DECLINED if no * cached entity fits the bill. /* go through the cache types till we get a match */ /* TODO: Handle this error */ * Check Content-Negotiation - Vary * At this point we need to make sure that the object we found in * the cache is the same object that would be delivered to the * client, when the effects of content negotiation are taken into * In plain english, we want to make sure that a language-negotiated * document in one language is not given to a client asking for a * language negotiated document in a different language by mistake. * This code makes the assumption that the storage manager will * cache the req_hdrs if the response contains a Vary * RFC2616 13.6 and 14.44 describe the Vary mechanism. /* isolate header name */ * is this header in the request and the header in the cached * request identical? If not, we give up and do a straight get /* both headers NULL, so a match - do nothing */ /* both headers exist and are equal - do nothing */ /* headers do not match, so Vary failed */ "cache_select_url(): Vary header mismatch.");
/* Is our cached response fresh enough? */ "conditional request headers.", r->
uri);
/* Make response into a conditional */ /* We can only revalidate with our own conditionals: remove the * conditions from the original request. * Do not do Range requests with our own conditionals: If * we get 304 the Range does not matter and otherwise the * entity changed and we want to have the complete entity /* If we have a cached etag and/or Last-Modified add in * The copy isn't fresh enough, but we cannot revalidate. * So it is the same case as if there had not been a cached * entry at all. Thus delete the entry from cache. "cache: attempt to remove url from cache unsuccessful.");
/* Okay, this response looks okay. Merge in our stuff and go. */ /* try again with next cache type */ /* This should never happen */ "cache: No cache request information available for key" * We have been here before during the processing of this request. * So return the key we already have. * Get the module configuration. We need this for the CacheIgnoreQueryString * 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. * We need to handle both cases in the same manner as for the reverse proxy * case we have the following situation: * If a cached entry is looked up by mod_cache's quick handler r->proxyreq * is still unset in the reverse proxy case as it only gets set in the * translate name hook (either by ProxyPass or mod_rewrite) which is run * after the quick handler hook. This is different to the forward proxy * case where it gets set before the quick handler is run (in the * post_read_request hook). * If a cache entry is created by the CACHE_SAVE filter we always have * r->proxyreq set correctly. * So we must ensure that in the reverse proxy case we use the same code * path and using the canonical name seems to be the right thing to do * in the reverse proxy case. /* Use _default_ as the hostname if none present, as in mod_vhost */ /* Copy the parsed uri hostname */ /* We are a proxied request, with no hostname. Unlikely * to get very far - but just in case */ * Copy the scheme, ensuring that it is lower case. If the parsed uri * contains no string or if this is not a proxy request get the http * scheme for this request. As r->parsed_uri.scheme is not set if this * is a reverse proxy request, it is ensured that the cases * "no proxy request" and "reverse proxy request" are handled in the same * manner (see above why this is needed). /* Copy the scheme and lower-case it */ * If this is a proxy request, but not a reverse proxy request (see comment * above why these cases must be handled in the same manner), copy the * URI's port-string (which may be a service name). If the URI contains * no port-string, use apr-util's notion of the default port for that * scheme - if available. Otherwise use the port-number of the current /* No port string given in the AbsoluteUri, and we have no * idea what the default port for the scheme is. Leave it * blank and live with the inefficiency of some extra cached /* Use the server port */ * Check if we need to ignore session identifiers in the URL and do so * Check that we have a parameter separator in the last segment * of the path and that the parameter matches our identifier * Check if the identifier is in the querystring and cut it out. * First check if the identifier is at the beginning of the * querystring and followed by a '=' * In order to avoid subkey matching (PR 48401) prepend * identifier with a '&' and append a '=' /* If we found something we are sitting on the '&' */ * If querystring is not "", then we have the case * that the identifier parameter we removed was the * last one in the original querystring. Hence we have * a trailing '&' which needs to be removed. /* Key format is a URI, optionally without the query-string */ * Store the key in the request_config for the cache as r->parsed_uri * might have changed in the time from our first visit here triggered by the * quick handler and our possible second visit triggered by the CACHE_SAVE * filter (e.g. r->parsed_uri got unescaped). In this case we would save the * resource in the cache under a key where it is never found by the quick * handler during following requests. "cache: Key for entity %s?%s is %s", r->
uri,