libdap++  Updated for version 3.8.2
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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 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 #define LOCK(m) pthread_mutex_lock((m))
74 #define TRYLOCK(m) pthread_mutex_trylock((m))
75 #define UNLOCK(m) pthread_mutex_unlock((m))
76 #define INIT(m) pthread_mutex_init((m), 0)
77 #define DESTROY(m) pthread_mutex_destroy((m))
78 
79 using namespace std;
80 
81 namespace libdap
82 {
83 
84 // This function is exported so the test code can use it too.
85 bool is_hop_by_hop_header(const string &header);
86 
139 {
140 private:
141  string d_cache_root;
142  FILE *d_locked_open_file; // Lock for single process use.
143 
144  bool d_cache_enabled;
145  bool d_cache_protected;
146  CacheDisconnectedMode d_cache_disconnected;
147  bool d_expire_ignored;
148  bool d_always_validate;
149 
150  unsigned long d_total_size; // How much can we store?
151  unsigned long d_folder_size; // How much of that is meta data?
152  unsigned long d_gc_buffer; // How much memory needed as buffer?
153  unsigned long d_max_entry_size; // Max individual entry size.
154  int d_default_expiration;
155 
156  vector<string> d_cache_control;
157  // these are values read from a request-directive Cache-Control header.
158  // Not to be confused with values read from the response or a cached
159  // response (e.g., CacheEntry has a max_age field, too). These fields are
160  // set when the set_cache_control method is called.
161  time_t d_max_age;
162  time_t d_max_stale; // -1: not set, 0:any response, >0 max time.
163  time_t d_min_fresh;
164 
165  // Lock non-const methods (also ones that use the STL).
166  pthread_mutex_t d_cache_mutex;
167 
168  HTTPCacheTable *d_http_cache_table;
169 
170  // d_open_files is used by the interrupt handler to clean up
171  vector<string> d_open_files;
172 
173  static HTTPCache *_instance;
174 
175  friend class HTTPCacheTest; // Unit tests
177 
178  // Private methods
179  HTTPCache(const HTTPCache &) {
180  throw InternalErr(__FILE__, __LINE__, "Unimplemented");
181  }
182  HTTPCache() {
183  throw InternalErr(__FILE__, __LINE__, "Unimplemented");
184  }
185  HTTPCache &operator=(const HTTPCache &) {
186  throw InternalErr(__FILE__, __LINE__, "Unimplemented");
187  }
188 
189  HTTPCache(string cache_root, bool force);
190 
191  static void delete_instance(); // Run by atexit (hence static)
192 
193  void set_cache_root(const string &root = "");
194  void create_cache_root(const string &cache_root);
195 
196  // These will go away when the cache can be used by multiple processes.
197  bool get_single_user_lock(bool force = false);
198  void release_single_user_lock();
199 
200  bool is_url_in_cache(const string &url);
201 
202  // I made these four methods so they could be tested by HTTPCacheTest.
203  // Otherwise they would be static functions. jhrg 10/01/02
204  void write_metadata(const string &cachename, const vector<string> &headers);
205  void read_metadata(const string &cachename, vector<string> &headers);
206  int write_body(const string &cachename, const FILE *src);
207  FILE *open_body(const string &cachename);
208 
209  bool stopGC() const;
210  bool startGC() const;
211 
212  void perform_garbage_collection();
213  void too_big_gc();
214  void expired_gc();
215  void hits_gc();
216 
217 public:
218  static HTTPCache *instance(const string &cache_root, bool force = false);
219  virtual ~HTTPCache();
220 
221  string get_cache_root() const;
222 
223  void set_cache_enabled(bool mode);
224  bool is_cache_enabled() const;
225 
226  void set_cache_disconnected(CacheDisconnectedMode mode);
227  CacheDisconnectedMode get_cache_disconnected() const;
228 
229  void set_expire_ignored(bool mode);
230  bool is_expire_ignored() const;
231 
232  void set_max_size(unsigned long size);
233  unsigned long get_max_size() const;
234 
235  void set_max_entry_size(unsigned long size);
236  unsigned long get_max_entry_size() const;
237 
238  void set_default_expiration(int exp_time);
239  int get_default_expiration() const;
240 
241  void set_always_validate(bool validate);
242  bool get_always_validate() const;
243 
244  void set_cache_control(const vector<string> &cc);
245  vector<string> get_cache_control();
246 
248  DBG(cerr << "Locking interface... ");
249  LOCK(&d_cache_mutex);
250  DBGN(cerr << "Done" << endl);
251  }
253  DBG(cerr << "Unlocking interface... " );
254  UNLOCK(&d_cache_mutex);
255  DBGN(cerr << "Done" << endl);
256  }
257 
258  // This must lock for writing
259  bool cache_response(const string &url, time_t request_time,
260  const vector<string> &headers, const FILE *body);
261  void update_response(const string &url, time_t request_time,
262  const vector<string> &headers);
263 
264  // This is separate from get_cached_response() because often an invalid
265  // cache entry just needs a header update. That is best left to the HTTP
266  // Connection code.
267  bool is_url_valid(const string &url);
268 
269  // Lock these for reading
270  vector<string> get_conditional_request_headers(const string &url);
271  FILE *get_cached_response(const string &url, vector<string> &headers,
272  string &cacheName);
273  FILE *get_cached_response(const string &url, vector<string> &headers);
274  FILE *get_cached_response(const string &url);
275 
276  void release_cached_response(FILE *response);
277 
278  void purge_cache();
279 };
280 
281 } // namespace libdap
282 
283 #endif // _http_cache_h
#define LOCK(m)
Definition: HTTPCache.h:73
#define DBGN(x)
Definition: debug.h:59
A class for software fault reporting.
Definition: InternalErr.h:64
bool is_hop_by_hop_header(const string &header)
Definition: HTTPCache.cc:949
#define DBG(x)
Definition: debug.h:58
#define UNLOCK(m)
Definition: HTTPCache.h:75
void unlock_cache_interface()
Definition: HTTPCache.h:252
void lock_cache_interface()
Definition: HTTPCache.h:247