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 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 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. 15 */ 16 17 /** 18 * @file cache_util.h 19 * @brief Cache Storage Functions 20 * 21 * @defgroup Cache_util Cache Utility Functions 22 * @ingroup MOD_CACHE 23 * @{ 24 */ 25 26 #ifndef CACHE_UTIL_H 27 #define CACHE_UTIL_H 28 29 #ifdef __cplusplus 30 extern "C" { 31 #endif 32 33 #include "mod_cache.h" 34 35 #include "apr_hooks.h" 36 #include "apr.h" 37 #include "apr_lib.h" 38 #include "apr_strings.h" 39 #include "apr_buckets.h" 40 #include "apr_md5.h" 41 #include "apr_pools.h" 42 #include "apr_strings.h" 43 #include "apr_optional.h" 44 #define APR_WANT_STRFUNC 45 #include "apr_want.h" 46 47 #include "httpd.h" 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" 55 #include "http_log.h" 56 #include "http_connection.h" 57 #include "util_filter.h" 58 #include "apr_uri.h" 59 60 #ifdef HAVE_NETDB_H 61 #include <netdb.h> 62 #endif 63 64 #ifdef HAVE_SYS_SOCKET_H 65 #include <sys/socket.h> 66 #endif 67 68 #ifdef HAVE_NETINET_IN_H 69 #include <netinet/in.h> 70 #endif 71 72 #ifdef HAVE_ARPA_INET_H 73 #include <arpa/inet.h> 74 #endif 75 76 #include "apr_atomic.h" 77 78 #ifndef MAX 79 #define MAX(a,b) ((a) > (b) ? (a) : (b)) 80 #endif 81 #ifndef MIN 82 #define MIN(a,b) ((a) < (b) ? (a) : (b)) 83 #endif 84 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 */ 89 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" 102 #define CACHE_SEPARATOR ", " 103 104 /** 105 * cache_util.c 106 */ 107 108 struct cache_enable { 109 apr_uri_t url; 110 const char *type; 111 apr_size_t pathlen; 112 }; 113 114 struct cache_disable { 115 apr_uri_t url; 116 apr_size_t pathlen; 117 }; 118 119 /* static information about the local cache */ 120 typedef struct { 121 apr_array_header_t *cacheenable; /* URLs to cache */ 122 apr_array_header_t *cachedisable; /* URLs not to cache */ 123 /** store the headers that should not be stored in the cache */ 124 apr_array_header_t *ignore_headers; 125 /** store the identifiers that should not be used for key calculation */ 126 apr_array_header_t *ignore_session_id; 127 const char *lockpath; 128 apr_time_t lockmaxage; 129 apr_uri_t *base_uri; 130 /** ignore client's requests for uncached responses */ 131 unsigned int ignorecachecontrol:1; 132 /** ignore query-string when caching */ 133 unsigned int ignorequerystring:1; 134 /** run within the quick handler */ 135 unsigned int quick:1; 136 /* thundering herd lock */ 137 unsigned int lock:1; 138 unsigned int x_cache:1; 139 unsigned int x_cache_detail:1; 140 /* flag if CacheIgnoreHeader has been set */ 141 #define CACHE_IGNORE_HEADERS_SET 1 142 #define CACHE_IGNORE_HEADERS_UNSET 0 143 unsigned int ignore_headers_set:1; 144 /* flag if CacheIgnoreURLSessionIdentifiers has been set */ 145 #define CACHE_IGNORE_SESSION_ID_SET 1 146 #define CACHE_IGNORE_SESSION_ID_UNSET 0 147 unsigned int ignore_session_id_set:1; 148 unsigned int base_uri_set:1; 149 unsigned int ignorecachecontrol_set:1; 150 unsigned int ignorequerystring_set:1; 151 unsigned int quick_set:1; 152 unsigned int lock_set:1; 153 unsigned int lockpath_set:1; 154 unsigned int lockmaxage_set:1; 155 unsigned int x_cache_set:1; 156 unsigned int x_cache_detail_set:1; 157 } cache_server_conf; 158 159 typedef struct { 160 /* Minimum time to keep cached files in msecs */ 161 apr_time_t minex; 162 /* Maximum time to keep cached files in msecs */ 163 apr_time_t maxex; 164 /* default time to keep cached file in msecs */ 165 apr_time_t defex; 166 /* factor for estimating expires date */ 167 double factor; 168 /* cache enabled for this location */ 169 apr_array_header_t *cacheenable; 170 /* cache disabled for this location */ 171 unsigned int disable:1; 172 /* set X-Cache headers */ 173 unsigned int x_cache:1; 174 unsigned int x_cache_detail:1; 175 /* serve stale on error */ 176 unsigned int stale_on_error:1; 177 /** ignore the last-modified header when deciding to cache this request */ 178 unsigned int no_last_mod_ignore:1; 179 /** ignore expiration date from server */ 180 unsigned int store_expired:1; 181 /** ignore Cache-Control: private header from server */ 182 unsigned int store_private:1; 183 /** ignore Cache-Control: no-store header from client or server */ 184 unsigned int store_nostore:1; 185 unsigned int minex_set:1; 186 unsigned int maxex_set:1; 187 unsigned int defex_set:1; 188 unsigned int factor_set:1; 189 unsigned int x_cache_set:1; 190 unsigned int x_cache_detail_set:1; 191 unsigned int stale_on_error_set:1; 192 unsigned int no_last_mod_ignore_set:1; 193 unsigned int store_expired_set:1; 194 unsigned int store_private_set:1; 195 unsigned int store_nostore_set:1; 196 unsigned int enable_set:1; 197 unsigned int disable_set:1; 198 } cache_dir_conf; 199 200 /* A linked-list of authn providers. */ 201 typedef struct cache_provider_list cache_provider_list; 202 203 struct cache_provider_list { 204 const char *provider_name; 205 const cache_provider *provider; 206 cache_provider_list *next; 207 }; 208 209 /* per request cache information */ 210 typedef struct { 211 cache_provider_list *providers; /* possible cache providers */ 212 const cache_provider *provider; /* current cache provider */ 213 const char *provider_name; /* current cache provider name */ 214 int fresh; /* is the entity fresh? */ 215 cache_handle_t *handle; /* current cache handle */ 216 cache_handle_t *stale_handle; /* stale cache handle */ 217 apr_table_t *stale_headers; /* original request headers. */ 218 int in_checked; /* CACHE_SAVE must cache the entity */ 219 int block_response; /* CACHE_SAVE must block response. */ 220 apr_bucket_brigade *saved_brigade; /* copy of partial response */ 221 apr_off_t saved_size; /* length of saved_brigade */ 222 apr_time_t exp; /* expiration */ 223 apr_time_t lastmod; /* last-modified time */ 224 cache_info *info; /* current cache info */ 225 ap_filter_t *save_filter; /* Enable us to restore the filter on error */ 226 ap_filter_t *remove_url_filter; /* Enable us to remove the filter */ 227 const char *key; /* The cache key created for this 228 * request 229 */ 230 apr_off_t size; /* the content length from the headers, or -1 */ 231 apr_bucket_brigade *out; /* brigade to reuse for upstream responses */ 232 cache_control_t control_in; /* cache control incoming */ 233 } cache_request_rec; 234 235 /** 236 * Check the whether the request allows a cached object to be served as per RFC2616 237 * section 14.9.4 (Cache Revalidation and Reload Controls) 238 * @param cache cache_request_rec 239 * @param r request_rec 240 * @return 0 ==> cache object may not be served, 1 ==> cache object may be served 241 */ 242 int ap_cache_check_no_cache(cache_request_rec *cache, request_rec *r); 243 244 /** 245 * Check the whether the request allows a cached object to be stored as per RFC2616 246 * section 14.9.2 (What May be Stored by Caches) 247 * @param cache cache_request_rec 248 * @param r request_rec 249 * @return 0 ==> cache object may not be served, 1 ==> cache object may be served 250 */ 251 int ap_cache_check_no_store(cache_request_rec *cache, request_rec *r); 252 253 /** 254 * Check the freshness of the cache object per RFC2616 section 13.2 (Expiration Model) 255 * @param h cache_handle_t 256 * @param cache cache_request_rec 257 * @param r request_rec 258 * @return 0 ==> cache object is stale, 1 ==> cache object is fresh 259 */ 260 int cache_check_freshness(cache_handle_t *h, cache_request_rec *cache, 261 request_rec *r); 262 263 /** 264 * Try obtain a cache wide lock on the given cache key. 265 * 266 * If we return APR_SUCCESS, we obtained the lock, and we are clear to 267 * proceed to the backend. If we return APR_EEXISTS, the the lock is 268 * already locked, someone else has gone to refresh the backend data 269 * already, so we must return stale data with a warning in the mean 270 * time. If we return anything else, then something has gone pear 271 * shaped, and we allow the request through to the backend regardless. 272 * 273 * This lock is created from the request pool, meaning that should 274 * something go wrong and the lock isn't deleted on return of the 275 * request headers from the backend for whatever reason, at worst the 276 * lock will be cleaned up when the request is dies or finishes. 277 * 278 * If something goes truly bananas and the lock isn't deleted when the 279 * request dies, the lock will be trashed when its max-age is reached, 280 * or when a request arrives containing a Cache-Control: no-cache. At 281 * no point is it possible for this lock to permanently deny access to 282 * the backend. 283 */ 284 apr_status_t cache_try_lock(cache_server_conf *conf, cache_request_rec *cache, 285 request_rec *r); 286 287 /** 288 * Remove the cache lock, if present. 289 * 290 * First, try to close the file handle, whose delete-on-close should 291 * kill the file. Otherwise, just delete the file by name. 292 * 293 * If no lock name has yet been calculated, do the calculation of the 294 * lock name first before trying to delete the file. 295 * 296 * If an optional bucket brigade is passed, the lock will only be 297 * removed if the bucket brigade contains an EOS bucket. 298 */ 299 apr_status_t cache_remove_lock(cache_server_conf *conf, 300 cache_request_rec *cache, request_rec *r, apr_bucket_brigade *bb); 301 302 cache_provider_list *cache_get_providers(request_rec *r, 303 cache_server_conf *conf, apr_uri_t uri); 304 305 /** 306 * Get a value from a table, where the table may contain multiple 307 * values for a given key. 308 * 309 * When the table contains a single value, that value is returned 310 * unchanged. 311 * 312 * When the table contains two or more values for a key, all values 313 * for the key are returned, separated by commas. 314 */ 315 const char *cache_table_getm(apr_pool_t *p, const apr_table_t *t, 316 const char *key); 317 318 /** 319 * String tokenizer that ignores separator characters within quoted strings 320 * and escaped characters, as per RFC2616 section 2.2. 321 */ 322 char *cache_strqtok(char *str, const char *sep, char **last); 323 324 #ifdef __cplusplus 325 } 326 #endif 327 328 #endif /* !CACHE_UTIL_H */ 329 /** @} */ 330