Page Speed Optimization Libraries
1.7.30.4
|
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 Variable; 00041 00044 class HTTPCache { 00045 public: 00047 static const char kCacheTimeUs[]; 00048 static const char kCacheHits[]; 00049 static const char kCacheMisses[]; 00050 static const char kCacheBackendHits[]; 00051 static const char kCacheBackendMisses[]; 00052 static const char kCacheFallbacks[]; 00053 static const char kCacheExpirations[]; 00054 static const char kCacheInserts[]; 00055 static const char kCacheDeletes[]; 00056 00058 static const char kEtagPrefix[]; 00059 00061 static GoogleString FormatEtag(StringPiece hash); 00062 00064 HTTPCache(CacheInterface* cache, Timer* timer, Hasher* hasher, 00065 Statistics* stats); 00066 virtual ~HTTPCache(); 00067 00069 enum FindResult { 00070 kFound, 00071 kNotFound, 00074 kRecentFetchFailed, 00075 kRecentFetchNotCacheable, 00076 }; 00077 00078 virtual void set_hasher(Hasher* hasher) { hasher_ = hasher; } 00079 00085 class Callback { 00086 public: 00094 explicit Callback(const RequestContextPtr& request_ctx) 00095 : response_headers_(NULL), 00096 owns_response_headers_(false), 00097 request_ctx_(request_ctx), 00098 is_background_(false) { 00099 } 00100 00103 Callback(const RequestContextPtr& request_ctx, 00104 RequestHeaders::Properties req_properties) 00105 : response_headers_(NULL), 00106 req_properties_(req_properties), 00107 owns_response_headers_(false), 00108 request_ctx_(request_ctx), 00109 is_background_(false) { 00110 } 00111 00112 virtual ~Callback(); 00113 virtual void Done(FindResult find_result) = 0; 00123 virtual bool IsCacheValid(const GoogleString& key, 00124 const ResponseHeaders& headers) { 00125 return true; 00126 } 00127 00135 virtual bool IsFresh(const ResponseHeaders& headers) { return true; } 00136 00140 virtual int64 OverrideCacheTtlMs(const GoogleString& key) { return -1; } 00141 00147 void ReportLatencyMs(int64 latency_ms); 00148 00157 virtual ResponseHeaders::VaryOption RespectVaryOnResources() const = 0; 00158 00161 HTTPValue* http_value() { return &http_value_; } 00162 ResponseHeaders* response_headers() { 00163 if (response_headers_ == NULL) { 00164 response_headers_ = new ResponseHeaders; 00165 owns_response_headers_ = true; 00166 } 00167 return response_headers_; 00168 } 00169 const ResponseHeaders* response_headers() const { 00170 return const_cast<Callback*>(this)->response_headers(); 00171 } 00172 void set_response_headers(ResponseHeaders* headers) { 00173 DCHECK(!owns_response_headers_); 00174 if (owns_response_headers_) { 00175 delete response_headers_; 00176 } 00177 response_headers_ = headers; 00178 owns_response_headers_ = false; 00179 } 00180 HTTPValue* fallback_http_value() { return &fallback_http_value_; } 00181 00182 const RequestContextPtr& request_context() { return request_ctx_; } 00183 void set_is_background(bool is_background) { 00184 is_background_ = is_background; 00185 } 00186 00187 RequestHeaders::Properties req_properties() const { 00188 return req_properties_; 00189 } 00190 00191 protected: 00194 virtual void ReportLatencyMsImpl(int64 latency_ms); 00195 00196 private: 00197 HTTPValue http_value_; 00200 HTTPValue fallback_http_value_; 00201 ResponseHeaders* response_headers_; 00202 RequestHeaders::Properties req_properties_; 00203 bool owns_response_headers_; 00204 RequestContextPtr request_ctx_; 00205 bool is_background_; 00206 00207 DISALLOW_COPY_AND_ASSIGN(Callback); 00208 }; 00209 00211 virtual void SetIgnoreFailurePuts(); 00212 00215 virtual void Find(const GoogleString& key, 00216 const GoogleString& fragment, 00217 MessageHandler* handler, 00218 Callback* callback); 00219 00222 void Put(const GoogleString& key, 00223 const GoogleString& fragment, 00224 RequestHeaders::Properties req_properties, 00225 ResponseHeaders::VaryOption respect_vary_on_resources, 00226 HTTPValue* value, 00227 MessageHandler* handler); 00228 00233 void Put(const GoogleString& key, 00234 const GoogleString& fragment, 00235 RequestHeaders::Properties req_properties, 00236 ResponseHeaders::VaryOption respect_vary_on_resources, 00237 ResponseHeaders* headers, 00238 const StringPiece& content, MessageHandler* handler); 00239 00241 virtual void Delete(const GoogleString& key, const GoogleString& fragment); 00242 00243 virtual void set_force_caching(bool force) { force_caching_ = force; } 00244 bool force_caching() const { return force_caching_; } 00245 virtual void set_disable_html_caching_on_https(bool x) { 00246 disable_html_caching_on_https_ = x; 00247 } 00248 Timer* timer() const { return timer_; } 00249 00258 virtual void RememberNotCacheable(const GoogleString& key, 00259 const GoogleString& fragment, 00260 bool is_200_status_code, 00261 MessageHandler* handler); 00262 00268 virtual void RememberFetchFailed(const GoogleString& key, 00269 const GoogleString& fragment, 00270 MessageHandler* handler); 00271 00275 virtual void RememberFetchDropped(const GoogleString& key, 00276 const GoogleString& fragment, 00277 MessageHandler* handler); 00278 00283 bool IsCacheableContentLength(ResponseHeaders* headers) const; 00288 bool IsCacheableBodySize(int64 body_size) const; 00289 00291 static void InitStats(Statistics* statistics); 00292 00300 bool IsExpired(const ResponseHeaders& headers); 00301 bool IsExpired(const ResponseHeaders& headers, int64 now_ms); 00302 00303 Variable* cache_time_us() { return cache_time_us_; } 00304 Variable* cache_hits() { return cache_hits_; } 00305 Variable* cache_misses() { return cache_misses_; } 00306 Variable* cache_fallbacks() { return cache_fallbacks_; } 00307 Variable* cache_expirations() { return cache_expirations_; } 00308 Variable* cache_inserts() { return cache_inserts_; } 00309 Variable* cache_deletes() { return cache_deletes_; } 00310 00311 int64 remember_not_cacheable_ttl_seconds() { 00312 return remember_not_cacheable_ttl_seconds_; 00313 } 00314 00315 virtual void set_remember_not_cacheable_ttl_seconds(int64 value) { 00316 DCHECK_LE(0, value); 00317 if (value >= 0) { 00318 remember_not_cacheable_ttl_seconds_ = value; 00319 } 00320 } 00321 00322 int64 remember_fetch_failed_ttl_seconds() { 00323 return remember_fetch_failed_ttl_seconds_; 00324 } 00325 00326 virtual void set_remember_fetch_failed_ttl_seconds(int64 value) { 00327 DCHECK_LE(0, value); 00328 if (value >= 0) { 00329 remember_fetch_failed_ttl_seconds_ = value; 00330 } 00331 } 00332 00333 int64 remember_fetch_dropped_ttl_seconds() { 00334 return remember_fetch_dropped_ttl_seconds_; 00335 } 00336 00337 virtual void set_remember_fetch_dropped_ttl_seconds(int64 value) { 00338 DCHECK_LE(0, value); 00339 if (value >= 0) { 00340 remember_fetch_dropped_ttl_seconds_ = value; 00341 } 00342 } 00343 00344 int max_cacheable_response_content_length() { 00345 return max_cacheable_response_content_length_; 00346 } 00347 00348 virtual void set_max_cacheable_response_content_length(int64 value); 00349 00350 virtual GoogleString Name() const { return FormatName(cache_->Name()); } 00351 static GoogleString FormatName(StringPiece cache); 00352 00353 static GoogleString CompositeKey(StringPiece key, StringPiece fragment) { 00354 DCHECK(fragment.find("/") == StringPiece::npos); 00355 00357 return StrCat(fragment, fragment.empty() ? "" : "/", key); 00358 } 00359 00360 protected: 00361 virtual void PutInternal(const GoogleString& key, 00362 const GoogleString& fragment, 00363 int64 start_us, 00364 HTTPValue* value); 00365 00366 private: 00367 friend class HTTPCacheCallback; 00368 friend class WriteThroughHTTPCache; 00369 00370 bool MayCacheUrl(const GoogleString& url, const ResponseHeaders& headers); 00375 HTTPValue* ApplyHeaderChangesForPut( 00376 int64 start_us, const StringPiece* content, ResponseHeaders* headers, 00377 HTTPValue* value, MessageHandler* handler); 00378 void UpdateStats(const GoogleString& key, const GoogleString& fragment, 00379 CacheInterface::KeyState backend_state, FindResult result, 00380 bool has_fallback, bool is_expired, int64 delta_us, 00381 MessageHandler* handler); 00382 void RememberFetchFailedorNotCacheableHelper( 00383 const GoogleString& key, const GoogleString& fragment, 00384 MessageHandler* handler, HttpStatus::Code code, int64 ttl_sec); 00385 00386 CacheInterface* cache_; 00387 Timer* timer_; 00388 Hasher* hasher_; 00389 bool force_caching_; 00391 bool disable_html_caching_on_https_; 00392 00394 Variable* cache_time_us_; 00396 Variable* cache_hits_; 00398 Variable* cache_misses_; 00401 Variable* cache_backend_hits_; 00403 Variable* cache_backend_misses_; 00404 Variable* cache_fallbacks_; 00405 Variable* cache_expirations_; 00406 Variable* cache_inserts_; 00407 Variable* cache_deletes_; 00408 00409 GoogleString name_; 00410 int64 remember_not_cacheable_ttl_seconds_; 00411 int64 remember_fetch_failed_ttl_seconds_; 00412 int64 remember_fetch_dropped_ttl_seconds_; 00413 int64 max_cacheable_response_content_length_; 00414 AtomicBool ignore_failure_puts_; 00415 00416 DISALLOW_COPY_AND_ASSIGN(HTTPCache); 00417 }; 00418 00419 } 00420 00421 #endif ///< NET_INSTAWEB_HTTP_PUBLIC_HTTP_CACHE_H_