64 RemoteHttpResource::RemoteHttpResource(
const string &url)
70 d_resourceCacheFileName.clear();
71 d_response_headers =
new vector<string>();
72 d_request_headers =
new vector<string>();
76 string err =
"RemoteHttpResource(): Remote resource URL is empty" ;
79 d_remoteResourceUrl = url;
80 BESDEBUG(
"gateway",
"RemoteHttpResource() - URL: " << d_remoteResourceUrl << endl);
98 BESDEBUG(
"gateway",
"RemoteHttpResource() - d_curl: " << d_curl << endl);
104 RemoteHttpResource::~RemoteHttpResource() {
110 BESDEBUG(
"gateway",
"~RemoteHttpResource() - BEGIN resourceURL: " << d_remoteResourceUrl << endl);
112 delete d_response_headers;
113 d_response_headers = 0;
114 BESDEBUG(
"gateway",
"~RemoteHttpResource() - Deleted d_response_headers." << endl);
116 delete d_request_headers;
117 d_request_headers = 0;
118 BESDEBUG(
"gateway",
"~RemoteHttpResource() - Deleted d_request_headers." << endl);
120 if(!d_resourceCacheFileName.empty()){
122 BESDEBUG(
"gateway",
"~RemoteHttpResource() - Closed and unlocked "<< d_resourceCacheFileName << endl);
123 d_resourceCacheFileName.clear();
128 curl_easy_cleanup(d_curl);
129 BESDEBUG(
"gateway",
"~RemoteHttpResource() - Called curl_easy_cleanup()." << endl);
134 BESDEBUG(
"gateway",
"~RemoteHttpResource() - END resourceURL: " << d_remoteResourceUrl << endl);
135 d_remoteResourceUrl.clear();
147 void RemoteHttpResource::retrieveResource()
149 BESDEBUG(
"gateway",
"RemoteHttpResource::retrieveResource() - BEGIN resourceURL: " << d_remoteResourceUrl << endl);
153 BESDEBUG(
"gateway",
"RemoteHttpResource::retrieveResource() - END Already initialized." << endl);
159 (
string)
"BES.CachePrefix", (
string)
"BES.CacheSize");
167 BESDEBUG(
"gateway",
"RemoteHttpResource::retrieveResource() - d_resourceCacheFileName: " << d_resourceCacheFileName << endl);
176 BESDEBUG(
"gateway",
"RemoteHttpResource::retrieveResource() - d_type: " << d_type << endl);
181 BESDEBUG(
"gateway",
"RemoteHttpResource::retrieveResource() - Remote resource is already in cache. cache_file_name: "
182 << d_resourceCacheFileName << endl );
193 writeResourceToFile(d_fd);
208 BESDEBUG(
"gateway",
"RemoteHttpResource::retrieveResource() - Converted exclusive cache lock to shared lock." << endl );
215 BESDEBUG(
"gateway",
"RemoteHttpResource::retrieveResource() - Updated cache info" << endl );
219 BESDEBUG(
"gateway",
"RemoteHttpResource::retrieveResource() - Updated and purged cache." << endl );
222 BESDEBUG(
"gateway",
"RemoteHttpResource::retrieveResource() - END" << endl );
230 BESDEBUG(
"gateway",
"RemoteHttpResource::retrieveResource() - Remote resource is in cache. cache_file_name: "
231 << d_resourceCacheFileName << endl );
237 string msg =
"RemoteHttpResource::retrieveResource() - Failed to acquire cache read lock for remote resource: '";
238 msg += d_remoteResourceUrl +
"\n";
239 throw libdap::Error(msg);
244 BESDEBUG(
"gateway",
"RemoteHttpResource::retrieveResource() - Caught exception, unlocking cache and re-throw." << endl );
261 void RemoteHttpResource::writeResourceToFile(
int fd) {
262 BESDEBUG(
"gateway",
"RemoteHttpResource::writeResourceToFile() - BEGIN" << endl );
267 BESDEBUG(
"gateway",
"RemoteHttpResource::writeResourceToFile() - Saving resource " << d_remoteResourceUrl <<
" to cache file " << d_resourceCacheFileName << endl );
268 status =
libcurl::read_url(d_curl, d_remoteResourceUrl, fd, d_response_headers, d_request_headers, d_error_buffer);
270 BESDEBUG(
"gateway",
"RemoteHttpResource::writeResourceToFile() - HTTP returned an error status: " << status << endl );
272 string msg =
"Error while reading the URL: '";
273 msg += d_remoteResourceUrl;
274 msg +=
"'The HTTP request returned a status of " + libdap::long_to_string(status) +
" which means '";
276 throw libdap::Error(msg);
278 BESDEBUG(
"gateway",
"RemoteHttpResource::writeResourceToFile() - Resource " << d_remoteResourceUrl <<
" saved to cache file " << d_resourceCacheFileName << endl );
281 lseek(fd,0,SEEK_SET);
282 BESDEBUG(
"gateway",
"RemoteHttpResource::writeResourceToFile() - Reset file descriptor." << endl );
285 setType(d_response_headers);
287 catch (libdap::Error &e) {
290 BESDEBUG(
"gateway",
"RemoteHttpResource::writeResourceToFile() - END" << endl );
295 void RemoteHttpResource::setType(
const vector<string> *resp_hdrs)
298 BESDEBUG(
"gateway",
"RemoteHttpResource::setType() - BEGIN" << endl);
310 vector<string>::const_iterator i = resp_hdrs->begin() ;
311 vector<string>::const_iterator e = resp_hdrs->end() ;
314 string hdr_line = (*i) ;
316 BESDEBUG(
"gateway",
"RemoteHttpResource::setType() - Evaluating header: " << hdr_line << endl);
320 string colon_space =
": ";
321 int index = hdr_line.find(colon_space);
322 string hdr_name = hdr_line.substr(0,index);
323 string hdr_value = hdr_line.substr(index + colon_space.length());
325 BESDEBUG(
"gateway",
"RemoteHttpResource::setType() - hdr_name: '" << hdr_name <<
"' hdr_value: '" <<hdr_value <<
"' "<< endl);
327 if( hdr_name.find(
"content-disposition" ) != string::npos )
330 BESDEBUG(
"gateway",
"RemoteHttpResource::setType() - Located content-disposition header." << endl);
333 if( hdr_name.find(
"content-type" ) != string::npos )
335 BESDEBUG(
"gateway",
"RemoteHttpResource::setType() - Located content-type header." << endl);
346 BESDEBUG(
"gateway",
"RemoteHttpResource::setType() - Evaluated content-disposition '" << disp
347 <<
"' matched type: \"" << type
355 if( type.empty() && !ctype.empty() )
358 BESDEBUG(
"gateway",
"RemoteHttpResource::setType() - Evaluated content-type '" << ctype <<
"' matched type \"" << type <<
"\"" << endl ) ;
366 BESDEBUG(
"gateway",
"RemoteHttpResource::setType() - Evaluated url '" << d_remoteResourceUrl
367 <<
"' matched type: \"" << type
374 string err = (string)
"RemoteHttpResource::setType() - Unable to determine the type of data"
375 +
" returned from '" + d_remoteResourceUrl +
"' Setting type to 'unknown'" ;
389 BESDEBUG(
"gateway",
"RemoteHttpResource::setType() - END" << endl);
virtual void unlock_cache()
Unlock the cache info file.
bool configureProxy(CURL *curl, const string &url)
Configure the proxy options for the passed curl object.
exception thrown if inernal error encountered
virtual bool create_and_lock(const string &target, int &fd)
Create a file in the cache and lock it for write access.
static string lowercase(const string &s)
Convert a string to all lower case.
static void Get_type_from_content_type(const string &ctype, string &type)
string http_status_to_string(int status)
This function translates an HTTP status code into an error messages.
static void Get_type_from_disposition(const string &disp, string &type)
Implementation of a caching mechanism for compressed data.
long read_url(CURL *curl, const string &url, int fd, vector< string > *resp_hdrs, const vector< string > *request_headers, char error_buffer[])
Use libcurl to dereference a URL.
CURL * init(char *error_buffer)
Get's a new instance of CURL* and performs basic configuration of that instance.
virtual bool cache_too_big(unsigned long long current_size) const
look at the cache size; is it too large? Look at the cache size and see if it is too big...
virtual string get_cache_file_name(const string &src, bool mangle=true)
Build the name of file that will holds the uncompressed data from 'src' in the cache.
virtual bool get_read_lock(const string &target, int &fd)
Get a read-only lock on the file if it exists.
virtual void update_and_purge(const string &new_file)
Purge files from the cache.
virtual unsigned long long update_cache_info(const string &target)
Update the cache info file to include 'target'.
static void Get_type_from_url(const string &url, string &type)
virtual void exclusive_to_shared_lock(int fd)
Transfer from an exclusive lock to a shared lock.
#define BESDEBUG(x, y)
macro used to send debug information to the debug stream
static BESKeys * TheKeys()
virtual void unlock_and_close(const string &target)
Unlock the named file.
static BESCache3 * get_instance()
Get an instance of the BESCache3 object.