19 #ifndef NET_INSTAWEB_HTTP_PUBLIC_HTTP_CACHE_H_
20 #define NET_INSTAWEB_HTTP_PUBLIC_HTTP_CACHE_H_
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"
38 namespace net_instaweb {
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[];
65 static GoogleString
FormatEtag(StringPiece hash);
68 HTTPCache(CacheInterface* cache, Timer* timer, Hasher* hasher,
72 enum FindResultClassification {
87 bool operator==(
const FindResult& other)
const {
88 return status == other.status &&
92 bool operator!=(
const FindResult& other)
const {
93 return !(*
this == other);
96 FindResultClassification status;
106 void set_hasher(Hasher* hasher) { hasher_ = hasher; }
122 explicit Callback(
const RequestContextPtr& request_ctx)
123 : response_headers_(NULL),
124 owns_response_headers_(false),
125 request_ctx_(request_ctx),
127 is_background_(false) {
133 RequestHeaders::Properties req_properties)
134 : response_headers_(NULL),
135 req_properties_(req_properties),
136 owns_response_headers_(false),
137 request_ctx_(request_ctx),
139 is_background_(false) {
143 virtual void Done(
FindResult find_result) = 0;
154 const ResponseHeaders& headers) {
165 virtual bool IsFresh(
const ResponseHeaders& headers) {
return true; }
192 ResponseHeaders* response_headers() {
193 if (response_headers_ == NULL) {
194 response_headers_ =
new ResponseHeaders(request_ctx_->options());
195 owns_response_headers_ =
true;
197 return response_headers_;
199 const ResponseHeaders* response_headers()
const {
200 return const_cast<Callback*
>(
this)->response_headers();
202 void set_response_headers(ResponseHeaders* headers) {
203 DCHECK(!owns_response_headers_);
204 if (owns_response_headers_) {
205 delete response_headers_;
207 response_headers_ = headers;
208 owns_response_headers_ =
false;
210 HTTPValue* fallback_http_value() {
return &fallback_http_value_; }
212 const RequestContextPtr& request_context() {
return request_ctx_; }
213 void set_is_background(
bool is_background) {
214 is_background_ = is_background;
217 RequestHeaders::Properties req_properties()
const {
218 return req_properties_;
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_;
241 void Find(
const GoogleString& key,
242 const GoogleString& fragment,
243 MessageHandler* handler,
248 void Put(
const GoogleString& key,
249 const GoogleString& fragment,
250 RequestHeaders::Properties req_properties,
251 const HttpOptions& http_options,
253 MessageHandler* handler);
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);
268 void Delete(
const GoogleString& key,
const GoogleString& fragment);
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;
275 Timer* timer()
const {
return timer_; }
276 CacheInterface* cache() {
return cache_; }
283 const GoogleString& fragment,
285 MessageHandler* handler);
299 static void InitStats(Statistics* statistics);
308 bool IsExpired(
const ResponseHeaders& headers);
309 bool IsExpired(
const ResponseHeaders& headers, int64 now_ms);
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_; }
328 int max_cacheable_response_content_length() {
329 return max_cacheable_response_content_length_;
332 void set_max_cacheable_response_content_length(int64 value);
337 int cache_levels()
const {
return cache_levels_; }
342 if (level >= -1 && level <= 9) {
343 compression_level_ = level;
345 LOG(INFO) <<
"Invalid compression level specified, defaulting to -1";
346 compression_level_ = -1;
349 int compression_level()
const {
return compression_level_; }
351 GoogleString Name()
const {
return FormatName(cache_->Name()); }
352 static GoogleString FormatName(StringPiece cache);
354 GoogleString
CompositeKey(StringPiece key, StringPiece fragment)
const {
355 DCHECK(fragment.find(
"/") == StringPiece::npos);
359 return StrCat(version_prefix_, fragment, fragment.empty() ?
"" :
"/", key);
363 friend class HTTPCacheCallback;
364 FRIEND_TEST(HTTPCacheTest, UpdateVersion);
368 void PutInternal(
bool preserve_response_headers,
369 const GoogleString& key,
370 const GoogleString& fragment,
373 ResponseHeaders* headers,
374 MessageHandler* handler);
375 void DeleteInternal(
const GoogleString& key_fragment);
378 void SetVersion(
int version_number);
379 void set_version_prefix(StringPiece version_prefix) {
380 version_prefix.CopyToString(&version_prefix_);
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);
398 CacheInterface* cache_;
403 bool disable_html_caching_on_https_;
406 int compression_level_;
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_;
425 HttpCacheFailurePolicy remember_failure_policy_;
426 int64 max_cacheable_response_content_length_;
427 AtomicBool ignore_failure_puts_;
429 GoogleString version_prefix_;
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.