00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
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/response_headers.h"
00026 #include "net/instaweb/util/public/atomic_bool.h"
00027 #include "net/instaweb/util/public/basictypes.h"
00028 #include "net/instaweb/util/public/string.h"
00029 #include "net/instaweb/util/public/string_util.h"
00030
00031 namespace net_instaweb {
00032
00033 class CacheInterface;
00034 class Hasher;
00035 class MessageHandler;
00036 class Statistics;
00037 class Timer;
00038 class TimingInfo;
00039 class Variable;
00040
00043 class HTTPCache {
00044 public:
00046 static const char kCacheTimeUs[];
00047 static const char kCacheHits[];
00048 static const char kCacheMisses[];
00049 static const char kCacheExpirations[];
00050 static const char kCacheInserts[];
00051 static const char kCacheDeletes[];
00052
00054 static const char kEtagPrefix[];
00055
00057 HTTPCache(CacheInterface* cache, Timer* timer, Hasher* hasher,
00058 Statistics* stats);
00059 virtual ~HTTPCache();
00060
00062 enum FindResult {
00063 kFound,
00064 kNotFound,
00067 kRecentFetchFailed,
00068 kRecentFetchNotCacheable,
00069 };
00070
00076 class Callback {
00077 public:
00078 Callback()
00079 : response_headers_(NULL),
00080 owns_response_headers_(false),
00081 timing_info_(NULL),
00082 owns_timing_info_(false) {
00083 }
00084 virtual ~Callback();
00085 virtual void Done(FindResult find_result) = 0;
00095 virtual bool IsCacheValid(const ResponseHeaders& headers) = 0;
00096
00104 virtual bool IsFresh(const ResponseHeaders& headers) { return true; }
00105
00108 HTTPValue* http_value() { return &http_value_; }
00109 ResponseHeaders* response_headers() {
00110 if (response_headers_ == NULL) {
00111 response_headers_ = new ResponseHeaders;
00112 owns_response_headers_ = true;
00113 }
00114 return response_headers_;
00115 }
00116 const ResponseHeaders* response_headers() const {
00117 return const_cast<Callback*>(this)->response_headers();
00118 }
00119 void set_response_headers(ResponseHeaders* headers) {
00120 DCHECK(!owns_response_headers_);
00121 if (owns_response_headers_) {
00122 delete response_headers_;
00123 }
00124 response_headers_ = headers;
00125 owns_response_headers_ = false;
00126 }
00127 HTTPValue* fallback_http_value() { return &fallback_http_value_; }
00128
00132 void set_timing_info(TimingInfo* timing_info);
00133 virtual TimingInfo* timing_info();
00134 virtual void SetTimingMs(int64 timing_value_ms);
00135
00136 private:
00137 HTTPValue http_value_;
00140 HTTPValue fallback_http_value_;
00141 ResponseHeaders* response_headers_;
00142 bool owns_response_headers_;
00143 TimingInfo* timing_info_;
00144 bool owns_timing_info_;
00145
00146 DISALLOW_COPY_AND_ASSIGN(Callback);
00147 };
00148
00150 virtual void SetIgnoreFailurePuts();
00151
00154 virtual void Find(const GoogleString& key, MessageHandler* handler,
00155 Callback* callback);
00156
00159 virtual void Put(const GoogleString& key, HTTPValue* value,
00160 MessageHandler* handler);
00161
00164 virtual void Put(const GoogleString& key, ResponseHeaders* headers,
00165 const StringPiece& content, MessageHandler* handler);
00166
00168 virtual void Delete(const GoogleString& key);
00169
00170 virtual void set_force_caching(bool force) { force_caching_ = force; }
00171 bool force_caching() const { return force_caching_; }
00172 Timer* timer() const { return timer_; }
00173
00181 virtual void RememberNotCacheable(const GoogleString& key,
00182 MessageHandler * handler);
00183
00189 virtual void RememberFetchFailed(const GoogleString& key,
00190 MessageHandler * handler);
00191
00196 bool IsCacheableContentLength(ResponseHeaders* headers) const;
00201 bool IsCacheableBodySize(int64 body_size) const;
00202
00204 static void Initialize(Statistics* statistics);
00205
00209 bool IsAlreadyExpired(const ResponseHeaders& headers);
00210
00211 Variable* cache_time_us() { return cache_time_us_; }
00212 Variable* cache_hits() { return cache_hits_; }
00213 Variable* cache_misses() { return cache_misses_; }
00214 Variable* cache_expirations() { return cache_expirations_; }
00215 Variable* cache_inserts() { return cache_inserts_; }
00216 Variable* cache_deletes() { return cache_deletes_; }
00217
00218 int64 remember_not_cacheable_ttl_seconds() {
00219 return remember_not_cacheable_ttl_seconds_;
00220 }
00221
00222 virtual void set_remember_not_cacheable_ttl_seconds(int64 value) {
00223 DCHECK_LE(0, value);
00224 if (value >= 0) {
00225 remember_not_cacheable_ttl_seconds_ = value;
00226 }
00227 }
00228
00229 int64 remember_fetch_failed_ttl_seconds() {
00230 return remember_fetch_failed_ttl_seconds_;
00231 }
00232
00233 virtual void set_remember_fetch_failed_ttl_seconds(int64 value) {
00234 DCHECK_LE(0, value);
00235 if (value >= 0) {
00236 remember_fetch_failed_ttl_seconds_ = value;
00237 }
00238 }
00239
00240 int max_cacheable_response_content_length() {
00241 return max_cacheable_response_content_length_;
00242 }
00243
00244 virtual void set_max_cacheable_response_content_length(int64 value);
00245
00246 virtual const char* Name() const { return name_.c_str(); }
00247
00248 protected:
00249 virtual void PutInternal(const GoogleString& key, int64 start_us,
00250 HTTPValue* value);
00251
00252 private:
00253 friend class HTTPCacheCallback;
00254 friend class WriteThroughHTTPCache;
00255
00256 bool IsCurrentlyValid(const ResponseHeaders& headers, int64 now_ms);
00261 HTTPValue* ApplyHeaderChangesForPut(
00262 const GoogleString& key, int64 start_us, const StringPiece* content,
00263 ResponseHeaders* headers, HTTPValue* value, MessageHandler* handler);
00264 void UpdateStats(FindResult result, int64 delta_us);
00265 void RememberFetchFailedorNotCacheableHelper(
00266 const GoogleString& key, MessageHandler* handler, HttpStatus::Code code,
00267 int64 ttl_sec);
00268
00269 CacheInterface* cache_;
00270 Timer* timer_;
00271 Hasher* hasher_;
00272 bool force_caching_;
00273 Variable* cache_time_us_;
00274 Variable* cache_hits_;
00275 Variable* cache_misses_;
00276 Variable* cache_expirations_;
00277 Variable* cache_inserts_;
00278 Variable* cache_deletes_;
00279 GoogleString name_;
00280 int64 remember_not_cacheable_ttl_seconds_;
00281 int64 remember_fetch_failed_ttl_seconds_;
00282 int64 max_cacheable_response_content_length_;
00283 AtomicBool ignore_failure_puts_;
00284
00285 DISALLOW_COPY_AND_ASSIGN(HTTPCache);
00286 };
00287
00288 }
00289
00290 #endif ///< NET_INSTAWEB_HTTP_PUBLIC_HTTP_CACHE_H_