Page Speed Optimization Libraries
1.8.31.3
|
00001 /* 00002 * Copyright 2010 Google Inc. 00003 * 00004 * Licensed under the Apache License, Version 2.0 (the "License"); 00005 * you may not use this file except in compliance with the License. 00006 * You may obtain a copy of the License at 00007 * 00008 * http:///www.apache.org/licenses/LICENSE-2.0 00009 * 00010 * Unless required by applicable law or agreed to in writing, software 00011 * distributed under the License is distributed on an "AS IS" BASIS, 00012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 00013 * See the License for the specific language governing permissions and 00014 * limitations under the License. 00015 */ 00016 00018 00019 #ifndef NET_INSTAWEB_HTTP_PUBLIC_HTTP_CACHE_H_ 00020 #define NET_INSTAWEB_HTTP_PUBLIC_HTTP_CACHE_H_ 00021 00022 #include "base/logging.h" 00023 #include "net/instaweb/http/public/http_value.h" 00024 #include "net/instaweb/http/public/meta_data.h" 00025 #include "net/instaweb/http/public/request_context.h" 00026 #include "net/instaweb/http/public/response_headers.h" 00027 #include "net/instaweb/util/public/atomic_bool.h" 00028 #include "net/instaweb/util/public/basictypes.h" 00029 #include "net/instaweb/util/public/cache_interface.h" 00030 #include "net/instaweb/util/public/string_util.h" 00031 #include "net/instaweb/util/public/string.h" 00032 #include "pagespeed/kernel/http/request_headers.h" 00033 00034 namespace net_instaweb { 00035 00036 class Hasher; 00037 class MessageHandler; 00038 class Statistics; 00039 class Timer; 00040 class UpDownCounter; 00041 class Variable; 00042 00045 class HTTPCache { 00046 public: 00048 static const char kCacheTimeUs[]; 00049 static const char kCacheHits[]; 00050 static const char kCacheMisses[]; 00051 static const char kCacheBackendHits[]; 00052 static const char kCacheBackendMisses[]; 00053 static const char kCacheFallbacks[]; 00054 static const char kCacheExpirations[]; 00055 static const char kCacheInserts[]; 00056 static const char kCacheDeletes[]; 00057 00059 static const char kEtagPrefix[]; 00060 00062 static GoogleString FormatEtag(StringPiece hash); 00063 00065 HTTPCache(CacheInterface* cache, Timer* timer, Hasher* hasher, 00066 Statistics* stats); 00067 virtual ~HTTPCache(); 00068 00070 enum FindResult { 00071 kFound, 00072 kNotFound, 00075 kRecentFetchFailed, 00076 kRecentFetchNotCacheable, 00077 }; 00078 00079 virtual void set_hasher(Hasher* hasher) { hasher_ = hasher; } 00080 00086 class Callback { 00087 public: 00095 explicit Callback(const RequestContextPtr& request_ctx) 00096 : response_headers_(NULL), 00097 owns_response_headers_(false), 00098 request_ctx_(request_ctx), 00099 is_background_(false) { 00100 } 00101 00104 Callback(const RequestContextPtr& request_ctx, 00105 RequestHeaders::Properties req_properties) 00106 : response_headers_(NULL), 00107 req_properties_(req_properties), 00108 owns_response_headers_(false), 00109 request_ctx_(request_ctx), 00110 is_background_(false) { 00111 } 00112 00113 virtual ~Callback(); 00114 virtual void Done(FindResult find_result) = 0; 00124 virtual bool IsCacheValid(const GoogleString& key, 00125 const ResponseHeaders& headers) { 00126 return true; 00127 } 00128 00136 virtual bool IsFresh(const ResponseHeaders& headers) { return true; } 00137 00141 virtual int64 OverrideCacheTtlMs(const GoogleString& key) { return -1; } 00142 00148 void ReportLatencyMs(int64 latency_ms); 00149 00158 virtual ResponseHeaders::VaryOption RespectVaryOnResources() const = 0; 00159 00162 HTTPValue* http_value() { return &http_value_; } 00163 ResponseHeaders* response_headers() { 00164 if (response_headers_ == NULL) { 00165 response_headers_ = new ResponseHeaders; 00166 owns_response_headers_ = true; 00167 } 00168 return response_headers_; 00169 } 00170 const ResponseHeaders* response_headers() const { 00171 return const_cast<Callback*>(this)->response_headers(); 00172 } 00173 void set_response_headers(ResponseHeaders* headers) { 00174 DCHECK(!owns_response_headers_); 00175 if (owns_response_headers_) { 00176 delete response_headers_; 00177 } 00178 response_headers_ = headers; 00179 owns_response_headers_ = false; 00180 } 00181 HTTPValue* fallback_http_value() { return &fallback_http_value_; } 00182 00183 const RequestContextPtr& request_context() { return request_ctx_; } 00184 void set_is_background(bool is_background) { 00185 is_background_ = is_background; 00186 } 00187 00188 RequestHeaders::Properties req_properties() const { 00189 return req_properties_; 00190 } 00191 00192 protected: 00195 virtual void ReportLatencyMsImpl(int64 latency_ms); 00196 00197 private: 00198 HTTPValue http_value_; 00201 HTTPValue fallback_http_value_; 00202 ResponseHeaders* response_headers_; 00203 RequestHeaders::Properties req_properties_; 00204 bool owns_response_headers_; 00205 RequestContextPtr request_ctx_; 00206 bool is_background_; 00207 00208 DISALLOW_COPY_AND_ASSIGN(Callback); 00209 }; 00210 00212 virtual void SetIgnoreFailurePuts(); 00213 00216 virtual void Find(const GoogleString& key, 00217 const GoogleString& fragment, 00218 MessageHandler* handler, 00219 Callback* callback); 00220 00223 void Put(const GoogleString& key, 00224 const GoogleString& fragment, 00225 RequestHeaders::Properties req_properties, 00226 ResponseHeaders::VaryOption respect_vary_on_resources, 00227 HTTPValue* value, 00228 MessageHandler* handler); 00229 00234 void Put(const GoogleString& key, 00235 const GoogleString& fragment, 00236 RequestHeaders::Properties req_properties, 00237 ResponseHeaders::VaryOption respect_vary_on_resources, 00238 ResponseHeaders* headers, 00239 const StringPiece& content, MessageHandler* handler); 00240 00242 virtual void Delete(const GoogleString& key, const GoogleString& fragment); 00243 00244 virtual void set_force_caching(bool force) { force_caching_ = force; } 00245 bool force_caching() const { return force_caching_; } 00246 virtual void set_disable_html_caching_on_https(bool x) { 00247 disable_html_caching_on_https_ = x; 00248 } 00249 Timer* timer() const { return timer_; } 00250 00259 virtual void RememberNotCacheable(const GoogleString& key, 00260 const GoogleString& fragment, 00261 bool is_200_status_code, 00262 MessageHandler* handler); 00263 00269 virtual void RememberFetchFailed(const GoogleString& key, 00270 const GoogleString& fragment, 00271 MessageHandler* handler); 00272 00276 virtual void RememberFetchDropped(const GoogleString& key, 00277 const GoogleString& fragment, 00278 MessageHandler* handler); 00279 00284 bool IsCacheableContentLength(ResponseHeaders* headers) const; 00289 bool IsCacheableBodySize(int64 body_size) const; 00290 00292 static void InitStats(Statistics* statistics); 00293 00301 bool IsExpired(const ResponseHeaders& headers); 00302 bool IsExpired(const ResponseHeaders& headers, int64 now_ms); 00303 00311 Variable* cache_time_us() { return cache_time_us_; } 00312 Variable* cache_hits() { return cache_hits_; } 00313 UpDownCounter* cache_misses() { return cache_misses_; } 00314 UpDownCounter* cache_fallbacks() { return cache_fallbacks_; } 00315 Variable* cache_expirations() { return cache_expirations_; } 00316 UpDownCounter* cache_inserts() { return cache_inserts_; } 00317 UpDownCounter* cache_deletes() { return cache_deletes_; } 00318 00319 int64 remember_not_cacheable_ttl_seconds() { 00320 return remember_not_cacheable_ttl_seconds_; 00321 } 00322 00323 virtual void set_remember_not_cacheable_ttl_seconds(int64 value) { 00324 DCHECK_LE(0, value); 00325 if (value >= 0) { 00326 remember_not_cacheable_ttl_seconds_ = value; 00327 } 00328 } 00329 00330 int64 remember_fetch_failed_ttl_seconds() { 00331 return remember_fetch_failed_ttl_seconds_; 00332 } 00333 00334 virtual void set_remember_fetch_failed_ttl_seconds(int64 value) { 00335 DCHECK_LE(0, value); 00336 if (value >= 0) { 00337 remember_fetch_failed_ttl_seconds_ = value; 00338 } 00339 } 00340 00341 int64 remember_fetch_dropped_ttl_seconds() { 00342 return remember_fetch_dropped_ttl_seconds_; 00343 } 00344 00345 virtual void set_remember_fetch_dropped_ttl_seconds(int64 value) { 00346 DCHECK_LE(0, value); 00347 if (value >= 0) { 00348 remember_fetch_dropped_ttl_seconds_ = value; 00349 } 00350 } 00351 00352 int max_cacheable_response_content_length() { 00353 return max_cacheable_response_content_length_; 00354 } 00355 00356 virtual void set_max_cacheable_response_content_length(int64 value); 00357 00358 virtual GoogleString Name() const { return FormatName(cache_->Name()); } 00359 static GoogleString FormatName(StringPiece cache); 00360 00361 static GoogleString CompositeKey(StringPiece key, StringPiece fragment) { 00362 DCHECK(fragment.find("/") == StringPiece::npos); 00363 00365 return StrCat(fragment, fragment.empty() ? "" : "/", key); 00366 } 00367 00368 protected: 00369 virtual void PutInternal(const GoogleString& key, 00370 const GoogleString& fragment, 00371 int64 start_us, 00372 HTTPValue* value); 00373 00374 private: 00375 friend class HTTPCacheCallback; 00376 friend class WriteThroughHTTPCache; 00377 00378 bool MayCacheUrl(const GoogleString& url, const ResponseHeaders& headers); 00383 HTTPValue* ApplyHeaderChangesForPut( 00384 int64 start_us, const StringPiece* content, ResponseHeaders* headers, 00385 HTTPValue* value, MessageHandler* handler); 00386 void UpdateStats(const GoogleString& key, const GoogleString& fragment, 00387 CacheInterface::KeyState backend_state, FindResult result, 00388 bool has_fallback, bool is_expired, int64 delta_us, 00389 MessageHandler* handler); 00390 void RememberFetchFailedorNotCacheableHelper( 00391 const GoogleString& key, const GoogleString& fragment, 00392 MessageHandler* handler, HttpStatus::Code code, int64 ttl_sec); 00393 00394 CacheInterface* cache_; 00395 Timer* timer_; 00396 Hasher* hasher_; 00397 bool force_caching_; 00399 bool disable_html_caching_on_https_; 00400 00402 Variable* cache_time_us_; 00404 Variable* cache_hits_; 00406 UpDownCounter* cache_misses_; 00409 Variable* cache_backend_hits_; 00411 Variable* cache_backend_misses_; 00412 UpDownCounter* cache_fallbacks_; 00413 Variable* cache_expirations_; 00414 UpDownCounter* cache_inserts_; 00415 UpDownCounter* cache_deletes_; 00416 00417 GoogleString name_; 00418 int64 remember_not_cacheable_ttl_seconds_; 00419 int64 remember_fetch_failed_ttl_seconds_; 00420 int64 remember_fetch_dropped_ttl_seconds_; 00421 int64 max_cacheable_response_content_length_; 00422 AtomicBool ignore_failure_puts_; 00423 00424 DISALLOW_COPY_AND_ASSIGN(HTTPCache); 00425 }; 00426 00427 } 00428 00429 #endif ///< NET_INSTAWEB_HTTP_PUBLIC_HTTP_CACHE_H_