libdap++  Updated for version 3.14.0
HTTPCache.h
Go to the documentation of this file.
1 
2 // -*- mode: c++; c-basic-offset:4 -*-
3 
4 // This file is part of libdap, A C++ implementation of the OPeNDAP Data
5 // Access Protocol.
6 
7 // Copyright (c) 2002,2008 OPeNDAP, Inc.
8 // Author: James Gallagher <jgallagher@opendap.org>
9 //
10 // This library is free software; you can redistribute it and/or
11 // modify it under the terms of the GNU Lesser General Public
12 // License as published by the Free Software Foundation; either
13 // version 2.1 of the License, or (at your option) any later version.
14 //
15 // This library is distributed in the hope that it will be useful,
16 // but WITHOUT ANY WARRANTY; without even the implied warranty of
17 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 // Lesser General Public License for more details.
19 //
20 // You should have received a copy of the GNU Lesser General Public
21 // License along with this library; if not, write to the Free Software
22 // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
23 //
24 // You can contact OPeNDAP, Inc. at PO Box 112, Saunderstown, RI. 02874-0112.
25 
26 #ifndef _http_cache_h
27 #define _http_cache_h
28 
29 #include <pthread.h>
30 
31 #ifdef WIN32
32 #include <io.h> // stat for win32? 09/05/02 jhrg
33 #endif
34 
35 #include <string>
36 #include <vector>
37 #include <map>
38 
39 #ifndef _http_cache_table_h
40 #include "HTTPCacheTable.h"
41 #endif
42 
43 #ifndef _error_h
44 #include "Error.h"
45 #endif
46 
47 #ifndef _internalerr_h
48 #include "InternalErr.h"
49 #endif
50 
51 #ifndef _debug_h
52 #include "debug.h"
53 #endif
54 
55 // The private method HTTPCache::write_body() could, at one time, throw
56 // ResponseTooBig to signal that while writing a response body it was found
57 // to be bigger than the max_entry_size property. But I bagged that; the
58 // garbage collection methods remove entries larger than max_entry_size. It
59 // might be that a really big entry belongs in the cache so long as it
60 // doesn't push other entries out. 10/07/02 jhrg
61 #ifndef _response_too_big_err_h
62 #include "ResponseTooBigErr.h"
63 #endif
64 
65 #ifndef _http_cache_disconnected_mode_h
67 #endif
68 
69 #ifndef _signal_handler_registered_err_h
71 #endif
72 
73 using namespace std;
74 
75 namespace libdap
76 {
77 
78 // This function is exported so the test code can use it too.
79 bool is_hop_by_hop_header(const string &header);
80 
133 {
134 private:
135  string d_cache_root;
136  FILE *d_locked_open_file; // Lock for single process use.
137 
138  bool d_cache_enabled;
139  bool d_cache_protected;
140  CacheDisconnectedMode d_cache_disconnected;
141  bool d_expire_ignored;
142  bool d_always_validate;
143 
144  unsigned long d_total_size; // How much can we store?
145  unsigned long d_folder_size; // How much of that is meta data?
146  unsigned long d_gc_buffer; // How much memory needed as buffer?
147  unsigned long d_max_entry_size; // Max individual entry size.
148  int d_default_expiration;
149 
150  vector<string> d_cache_control;
151  // these are values read from a request-directive Cache-Control header.
152  // Not to be confused with values read from the response or a cached
153  // response (e.g., CacheEntry has a max_age field, too). These fields are
154  // set when the set_cache_control method is called.
155  time_t d_max_age;
156  time_t d_max_stale; // -1: not set, 0:any response, >0 max time.
157  time_t d_min_fresh;
158 
159  // Lock non-const methods (also ones that use the STL).
160  pthread_mutex_t d_cache_mutex;
161 
162  HTTPCacheTable *d_http_cache_table;
163 
164  // d_open_files is used by the interrupt handler to clean up
165  vector<string> d_open_files;
166 
167  static HTTPCache *_instance;
168 
169  friend class HTTPCacheTest; // Unit tests
170  friend class HTTPConnectTest;
171 
173 
174  // Private methods
175  HTTPCache(const HTTPCache &) {
176  throw InternalErr(__FILE__, __LINE__, "Unimplemented");
177  }
178  HTTPCache() {
179  throw InternalErr(__FILE__, __LINE__, "Unimplemented");
180  }
181  HTTPCache &operator=(const HTTPCache &) {
182  throw InternalErr(__FILE__, __LINE__, "Unimplemented");
183  }
184 
185  HTTPCache(string cache_root, bool force);
186 
187  static void delete_instance(); // Run by atexit (hence static)
188 
189  void set_cache_root(const string &root = "");
190  void create_cache_root(const string &cache_root);
191 
192  // These will go away when the cache can be used by multiple processes.
193  bool get_single_user_lock(bool force = false);
194  void release_single_user_lock();
195 
196  bool is_url_in_cache(const string &url);
197 
198  // I made these four methods so they could be tested by HTTPCacheTest.
199  // Otherwise they would be static functions. jhrg 10/01/02
200  void write_metadata(const string &cachename, const vector<string> &headers);
201  void read_metadata(const string &cachename, vector<string> &headers);
202  int write_body(const string &cachename, const FILE *src);
203  FILE *open_body(const string &cachename);
204 
205  bool stopGC() const;
206  bool startGC() const;
207 
208  void perform_garbage_collection();
209  void too_big_gc();
210  void expired_gc();
211  void hits_gc();
212 
213 public:
214  static HTTPCache *instance(const string &cache_root, bool force = false);
215  virtual ~HTTPCache();
216 
217  string get_cache_root() const;
218 
219  void set_cache_enabled(bool mode);
220  bool is_cache_enabled() const;
221 
222  void set_cache_disconnected(CacheDisconnectedMode mode);
223  CacheDisconnectedMode get_cache_disconnected() const;
224 
225  void set_expire_ignored(bool mode);
226  bool is_expire_ignored() const;
227 
228  void set_max_size(unsigned long size);
229  unsigned long get_max_size() const;
230 
231  void set_max_entry_size(unsigned long size);
232  unsigned long get_max_entry_size() const;
233 
234  void set_default_expiration(int exp_time);
235  int get_default_expiration() const;
236 
237  void set_always_validate(bool validate);
238  bool get_always_validate() const;
239 
240  void set_cache_control(const vector<string> &cc);
241  vector<string> get_cache_control();
242 
244  DBG(cerr << "Locking interface... ");
245  LOCK(&d_cache_mutex);
246  DBGN(cerr << "Done" << endl);
247  }
249  DBG(cerr << "Unlocking interface... " );
250  UNLOCK(&d_cache_mutex);
251  DBGN(cerr << "Done" << endl);
252  }
253 
254  // This must lock for writing
255  bool cache_response(const string &url, time_t request_time,
256  const vector<string> &headers, const FILE *body);
257  void update_response(const string &url, time_t request_time,
258  const vector<string> &headers);
259 
260  // This is separate from get_cached_response() because often an invalid
261  // cache entry just needs a header update. That is best left to the HTTP
262  // Connection code.
263  bool is_url_valid(const string &url);
264 
265  // Lock these for reading
266  vector<string> get_conditional_request_headers(const string &url);
267  FILE *get_cached_response(const string &url, vector<string> &headers,
268  string &cacheName);
269  FILE *get_cached_response(const string &url, vector<string> &headers);
270  FILE *get_cached_response(const string &url);
271 
272  void release_cached_response(FILE *response);
273 
274  void purge_cache();
275 };
276 
277 } // namespace libdap
278 
279 #endif // _http_cache_h
#define DBGN(x)
Definition: debug.h:59
#define UNLOCK(m)
A class for software fault reporting.
Definition: InternalErr.h:64
bool is_hop_by_hop_header(const string &header)
Definition: HTTPCache.cc:938
#define DBG(x)
Definition: debug.h:58
#define LOCK(m)
void unlock_cache_interface()
Definition: HTTPCache.h:248
void lock_cache_interface()
Definition: HTTPCache.h:243