Page Speed Optimization Libraries  1.8.31.3
net/instaweb/http/public/http_cache.h
Go to the documentation of this file.
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_
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines