32 #include "BESInternalError.h"
37 #include "GatewayCache.h"
38 #include "GatewayUtils.h"
39 #include "curl_utils.h"
40 #include "RemoteHttpResource.h"
43 using namespace gateway;
50 RemoteHttpResource::RemoteHttpResource(
const string &url)
52 d_initialized =
false;
56 d_resourceCacheFileName.clear();
57 d_response_headers =
new vector<string>();
58 d_request_headers =
new vector<string>();
61 string err =
"RemoteHttpResource(): Remote resource URL is empty";
65 d_remoteResourceUrl = url;
67 BESDEBUG(
"gateway",
"RemoteHttpResource() - URL: " << d_remoteResourceUrl << endl);
76 d_curl = init(d_error_buffer);
78 configureProxy(d_curl, d_remoteResourceUrl);
80 BESDEBUG(
"gateway",
"RemoteHttpResource() - d_curl: " << d_curl << endl);
82 RemoteHttpResource::~RemoteHttpResource()
88 BESDEBUG(
"gateway",
"~RemoteHttpResource() - BEGIN resourceURL: " << d_remoteResourceUrl << endl);
90 delete d_response_headers;
91 d_response_headers = 0;
92 BESDEBUG(
"gateway",
"~RemoteHttpResource() - Deleted d_response_headers." << endl);
94 delete d_request_headers;
95 d_request_headers = 0;
96 BESDEBUG(
"gateway",
"~RemoteHttpResource() - Deleted d_request_headers." << endl);
98 if (!d_resourceCacheFileName.empty()) {
102 BESDEBUG(
"gateway",
"~RemoteHttpResource() - Closed and unlocked "<< d_resourceCacheFileName << endl);
103 d_resourceCacheFileName.clear();
108 curl_easy_cleanup(d_curl);
109 BESDEBUG(
"gateway",
"~RemoteHttpResource() - Called curl_easy_cleanup()." << endl);
113 BESDEBUG(
"gateway",
"~RemoteHttpResource() - END resourceURL: " << d_remoteResourceUrl << endl);
114 d_remoteResourceUrl.clear();
124 void RemoteHttpResource::retrieveResource()
127 "RemoteHttpResource::retrieveResource() - BEGIN resourceURL: " << d_remoteResourceUrl << endl);
130 BESDEBUG(
"gateway",
"RemoteHttpResource::retrieveResource() - END Already initialized." << endl);
138 oss << __func__ <<
"() - FAILED to get local cache."
139 " Unable to proceed with request for " << this->d_remoteResourceUrl
140 <<
" The gateway_module MUST have a valid cache configuration to operate." << endl;
141 BESDEBUG(
"gateway", oss.str());
149 "RemoteHttpResource::retrieveResource() - d_resourceCacheFileName: " << d_resourceCacheFileName << endl);
157 GatewayUtils::Get_type_from_url(d_remoteResourceUrl, d_type);
158 BESDEBUG(
"gateway",
"RemoteHttpResource::retrieveResource() - d_type: " << d_type << endl);
164 "RemoteHttpResource::retrieveResource() - Remote resource is already in cache. cache_file_name: " << d_resourceCacheFileName << endl);
165 d_initialized =
true;
176 writeResourceToFile(d_fd);
180 unlink(d_resourceCacheFileName.c_str());
194 "RemoteHttpResource::retrieveResource() - Converted exclusive cache lock to shared lock." << endl);
200 BESDEBUG(
"gateway",
"RemoteHttpResource::retrieveResource() - Updated cache info" << endl);
204 BESDEBUG(
"gateway",
"RemoteHttpResource::retrieveResource() - Updated and purged cache." << endl);
207 BESDEBUG(
"gateway",
"RemoteHttpResource::retrieveResource() - END" << endl);
209 d_initialized =
true;
216 "RemoteHttpResource::retrieveResource() - Remote resource is in cache. cache_file_name: " << d_resourceCacheFileName << endl);
217 d_initialized =
true;
222 string msg =
"RemoteHttpResource::retrieveResource() - Failed to acquire cache read lock for remote resource: '";
223 msg += d_remoteResourceUrl +
"\n";
224 throw libdap::Error(msg);
229 "RemoteHttpResource::retrieveResource() - Caught exception, unlocking cache and re-throw." << endl);
244 void RemoteHttpResource::writeResourceToFile(
int fd)
246 BESDEBUG(
"gateway",
"RemoteHttpResource::writeResourceToFile() - BEGIN" << endl);
251 "RemoteHttpResource::writeResourceToFile() - Saving resource " << d_remoteResourceUrl <<
" to cache file " << d_resourceCacheFileName << endl);
252 status = read_url(d_curl, d_remoteResourceUrl, fd, d_response_headers, d_request_headers,
256 "RemoteHttpResource::writeResourceToFile() - HTTP returned an error status: " << status << endl);
258 string msg =
"Error while reading the URL: '";
259 msg += d_remoteResourceUrl;
260 msg +=
"'The HTTP request returned a status of " + libdap::long_to_string(status) +
" which means '";
261 msg += http_status_to_string(status) +
"' \n";
262 throw libdap::Error(msg);
265 "RemoteHttpResource::writeResourceToFile() - Resource " << d_remoteResourceUrl <<
" saved to cache file " << d_resourceCacheFileName << endl);
271 int status = lseek(fd, 0, SEEK_SET);
273 throw BESError(
"Could not seek within the response.", BES_NOT_FOUND_ERROR, __FILE__, __LINE__);
275 BESDEBUG(
"gateway",
"RemoteHttpResource::writeResourceToFile() - Reset file descriptor." << endl);
278 setType(d_response_headers);
280 catch (libdap::Error &e) {
283 BESDEBUG(
"gateway",
"RemoteHttpResource::writeResourceToFile() - END" << endl);
286 void RemoteHttpResource::setType(
const vector<string> *resp_hdrs)
289 BESDEBUG(
"gateway",
"RemoteHttpResource::setType() - BEGIN" << endl);
299 vector<string>::const_iterator i = resp_hdrs->begin();
300 vector<string>::const_iterator e = resp_hdrs->end();
301 for (; i != e; i++) {
302 string hdr_line = (*i);
304 BESDEBUG(
"gateway",
"RemoteHttpResource::setType() - Evaluating header: " << hdr_line << endl);
308 string colon_space =
": ";
309 int index = hdr_line.find(colon_space);
310 string hdr_name = hdr_line.substr(0, index);
311 string hdr_value = hdr_line.substr(index + colon_space.length());
314 "RemoteHttpResource::setType() - hdr_name: '" << hdr_name <<
"' hdr_value: '" <<hdr_value <<
"' "<< endl);
316 if (hdr_name.find(
"content-disposition") != string::npos) {
318 BESDEBUG(
"gateway",
"RemoteHttpResource::setType() - Located content-disposition header." << endl);
321 if (hdr_name.find(
"content-type") != string::npos) {
322 BESDEBUG(
"gateway",
"RemoteHttpResource::setType() - Located content-type header." << endl);
331 GatewayUtils::Get_type_from_disposition(disp, type);
333 "RemoteHttpResource::setType() - Evaluated content-disposition '" << disp <<
"' matched type: \"" << type <<
"\"" << endl);
340 if (type.empty() && !ctype.empty()) {
341 GatewayUtils::Get_type_from_content_type(ctype, type);
343 "RemoteHttpResource::setType() - Evaluated content-type '" << ctype <<
"' matched type \"" << type <<
"\"" << endl);
349 GatewayUtils::Get_type_from_url(d_remoteResourceUrl, type);
351 "RemoteHttpResource::setType() - Evaluated url '" << d_remoteResourceUrl <<
"' matched type: \"" << type <<
"\"" << endl);
356 string err = (string)
"RemoteHttpResource::setType() - Unable to determine the type of data"
357 +
" returned from '" + d_remoteResourceUrl +
"' Setting type to 'unknown'";
358 BESDEBUG(
"gateway", err);
368 BESDEBUG(
"gateway",
"RemoteHttpResource::setType() - END" << endl);