00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026 #ifndef _http_cache_h
00027 #define _http_cache_h
00028
00029 #include <stdio.h>
00030 #include <pthread.h>
00031 #include <sys/types.h>
00032 #include <sys/stat.h>
00033
00034 #ifdef WIN32
00035 #include <io.h>
00036 #else
00037 #include <unistd.h>
00038 #endif
00039
00040 #include <string>
00041 #include <vector>
00042 #include <map>
00043
00044 #ifndef _error_h
00045 #include "Error.h"
00046 #endif
00047
00048 #ifndef _internalerr_h
00049 #include "InternalErr.h"
00050 #endif
00051
00052
00053
00054
00055
00056
00057
00058 #ifndef _response_too_big_err_h
00059 #include "ResponseTooBigErr.h"
00060 #endif
00061
00062 #ifndef _http_cache_disconnected_mode_h
00063 #include "HTTPCacheDisconnectedMode.h"
00064 #endif
00065
00066 #ifndef _signal_handler_registered_err_h
00067 #include "SignalHandlerRegisteredErr.h"
00068 #endif
00069
00070 const int CACHE_TABLE_SIZE = 1499;
00071
00072 using namespace std;
00073
00131 class HTTPCache
00132 {
00133 public:
00145 struct CacheEntry
00146 {
00147 string url;
00148 int hash;
00149 int hits;
00150
00151 string cachename;
00152
00153 string etag;
00154 time_t lm;
00155 time_t expires;
00156 time_t date;
00157 time_t age;
00158 time_t max_age;
00159
00160 unsigned long size;
00161 bool range;
00162
00163
00164 time_t freshness_lifetime;
00165 time_t response_time;
00166 time_t corrected_initial_age;
00167
00168 bool must_revalidate;
00169 bool no_cache;
00170
00171 int locked;
00172 pthread_mutex_t lock ;
00173
00174 CacheEntry() : url(""), hash(-1), hits(0), cachename(""),
00175 etag(""), lm(-1),
00176 expires(-1), date(-1), age(-1), max_age(-1), size(0),
00177 range(false), freshness_lifetime(0), response_time(0),
00178 corrected_initial_age(0), must_revalidate(false),
00179 no_cache(false), locked(0)
00180 {}
00181 };
00182
00183 #ifdef WIN32
00184
00185
00186
00187
00188
00189
00190
00191
00192
00193 unsigned long d_max_entry_size;
00194
00195 void remove_cache_entry(CacheEntry *entry);
00196 bool stopGC() const;
00197 #endif
00198
00199 private:
00200 string d_cache_root;
00201 string d_cache_index;
00202 FILE *d_locked_open_file;
00203
00204 bool d_cache_enabled;
00205 bool d_cache_protected;
00206 CacheDisconnectedMode d_cache_disconnected;
00207 bool d_expire_ignored;
00208 bool d_always_validate;
00209
00210 unsigned long d_total_size;
00211 unsigned long d_folder_size;
00212 unsigned long d_gc_buffer;
00213 #ifndef WIN32 // Declared public above for win32
00214 unsigned long d_max_entry_size;
00215 #endif
00216 unsigned long d_current_size;
00217 int d_default_expiration;
00218 unsigned int d_block_size;
00219
00220 vector<string> d_cache_control;
00221
00222
00223
00224
00225 time_t d_max_age;
00226 time_t d_max_stale;
00227 time_t d_min_fresh;
00228
00229 int d_new_entries;
00230
00231
00232 pthread_mutex_t d_cache_mutex;
00233
00234
00235
00236
00237
00238
00239 typedef vector<CacheEntry *> CachePointers;
00240 typedef CachePointers::iterator CachePointersIter;
00241
00242
00243
00244
00245 typedef CachePointers *CacheTable[CACHE_TABLE_SIZE];
00246
00247 CacheTable d_cache_table;
00248
00249 map<FILE *, CacheEntry *> d_locked_entries;
00250 vector<string> d_open_files;
00251
00252 static HTTPCache *_instance;
00253
00254 friend class HTTPCacheTest;
00255 friend class HTTPCacheInterruptHandler;
00256
00257
00258
00259 friend class DeleteExpired;
00260 friend class DeleteByHits;
00261 friend class DeleteCacheEntry;
00262 friend class DeleteUnlockedCacheEntry;
00263 friend class WriteOneCacheEntry;
00264
00265
00266
00267 void clone(const HTTPCache &)
00268 {}
00269
00270 HTTPCache(const HTTPCache &cache)
00271 {
00272 clone(cache);
00273 }
00274
00275 HTTPCache()
00276 {}
00277
00278 HTTPCache(string cache_root, bool force) throw(Error);
00279
00280 HTTPCache &operator=(const HTTPCache &rhs)
00281 {
00282 if (this != &rhs)
00283 clone(rhs);
00284 return *this;
00285 }
00286
00287 static void delete_instance();
00288
00289 CacheEntry *cache_index_parse_line(const char *line);
00290 bool cache_index_read();
00291 bool cache_index_delete();
00292
00293 void set_cache_root(const string &root = "");
00294
00295 bool get_single_user_lock(bool force = false);
00296 void release_single_user_lock();
00297
00298 void add_entry_to_cache_table(CacheEntry *e);
00299 void remove_entry_from_cache_table(const string &url);
00300 void parse_headers(CacheEntry *entry, const vector<string> &headers);
00301 void calculate_time(CacheEntry *entry, time_t request_time);
00302 #ifndef WIN32 // Declared public above for win32
00303 void remove_cache_entry(CacheEntry *entry);
00304 #endif
00305 CacheEntry *get_entry_from_cache_table(const string &url) const;
00306 CacheEntry *get_entry_from_cache_table(int hash, const string &url) const;
00307
00308
00309
00310
00311 void write_metadata(const string &cachename, const vector<string> &headers);
00312 void read_metadata(const string &cachename, vector<string> &headers);
00313 int write_body(const string &cachename, const FILE *src);
00314 FILE *open_body(const string &cachename);
00315
00316 void create_cache_root(const string &cache_root);
00317
00318 string create_hash_directory(int hash);
00319 void create_location(CacheEntry *entry);
00320
00321 #ifndef WIN32 // Declared public above for win32
00322 bool stopGC() const;
00323 #endif
00324 bool startGC() const;
00325
00326 void cache_index_write();
00327
00328 void perform_garbage_collection();
00329 void expired_gc();
00330 void hits_gc();
00331
00332 public:
00333 static HTTPCache *instance(const string &cache_root, bool force = false);
00334 virtual ~HTTPCache();
00335
00336 string get_cache_root() const;
00337
00338 void set_cache_enabled(bool mode);
00339 bool is_cache_enabled() const;
00340
00341 void set_cache_protected(bool mode);
00342 bool is_cache_protected() const;
00343
00344 void set_cache_disconnected(CacheDisconnectedMode mode);
00345 CacheDisconnectedMode get_cache_disconnected() const;
00346
00347 void set_expire_ignored(bool mode);
00348 bool is_expire_ignored() const;
00349
00350 void set_max_size(unsigned long size);
00351 unsigned long get_max_size() const;
00352
00353 void set_max_entry_size(unsigned long size);
00354 unsigned long get_max_entry_size() const;
00355
00356 void set_default_expiration(int exp_time);
00357 int get_default_expiration() const;
00358
00359 void set_always_validate(bool validate);
00360 bool get_always_validate() const;
00361
00362 void set_cache_control(const vector<string> &cc);
00363 vector<string> get_cache_control();
00364
00365 bool cache_response(const string &url, time_t request_time,
00366 const vector<string> &headers, const FILE *body);
00367 vector<string> get_conditional_request_headers(const string &url);
00368 void update_response(const string &url, time_t request_time,
00369 const vector<string> &headers);
00370
00371 bool is_url_in_cache(const string &url);
00372 bool is_url_valid(const string &url);
00373 FILE *get_cached_response(const string &url, vector<string> &headers);
00374 FILE *get_cached_response_body(const string &url);
00375 void release_cached_response(FILE *response);
00376
00377 void purge_cache();
00378 };
00379
00380 #endif // _http_cache_h