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 unsigned int ignorecachecontrol:1;
131 /** ignore query-string when caching */
132 unsigned int ignorequerystring:1;
133 /** run within the quick handler */
134 unsigned int quick:1;
135 /* thundering herd lock */
137 unsigned int x_cache:1;
138 unsigned 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 unsigned 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 unsigned int ignore_session_id_set:1;
147 unsigned int base_uri_set:1;
148 unsigned int ignorecachecontrol_set:1;
149 unsigned int ignorequerystring_set:1;
150 unsigned int quick_set:1;
151 unsigned int lock_set:1;
152 unsigned int lockpath_set:1;
153 unsigned int lockmaxage_set:1;
154 unsigned int x_cache_set:1;
155 unsigned 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 /* cache enabled for this location */
168 apr_array_header_t *cacheenable;
169 /* cache disabled for this location */
170 unsigned int disable:1;
171 /* set X-Cache headers */
172 unsigned int x_cache:1;
173 unsigned int x_cache_detail:1;
174 /* serve stale on error */
175 unsigned int stale_on_error:1;
176 /** ignore the last-modified header when deciding to cache this request */
177 unsigned int no_last_mod_ignore:1;
178 /** ignore expiration date from server */
179 unsigned int store_expired:1;
180 /** ignore Cache-Control: private header from server */
181 unsigned int store_private:1;
182 /** ignore Cache-Control: no-store header from client or server */
183 unsigned int store_nostore:1;
184 unsigned int minex_set:1;
185 unsigned int maxex_set:1;
186 unsigned int defex_set:1;
187 unsigned int factor_set:1;
188 unsigned int x_cache_set:1;
189 unsigned int x_cache_detail_set:1;
190 unsigned int stale_on_error_set:1;
191 unsigned int no_last_mod_ignore_set:1;
192 unsigned int store_expired_set:1;
193 unsigned int store_private_set:1;
194 unsigned int store_nostore_set:1;
195 unsigned int enable_set:1;
196 unsigned int disable_set:1;
199 /* A linked-list of authn providers. */
200 typedef struct cache_provider_list cache_provider_list;
202 struct cache_provider_list {
203 const char *provider_name;
204 const cache_provider *provider;
205 cache_provider_list *next;
208 /* per request cache information */
210 cache_provider_list *providers; /* possible cache providers */
211 const cache_provider *provider; /* current cache provider */
212 const char *provider_name; /* current cache provider name */
213 int fresh; /* is the entity fresh? */
214 cache_handle_t *handle; /* current cache handle */
215 cache_handle_t *stale_handle; /* stale cache handle */
216 apr_table_t *stale_headers; /* original request headers. */
217 int in_checked; /* CACHE_SAVE must cache the entity */
218 int block_response; /* CACHE_SAVE must block response. */
219 apr_bucket_brigade *saved_brigade; /* copy of partial response */
220 apr_off_t saved_size; /* length of saved_brigade */
221 apr_time_t exp; /* expiration */
222 apr_time_t lastmod; /* last-modified time */
223 cache_info *info; /* current cache info */
224 ap_filter_t *save_filter; /* Enable us to restore the filter on error */
225 ap_filter_t *remove_url_filter; /* Enable us to remove the filter */
226 const char *key; /* The cache key created for this
229 apr_off_t size; /* the content length from the headers, or -1 */
230 apr_bucket_brigade *out; /* brigade to reuse for upstream responses */
231 cache_control_t control_in; /* cache control incoming */
235 * Check the whether the request allows a cached object to be served as per RFC2616
236 * section 14.9.4 (Cache Revalidation and Reload Controls)
237 * @param cache cache_request_rec
238 * @param r request_rec
239 * @return 0 ==> cache object may not be served, 1 ==> cache object may be served
241 int ap_cache_check_no_cache(cache_request_rec *cache, request_rec *r);
244 * Check the whether the request allows a cached object to be stored as per RFC2616
245 * section 14.9.2 (What May be Stored by Caches)
246 * @param cache cache_request_rec
247 * @param r request_rec
248 * @return 0 ==> cache object may not be served, 1 ==> cache object may be served
250 int ap_cache_check_no_store(cache_request_rec *cache, request_rec *r);
253 * Check the freshness of the cache object per RFC2616 section 13.2 (Expiration Model)
254 * @param h cache_handle_t
255 * @param cache cache_request_rec
256 * @param r request_rec
257 * @return 0 ==> cache object is stale, 1 ==> cache object is fresh
259 int cache_check_freshness(cache_handle_t *h, cache_request_rec *cache,
263 * Try obtain a cache wide lock on the given cache key.
265 * If we return APR_SUCCESS, we obtained the lock, and we are clear to
266 * proceed to the backend. If we return APR_EEXISTS, then the lock is
267 * already locked, someone else has gone to refresh the backend data
268 * already, so we must return stale data with a warning in the mean
269 * time. If we return anything else, then something has gone pear
270 * shaped, and we allow the request through to the backend regardless.
272 * This lock is created from the request pool, meaning that should
273 * something go wrong and the lock isn't deleted on return of the
274 * request headers from the backend for whatever reason, at worst the
275 * lock will be cleaned up when the request is dies or finishes.
277 * If something goes truly bananas and the lock isn't deleted when the
278 * request dies, the lock will be trashed when its max-age is reached,
279 * or when a request arrives containing a Cache-Control: no-cache. At
280 * no point is it possible for this lock to permanently deny access to
283 apr_status_t cache_try_lock(cache_server_conf *conf, cache_request_rec *cache,
287 * Remove the cache lock, if present.
289 * First, try to close the file handle, whose delete-on-close should
290 * kill the file. Otherwise, just delete the file by name.
292 * If no lock name has yet been calculated, do the calculation of the
293 * lock name first before trying to delete the file.
295 * If an optional bucket brigade is passed, the lock will only be
296 * removed if the bucket brigade contains an EOS bucket.
298 apr_status_t cache_remove_lock(cache_server_conf *conf,
299 cache_request_rec *cache, request_rec *r, apr_bucket_brigade *bb);
301 cache_provider_list *cache_get_providers(request_rec *r,
302 cache_server_conf *conf);
305 * Get a value from a table, where the table may contain multiple
306 * values for a given key.
308 * When the table contains a single value, that value is returned
311 * When the table contains two or more values for a key, all values
312 * for the key are returned, separated by commas.
314 const char *cache_table_getm(apr_pool_t *p, const apr_table_t *t,
318 * String tokenizer per RFC 7234 section 5.2 (1#token[=["]arg["]]).
319 * If any (and arg not NULL), the argument is also returned (unquoted).
321 apr_status_t cache_strqtok(char *str, char **token, char **arg, char **last);
324 * Merge err_headers_out into headers_out and add request's Content-Type and
325 * Content-Encoding if available.
327 apr_table_t *cache_merge_headers_out(request_rec *r);
330 * Return whether to use request's path/query from early stage (r->parsed_uri)
331 * or the current/rewritable ones (r->uri/r->args).
333 int cache_use_early_url(request_rec *r);
339 #endif /* !CACHE_UTIL_H */