1 /* Licensed to the Apache Software Foundation (ASF) under one or more
2 * contributor license agreements. See the NOTICE file distributed with
3 * this work for additional information regarding copyright ownership.
4 * The ASF licenses this file to You under the Apache License, Version 2.0
5 * (the "License"); you may not use this file except in compliance with
6 * the License. You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
19 * @brief Cache Storage Functions
21 * @defgroup Cache_util Cache Utility Functions
33 #include "mod_cache.h"
35 #include "apr_hooks.h"
38 #include "apr_strings.h"
39 #include "apr_buckets.h"
41 #include "apr_pools.h"
42 #include "apr_strings.h"
43 #include "apr_optional.h"
44 #define APR_WANT_STRFUNC
48 #include "http_config.h"
49 #include "ap_config.h"
50 #include "http_core.h"
51 #include "http_protocol.h"
52 #include "http_request.h"
53 #include "http_vhost.h"
54 #include "http_main.h"
56 #include "http_connection.h"
57 #include "util_filter.h"
64 #ifdef HAVE_SYS_SOCKET_H
65 #include <sys/socket.h>
68 #ifdef HAVE_NETINET_IN_H
69 #include <netinet/in.h>
72 #ifdef HAVE_ARPA_INET_H
73 #include <arpa/inet.h>
76 #include "apr_atomic.h"
79 #define MAX(a,b) ((a) > (b) ? (a) : (b))
82 #define MIN(a,b) ((a) < (b) ? (a) : (b))
85 #define MSEC_ONE_DAY ((apr_time_t)(86400*APR_USEC_PER_SEC)) /* one day, in microseconds */
86 #define MSEC_ONE_HR ((apr_time_t)(3600*APR_USEC_PER_SEC)) /* one hour, in microseconds */
87 #define MSEC_ONE_MIN ((apr_time_t)(60*APR_USEC_PER_SEC)) /* one minute, in microseconds */
88 #define MSEC_ONE_SEC ((apr_time_t)(APR_USEC_PER_SEC)) /* one second, in microseconds */
90 #define DEFAULT_CACHE_MAXEXPIRE MSEC_ONE_DAY
91 #define DEFAULT_CACHE_MINEXPIRE 0
92 #define DEFAULT_CACHE_EXPIRE MSEC_ONE_HR
93 #define DEFAULT_CACHE_LMFACTOR (0.1)
94 #define DEFAULT_CACHE_MAXAGE 5
95 #define DEFAULT_X_CACHE 0
96 #define DEFAULT_X_CACHE_DETAIL 0
97 #define DEFAULT_CACHE_STALE_ON_ERROR 1
98 #define DEFAULT_CACHE_LOCKPATH "/mod_cache-lock"
99 #define CACHE_LOCKNAME_KEY "mod_cache-lockname"
100 #define CACHE_LOCKFILE_KEY "mod_cache-lockfile"
101 #define CACHE_CTX_KEY "mod_cache-ctx"
107 struct cache_enable {
113 struct cache_disable {
118 /* static information about the local cache */
120 apr_array_header_t *cacheenable; /* URLs to cache */
121 apr_array_header_t *cachedisable; /* URLs not to cache */
122 /** store the headers that should not be stored in the cache */
123 apr_array_header_t *ignore_headers;
124 /** store the identifiers that should not be used for key calculation */
125 apr_array_header_t *ignore_session_id;
126 const char *lockpath;
127 apr_time_t lockmaxage;
129 /** ignore client's requests for uncached responses */
130 int ignorecachecontrol:1;
131 /** ignore query-string when caching */
132 int ignorequerystring:1;
133 /** run within the quick handler */
135 /* thundering herd lock */
138 int x_cache_detail:1;
139 /* flag if CacheIgnoreHeader has been set */
140 #define CACHE_IGNORE_HEADERS_SET 1
141 #define CACHE_IGNORE_HEADERS_UNSET 0
142 int ignore_headers_set:1;
143 /* flag if CacheIgnoreURLSessionIdentifiers has been set */
144 #define CACHE_IGNORE_SESSION_ID_SET 1
145 #define CACHE_IGNORE_SESSION_ID_UNSET 0
146 int ignore_session_id_set:1;
148 int ignorecachecontrol_set:1;
149 int ignorequerystring_set:1;
153 int lockmaxage_set:1;
155 int x_cache_detail_set:1;
159 /* Minimum time to keep cached files in msecs */
161 /* Maximum time to keep cached files in msecs */
163 /* default time to keep cached file in msecs */
165 /* factor for estimating expires date */
167 /* set X-Cache headers */
169 int x_cache_detail:1;
170 /* serve stale on error */
171 int stale_on_error:1;
172 /** ignore the last-modified header when deciding to cache this request */
173 int no_last_mod_ignore:1;
174 /** ignore expiration date from server */
176 /** ignore Cache-Control: private header from server */
178 /** ignore Cache-Control: no-store header from client or server */
185 int x_cache_detail_set:1;
186 int stale_on_error_set:1;
187 int no_last_mod_ignore_set:1;
188 int store_expired_set:1;
189 int store_private_set:1;
190 int store_nostore_set:1;
193 /* A linked-list of authn providers. */
194 typedef struct cache_provider_list cache_provider_list;
196 struct cache_provider_list {
197 const char *provider_name;
198 const cache_provider *provider;
199 cache_provider_list *next;
202 /* per request cache information */
204 cache_provider_list *providers; /* possible cache providers */
205 const cache_provider *provider; /* current cache provider */
206 const char *provider_name; /* current cache provider name */
207 int fresh; /* is the entity fresh? */
208 cache_handle_t *handle; /* current cache handle */
209 cache_handle_t *stale_handle; /* stale cache handle */
210 apr_table_t *stale_headers; /* original request headers. */
211 int in_checked; /* CACHE_SAVE must cache the entity */
212 int block_response; /* CACHE_SAVE must block response. */
213 apr_bucket_brigade *saved_brigade; /* copy of partial response */
214 apr_off_t saved_size; /* length of saved_brigade */
215 apr_time_t exp; /* expiration */
216 apr_time_t lastmod; /* last-modified time */
217 cache_info *info; /* current cache info */
218 ap_filter_t *save_filter; /* Enable us to restore the filter on error */
219 ap_filter_t *remove_url_filter; /* Enable us to remove the filter */
220 const char *key; /* The cache key created for this
223 apr_off_t size; /* the content length from the headers, or -1 */
224 apr_bucket_brigade *out; /* brigade to reuse for upstream responses */
225 cache_control_t control_in; /* cache control incoming */
229 * Check the whether the request allows a cached object to be served as per RFC2616
230 * section 14.9.4 (Cache Revalidation and Reload Controls)
231 * @param h cache_handle_t
232 * @param r request_rec
233 * @return 0 ==> cache object may not be served, 1 ==> cache object may be served
235 CACHE_DECLARE(int) ap_cache_check_allowed(cache_request_rec *cache, request_rec *r);
238 * Check the freshness of the cache object per RFC2616 section 13.2 (Expiration Model)
239 * @param h cache_handle_t
240 * @param r request_rec
241 * @return 0 ==> cache object is stale, 1 ==> cache object is fresh
243 int cache_check_freshness(cache_handle_t *h, cache_request_rec *cache,
247 * Try obtain a cache wide lock on the given cache key.
249 * If we return APR_SUCCESS, we obtained the lock, and we are clear to
250 * proceed to the backend. If we return APR_EEXISTS, the the lock is
251 * already locked, someone else has gone to refresh the backend data
252 * already, so we must return stale data with a warning in the mean
253 * time. If we return anything else, then something has gone pear
254 * shaped, and we allow the request through to the backend regardless.
256 * This lock is created from the request pool, meaning that should
257 * something go wrong and the lock isn't deleted on return of the
258 * request headers from the backend for whatever reason, at worst the
259 * lock will be cleaned up when the request is dies or finishes.
261 * If something goes truly bananas and the lock isn't deleted when the
262 * request dies, the lock will be trashed when its max-age is reached,
263 * or when a request arrives containing a Cache-Control: no-cache. At
264 * no point is it possible for this lock to permanently deny access to
267 apr_status_t cache_try_lock(cache_server_conf *conf, cache_request_rec *cache,
271 * Remove the cache lock, if present.
273 * First, try to close the file handle, whose delete-on-close should
274 * kill the file. Otherwise, just delete the file by name.
276 * If no lock name has yet been calculated, do the calculation of the
277 * lock name first before trying to delete the file.
279 * If an optional bucket brigade is passed, the lock will only be
280 * removed if the bucket brigade contains an EOS bucket.
282 apr_status_t cache_remove_lock(cache_server_conf *conf,
283 cache_request_rec *cache, request_rec *r, apr_bucket_brigade *bb);
285 cache_provider_list *cache_get_providers(request_rec *r,
286 cache_server_conf *conf, apr_uri_t uri);
292 #endif /* !CACHE_UTIL_H */