libdap
Updated for version 3.17.0
|
00001 00002 // -*- mode: c++; c-basic-offset:4 -*- 00003 00004 // This file is part of libdap, A C++ implementation of the OPeNDAP Data 00005 // Access Protocol. 00006 00007 // Copyright (c) 2002,2008 OPeNDAP, Inc. 00008 // Author: James Gallagher <jgallagher@opendap.org> 00009 // 00010 // This library is free software; you can redistribute it and/or 00011 // modify it under the terms of the GNU Lesser General Public 00012 // License as published by the Free Software Foundation; either 00013 // version 2.1 of the License, or (at your option) any later version. 00014 // 00015 // This library is distributed in the hope that it will be useful, 00016 // but WITHOUT ANY WARRANTY; without even the implied warranty of 00017 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00018 // Lesser General Public License for more details. 00019 // 00020 // You should have received a copy of the GNU Lesser General Public 00021 // License along with this library; if not, write to the Free Software 00022 // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 00023 // 00024 // You can contact OPeNDAP, Inc. at PO Box 112, Saunderstown, RI. 02874-0112. 00025 00026 #ifndef _http_cache_h 00027 #define _http_cache_h 00028 00029 #include <pthread.h> 00030 00031 #ifdef WIN32 00032 #include <io.h> // stat for win32? 09/05/02 jhrg 00033 #endif 00034 00035 #include <string> 00036 #include <vector> 00037 #include <map> 00038 00039 #include "HTTPCacheTable.h" // included for macros 00040 00041 #include "HTTPCacheDisconnectedMode.h" 00042 //using namespace std; 00043 00044 namespace libdap 00045 { 00046 00047 class HTTPCacheTabe; 00048 00049 // This function is exported so the test code can use it too. 00050 bool is_hop_by_hop_header(const string &header); 00051 00103 class HTTPCache 00104 { 00105 private: 00106 string d_cache_root; 00107 FILE *d_locked_open_file; // Lock for single process use. 00108 00109 bool d_cache_enabled; 00110 bool d_cache_protected; 00111 CacheDisconnectedMode d_cache_disconnected; 00112 bool d_expire_ignored; 00113 bool d_always_validate; 00114 00115 unsigned long d_total_size; // How much can we store? 00116 unsigned long d_folder_size; // How much of that is meta data? 00117 unsigned long d_gc_buffer; // How much memory needed as buffer? 00118 unsigned long d_max_entry_size; // Max individual entry size. 00119 int d_default_expiration; 00120 00121 vector<string> d_cache_control; 00122 // these are values read from a request-directive Cache-Control header. 00123 // Not to be confused with values read from the response or a cached 00124 // response (e.g., CacheEntry has a max_age field, too). These fields are 00125 // set when the set_cache_control method is called. 00126 time_t d_max_age; 00127 time_t d_max_stale; // -1: not set, 0:any response, >0 max time. 00128 time_t d_min_fresh; 00129 00130 // Lock non-const methods (also ones that use the STL). 00131 pthread_mutex_t d_cache_mutex; 00132 00133 HTTPCacheTable *d_http_cache_table; 00134 00135 // d_open_files is used by the interrupt handler to clean up 00136 vector<string> d_open_files; 00137 00138 static HTTPCache *_instance; 00139 00140 friend class HTTPCacheTest; // Unit tests 00141 friend class HTTPConnectTest; 00142 00143 friend class HTTPCacheInterruptHandler; 00144 00145 // Private methods 00146 HTTPCache(const HTTPCache &); 00147 HTTPCache(); 00148 HTTPCache &operator=(const HTTPCache &); 00149 00150 HTTPCache(string cache_root, bool force); 00151 00152 static void delete_instance(); // Run by atexit (hence static) 00153 00154 void set_cache_root(const string &root = ""); 00155 void create_cache_root(const string &cache_root); 00156 00157 // These will go away when the cache can be used by multiple processes. 00158 bool get_single_user_lock(bool force = false); 00159 void release_single_user_lock(); 00160 00161 bool is_url_in_cache(const string &url); 00162 00163 // I made these four methods so they could be tested by HTTPCacheTest. 00164 // Otherwise they would be static functions. jhrg 10/01/02 00165 void write_metadata(const string &cachename, const vector<string> &headers); 00166 void read_metadata(const string &cachename, vector<string> &headers); 00167 int write_body(const string &cachename, const FILE *src); 00168 FILE *open_body(const string &cachename); 00169 00170 bool stopGC() const; 00171 bool startGC() const; 00172 00173 void perform_garbage_collection(); 00174 void too_big_gc(); 00175 void expired_gc(); 00176 void hits_gc(); 00177 00178 public: 00179 static HTTPCache *instance(const string &cache_root, bool force = false); 00180 virtual ~HTTPCache(); 00181 00182 string get_cache_root() const; 00183 00184 void set_cache_enabled(bool mode); 00185 bool is_cache_enabled() const; 00186 00187 void set_cache_disconnected(CacheDisconnectedMode mode); 00188 CacheDisconnectedMode get_cache_disconnected() const; 00189 00190 void set_expire_ignored(bool mode); 00191 bool is_expire_ignored() const; 00192 00193 void set_max_size(unsigned long size); 00194 unsigned long get_max_size() const; 00195 00196 void set_max_entry_size(unsigned long size); 00197 unsigned long get_max_entry_size() const; 00198 00199 void set_default_expiration(int exp_time); 00200 int get_default_expiration() const; 00201 00202 void set_always_validate(bool validate); 00203 bool get_always_validate() const; 00204 00205 void set_cache_control(const vector<string> &cc); 00206 vector<string> get_cache_control(); 00207 00208 void lock_cache_interface() { 00209 DBG(cerr << "Locking interface... "); 00210 LOCK(&d_cache_mutex); 00211 DBGN(cerr << "Done" << endl); 00212 } 00213 void unlock_cache_interface() { 00214 DBG(cerr << "Unlocking interface... " ); 00215 UNLOCK(&d_cache_mutex); 00216 DBGN(cerr << "Done" << endl); 00217 } 00218 00219 // This must lock for writing 00220 bool cache_response(const string &url, time_t request_time, 00221 const vector<string> &headers, const FILE *body); 00222 void update_response(const string &url, time_t request_time, 00223 const vector<string> &headers); 00224 00225 // This is separate from get_cached_response() because often an invalid 00226 // cache entry just needs a header update. That is best left to the HTTP 00227 // Connection code. 00228 bool is_url_valid(const string &url); 00229 00230 // Lock these for reading 00231 vector<string> get_conditional_request_headers(const string &url); 00232 FILE *get_cached_response(const string &url, vector<string> &headers, 00233 string &cacheName); 00234 FILE *get_cached_response(const string &url, vector<string> &headers); 00235 FILE *get_cached_response(const string &url); 00236 00237 void release_cached_response(FILE *response); 00238 00239 void purge_cache(); 00240 }; 00241 00242 } // namespace libdap 00243 00244 #endif // _http_cache_h