Page Speed Optimization Libraries  1.11.33.2
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Pages
http_cache.h
Go to the documentation of this file.
1 /*
2  * Copyright 2010 Google Inc.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * 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 
18 
19 #ifndef NET_INSTAWEB_HTTP_PUBLIC_HTTP_CACHE_H_
20 #define NET_INSTAWEB_HTTP_PUBLIC_HTTP_CACHE_H_
21 
22 #include "base/logging.h"
25 #include "net/instaweb/http/public/request_context.h"
26 #include "pagespeed/kernel/base/atomic_bool.h"
27 #include "pagespeed/kernel/base/basictypes.h"
28 #include "pagespeed/kernel/base/gtest_prod.h"
29 #include "pagespeed/kernel/base/ref_counted_ptr.h"
30 #include "pagespeed/kernel/base/string.h"
31 #include "pagespeed/kernel/base/string_util.h"
32 #include "pagespeed/kernel/cache/cache_interface.h"
33 #include "pagespeed/kernel/http/http_names.h"
34 #include "pagespeed/kernel/http/http_options.h"
35 #include "pagespeed/kernel/http/request_headers.h"
36 #include "pagespeed/kernel/http/response_headers.h"
37 
38 namespace net_instaweb {
39 
40 class Hasher;
41 class MessageHandler;
42 class Statistics;
43 class Timer;
44 class Variable;
45 
48 class HTTPCache {
49  public:
51  static const char kCacheTimeUs[];
52  static const char kCacheHits[];
53  static const char kCacheMisses[];
54  static const char kCacheBackendHits[];
55  static const char kCacheBackendMisses[];
56  static const char kCacheFallbacks[];
57  static const char kCacheExpirations[];
58  static const char kCacheInserts[];
59  static const char kCacheDeletes[];
60 
62  static const char kEtagPrefix[];
63 
65  static GoogleString FormatEtag(StringPiece hash);
66 
68  HTTPCache(CacheInterface* cache, Timer* timer, Hasher* hasher,
69  Statistics* stats);
70  ~HTTPCache();
71 
72  enum FindResultClassification {
73  kFound,
74  kNotFound,
75  kRecentFailure,
76  };
77 
79  struct FindResult {
80  FindResult()
81  : status(kNotFound), failure_details(kFetchStatusNotSet) {}
82 
83  FindResult(FindResultClassification in_status,
84  FetchResponseStatus in_failure_details)
85  : status(in_status), failure_details(in_failure_details) {}
86 
87  bool operator==(const FindResult& other) const {
88  return status == other.status &&
90  }
91 
92  bool operator!=(const FindResult& other) const {
93  return !(*this == other);
94  }
95 
96  FindResultClassification status;
97 
104  };
105 
106  void set_hasher(Hasher* hasher) { hasher_ = hasher; }
107 
113  class Callback {
114  public:
122  explicit Callback(const RequestContextPtr& request_ctx)
123  : response_headers_(NULL),
124  owns_response_headers_(false),
125  request_ctx_(request_ctx),
126  cache_level_(0),
127  is_background_(false) {
128  }
129 
132  Callback(const RequestContextPtr& request_ctx,
133  RequestHeaders::Properties req_properties)
134  : response_headers_(NULL),
135  req_properties_(req_properties),
136  owns_response_headers_(false),
137  request_ctx_(request_ctx),
138  cache_level_(0),
139  is_background_(false) {
140  }
141 
142  virtual ~Callback();
143  virtual void Done(FindResult find_result) = 0;
153  virtual bool IsCacheValid(const GoogleString& key,
154  const ResponseHeaders& headers) {
155  return true;
156  }
157 
165  virtual bool IsFresh(const ResponseHeaders& headers) { return true; }
166 
170  virtual int64 OverrideCacheTtlMs(const GoogleString& key) { return -1; }
171 
177  void ReportLatencyMs(int64 latency_ms);
178 
187  virtual ResponseHeaders::VaryOption RespectVaryOnResources() const = 0;
188 
191  HTTPValue* http_value() { return &http_value_; }
192  ResponseHeaders* response_headers() {
193  if (response_headers_ == NULL) {
194  response_headers_ = new ResponseHeaders(request_ctx_->options());
195  owns_response_headers_ = true;
196  }
197  return response_headers_;
198  }
199  const ResponseHeaders* response_headers() const {
200  return const_cast<Callback*>(this)->response_headers();
201  }
202  void set_response_headers(ResponseHeaders* headers) {
203  DCHECK(!owns_response_headers_);
204  if (owns_response_headers_) {
205  delete response_headers_;
206  }
207  response_headers_ = headers;
208  owns_response_headers_ = false;
209  }
210  HTTPValue* fallback_http_value() { return &fallback_http_value_; }
211 
212  const RequestContextPtr& request_context() { return request_ctx_; }
213  void set_is_background(bool is_background) {
214  is_background_ = is_background;
215  }
216 
217  RequestHeaders::Properties req_properties() const {
218  return req_properties_;
219  }
220 
221  private:
222  HTTPValue http_value_;
225  HTTPValue fallback_http_value_;
226  ResponseHeaders* response_headers_;
227  RequestHeaders::Properties req_properties_;
228  bool owns_response_headers_;
229  RequestContextPtr request_ctx_;
230  int cache_level_;
231  bool is_background_;
232 
233 
234  };
235 
237  void SetIgnoreFailurePuts();
238 
241  void Find(const GoogleString& key,
242  const GoogleString& fragment,
243  MessageHandler* handler,
244  Callback* callback);
245 
248  void Put(const GoogleString& key,
249  const GoogleString& fragment,
250  RequestHeaders::Properties req_properties,
251  const HttpOptions& http_options,
252  HTTPValue* value,
253  MessageHandler* handler);
254 
259  void Put(const GoogleString& key,
260  const GoogleString& fragment,
261  RequestHeaders::Properties req_properties,
263  ResponseHeaders::VaryOption respect_vary_on_resources,
264  ResponseHeaders* headers,
265  const StringPiece& content, MessageHandler* handler);
266 
268  void Delete(const GoogleString& key, const GoogleString& fragment);
269 
270  void set_force_caching(bool force) { force_caching_ = force; }
271  bool force_caching() const { return force_caching_; }
272  void set_disable_html_caching_on_https(bool x) {
273  disable_html_caching_on_https_ = x;
274  }
275  Timer* timer() const { return timer_; }
276  CacheInterface* cache() { return cache_; }
277 
282  void RememberFailure(const GoogleString& key,
283  const GoogleString& fragment,
284  FetchResponseStatus the_failure,
285  MessageHandler* handler);
286 
291  bool IsCacheableContentLength(ResponseHeaders* headers) const;
296  bool IsCacheableBodySize(int64 body_size) const;
297 
299  static void InitStats(Statistics* statistics);
300 
308  bool IsExpired(const ResponseHeaders& headers);
309  bool IsExpired(const ResponseHeaders& headers, int64 now_ms);
310 
312  Variable* cache_time_us() { return cache_time_us_; }
313  Variable* cache_hits() { return cache_hits_; }
314  Variable* cache_misses() { return cache_misses_; }
315  Variable* cache_fallbacks() { return cache_fallbacks_; }
316  Variable* cache_expirations() { return cache_expirations_; }
317  Variable* cache_inserts() { return cache_inserts_; }
318  Variable* cache_deletes() { return cache_deletes_; }
319 
320  int failure_caching_ttl_sec(FetchResponseStatus kind) const {
321  return remember_failure_policy_.ttl_sec_for_status[kind];
322  }
323 
324  void set_failure_caching_ttl_sec(FetchResponseStatus kind, int ttl_sec) {
325  remember_failure_policy_.ttl_sec_for_status[kind] = ttl_sec;
326  }
327 
328  int max_cacheable_response_content_length() {
329  return max_cacheable_response_content_length_;
330  }
331 
332  void set_max_cacheable_response_content_length(int64 value);
333 
336  void set_cache_levels(int levels) { cache_levels_ = levels; }
337  int cache_levels() const { return cache_levels_; }
338 
341  void SetCompressionLevel(int level) {
342  if (level >= -1 && level <= 9) {
343  compression_level_ = level;
344  } else {
345  LOG(INFO) << "Invalid compression level specified, defaulting to -1";
346  compression_level_ = -1;
347  }
348  }
349  int compression_level() const { return compression_level_; }
350 
351  GoogleString Name() const { return FormatName(cache_->Name()); }
352  static GoogleString FormatName(StringPiece cache);
353 
354  GoogleString CompositeKey(StringPiece key, StringPiece fragment) const {
355  DCHECK(fragment.find("/") == StringPiece::npos);
356 
359  return StrCat(version_prefix_, fragment, fragment.empty() ? "" : "/", key);
360  }
361 
362  private:
363  friend class HTTPCacheCallback;
364  FRIEND_TEST(HTTPCacheTest, UpdateVersion);
365 
368  void PutInternal(bool preserve_response_headers,
369  const GoogleString& key,
370  const GoogleString& fragment,
371  int64 start_us,
372  HTTPValue* value,
373  ResponseHeaders* headers,
374  MessageHandler* handler);
375  void DeleteInternal(const GoogleString& key_fragment);
376 
378  void SetVersion(int version_number);
379  void set_version_prefix(StringPiece version_prefix) {
380  version_prefix.CopyToString(&version_prefix_);
381  }
382 
383  bool MayCacheUrl(const GoogleString& url, const ResponseHeaders& headers);
388  HTTPValue* ApplyHeaderChangesForPut(
389  int64 start_us, const StringPiece* content, ResponseHeaders* headers,
390  HTTPValue* value, MessageHandler* handler);
391  void UpdateStats(const GoogleString& key, const GoogleString& fragment,
392  CacheInterface::KeyState backend_state, FindResult result,
393  bool has_fallback, bool is_expired, MessageHandler* handler);
394  void RememberFetchFailedOrNotCacheableHelper(
395  const GoogleString& key, const GoogleString& fragment,
396  MessageHandler* handler, HttpStatus::Code code, int64 ttl_sec);
397 
398  CacheInterface* cache_;
399  Timer* timer_;
400  Hasher* hasher_;
401  bool force_caching_;
403  bool disable_html_caching_on_https_;
404 
405  int cache_levels_;
406  int compression_level_;
407 
409  Variable* cache_time_us_;
411  Variable* cache_hits_;
413  Variable* cache_misses_;
416  Variable* cache_backend_hits_;
418  Variable* cache_backend_misses_;
419  Variable* cache_fallbacks_;
420  Variable* cache_expirations_;
421  Variable* cache_inserts_;
422  Variable* cache_deletes_;
423 
424  GoogleString name_;
425  HttpCacheFailurePolicy remember_failure_policy_;
426  int64 max_cacheable_response_content_length_;
427  AtomicBool ignore_failure_puts_;
428 
429  GoogleString version_prefix_;
430 
431 
432 };
433 
434 }
435 
436 #endif
Callback(const RequestContextPtr &request_ctx, RequestHeaders::Properties req_properties)
Definition: http_cache.h:132
Callback(const RequestContextPtr &request_ctx)
Definition: http_cache.h:122
virtual bool IsFresh(const ResponseHeaders &headers)
Definition: http_cache.h:165
When a lookup is done in the HTTP Cache, it returns one of these values.
Definition: http_cache.h:79
Definition: http_value.h:38
static const char kEtagPrefix[]
The prefix used for Etags.
Definition: http_cache.h:62
void SetCompressionLevel(int level)
Definition: http_cache.h:341
void RememberFailure(const GoogleString &key, const GoogleString &fragment, FetchResponseStatus the_failure, MessageHandler *handler)
Variable * cache_time_us()
Stats for the HTTP cache.
Definition: http_cache.h:312
GoogleString CompositeKey(StringPiece key, StringPiece fragment) const
Definition: http_cache.h:354
FetchResponseStatus failure_details
Definition: http_cache.h:103
void SetIgnoreFailurePuts()
Makes the cache ignore put requests that do not record successes.
void Find(const GoogleString &key, const GoogleString &fragment, MessageHandler *handler, Callback *callback)
static const char kCacheTimeUs[]
Names of statistics variables: exported for tests.
Definition: http_cache.h:51
bool IsCacheableBodySize(int64 body_size) const
bool IsExpired(const ResponseHeaders &headers)
int ttl_sec_for_status[8]
Definition: http_cache_failure.h:51
void Delete(const GoogleString &key, const GoogleString &fragment)
Deletes an element in the cache.
virtual bool IsCacheValid(const GoogleString &key, const ResponseHeaders &headers)
Definition: http_cache.h:153
static void InitStats(Statistics *statistics)
Initialize statistics variables for the cache.
bool IsCacheableContentLength(ResponseHeaders *headers) const
void ReportLatencyMs(int64 latency_ms)
void Put(const GoogleString &key, const GoogleString &fragment, RequestHeaders::Properties req_properties, const HttpOptions &http_options, HTTPValue *value, MessageHandler *handler)
HTTPValue * http_value()
Definition: http_cache.h:191
HTTPCache(CacheInterface *cache, Timer *timer, Hasher *hasher, Statistics *stats)
Does not take ownership of any inputs.
Definition: http_cache.h:113
FetchResponseStatus
Definition: http_cache_failure.h:33
virtual int64 OverrideCacheTtlMs(const GoogleString &key)
Definition: http_cache.h:170
void set_cache_levels(int levels)
Definition: http_cache.h:336
virtual ResponseHeaders::VaryOption RespectVaryOnResources() const =0
Definition: http_cache.h:48
static GoogleString FormatEtag(StringPiece hash)
Function to format etags.