libdap  Updated for version 3.17.0
HTTPCache.h
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