Page Speed Optimization Libraries  1.7.30.4
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 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_
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines