43 #define CLIENT_ERR_MIN 400
44 #define CLIENT_ERR_MAX 417
48 "Unauthorized: Contact the server administrator.",
50 "Forbidden: Contact the server administrator.",
51 "Not Found: The data source or server could not be found.\n\
52 Often this means that the OPeNDAP server is missing or needs attention;\n\
53 Please contact the server administrator.",
54 "Method Not Allowed.",
56 "Proxy Authentication Required.",
61 "Precondition Failed.",
62 "Request Entity Too Large.",
63 "Request URI Too Large.",
64 "Unsupported Media Type.",
65 "Requested Range Not Satisfiable.",
69 #define SERVER_ERR_MIN 500
70 #define SERVER_ERR_MAX 505
73 "Internal Server Error.",
76 "Service Unavailable.",
78 "HTTP Version Not Supported."
91 return string(
"Unknown Error: This indicates a problem with libdap++.\nPlease report this to support@opendap.org.");
94 static string getCurlAuthTypeName(
const int authType){
96 string authTypeString;
99 match = authType & CURLAUTH_BASIC;
101 authTypeString +=
"CURLAUTH_BASIC";
104 match = authType & CURLAUTH_DIGEST;
106 if(!authTypeString.empty())
107 authTypeString +=
" ";
108 authTypeString +=
"CURLAUTH_DIGEST";
111 match = authType & CURLAUTH_DIGEST_IE;
113 if(!authTypeString.empty())
114 authTypeString +=
" ";
115 authTypeString +=
"CURLAUTH_DIGEST_IE";
118 match = authType & CURLAUTH_GSSNEGOTIATE;
120 if(!authTypeString.empty())
121 authTypeString +=
" ";
122 authTypeString +=
"CURLAUTH_GSSNEGOTIATE";
125 match = authType & CURLAUTH_NTLM;
127 if(!authTypeString.empty())
128 authTypeString +=
" ";
129 authTypeString +=
"CURLAUTH_NTLM";
133 match = authType & CURLAUTH_ANY;
135 if(!authTypeString.empty())
136 authTypeString +=
" ";
137 authTypeString +=
"CURLAUTH_ANY";
141 match = authType & CURLAUTH_ANY;
143 if(!authTypeString.empty())
144 authTypeString +=
" ";
145 authTypeString +=
"CURLAUTH_ANYSAFE";
149 match = authType & CURLAUTH_ANY;
151 if(!authTypeString.empty())
152 authTypeString +=
" ";
153 authTypeString +=
"CURLAUTH_ONLY";
157 return authTypeString;
165 static size_t writeToOpenfileDescriptor(
char *data,
size_t ,
size_t nmemb,
void *userdata){
167 int *fd = (
int *) userdata;
169 BESDEBUG(
"curl",
"curl_utils::writeToOpenfileDescriptor() - Bytes received " << libdap::long_to_string(nmemb) << endl);
170 int wrote = write(*fd, data, nmemb);
171 BESDEBUG(
"curl",
"curl_utils::writeToOpenfileDescriptor() - Bytes written " << libdap::long_to_string(wrote) << endl);
200 static size_t save_raw_http_headers(
void *ptr,
size_t size,
size_t nmemb,
void *resp_hdrs)
202 BESDEBUG(
"curl",
"curl_utils::save_raw_http_headers() - Inside the header parser." << endl);
203 vector<string> *hdrs =
static_cast<vector<string> *
>(resp_hdrs);
206 string complete_line;
207 if (nmemb > 1 && *(static_cast<char*>(ptr) + size * (nmemb - 2)) ==
'\r')
208 complete_line.assign(static_cast<char *>(ptr), size * (nmemb - 2));
210 complete_line.assign(static_cast<char *>(ptr), size * (nmemb - 1));
213 if (complete_line !=
"" && complete_line.find(
"HTTP") == string::npos) {
214 BESDEBUG(
"curl",
"curl_utils::save_raw_http_headers() - Header line: " << complete_line << endl);
215 hdrs->push_back(complete_line);
226 static int curl_debug(CURL *, curl_infotype info,
char *msg,
size_t size,
void *)
228 string message(msg, size);
232 BESDEBUG(
"curl",
"curl_utils::curl_debug() - Text: " << message << endl );
break;
233 case CURLINFO_HEADER_IN:
234 BESDEBUG(
"curl",
"curl_utils::curl_debug() - Header in: " << message << endl );
break;
235 case CURLINFO_HEADER_OUT:
236 BESDEBUG(
"curl",
"curl_utils::curl_debug() - Header out: " << endl << message << endl );
break;
237 case CURLINFO_DATA_IN:
238 BESDEBUG(
"curl",
"curl_utils::curl_debug() - Data in: " << message << endl );
break;
239 case CURLINFO_DATA_OUT:
240 BESDEBUG(
"curl",
"curl_utils::curl_debug() - Data out: " << message << endl );
break;
242 BESDEBUG(
"curl",
"curl_utils::curl_debug() - End: " << message << endl );
break;
243 #ifdef CURLINFO_SSL_DATA_IN
244 case CURLINFO_SSL_DATA_IN:
245 BESDEBUG(
"curl",
"curl_utils::curl_debug() - SSL Data in: " << message << endl );
break;
247 #ifdef CURLINFO_SSL_DATA_OUT
248 case CURLINFO_SSL_DATA_OUT:
249 BESDEBUG(
"curl",
"curl_utils::curl_debug() - SSL Data out: " << message << endl );
break;
252 BESDEBUG(
"curl",
"curl_utils::curl_debug() - Curl info: " << message << endl );
break;
265 class BuildHeaders :
public std::unary_function<const string &, void>
267 struct curl_slist *d_cl;
270 BuildHeaders() : d_cl(0)
273 void operator()(
const string &header)
275 BESDEBUG(
"curl",
"BuildHeaders::operator() - Adding '" << header.c_str() <<
"' to the header list." << endl);
276 d_cl = curl_slist_append(d_cl, header.c_str());
279 struct curl_slist *get_headers()
305 BESDEBUG(
"curl",
"curl_utils::configureProxy() - BEGIN." << endl);
307 bool using_proxy =
false;
320 if (!proxyHost.empty()) {
331 BESDEBUG(
"curl",
"curl_utils::configureProxy() - Found proxy configuration." << endl);
338 BESDEBUG(
"curl",
"curl_utils::configureProxy() - Found NoProxyRegex." << endl);
340 if (r.match(url.c_str(), url.length()) != -1) {
348 BESDEBUG(
"curl",
"curl_utils::configureProxy() - Setting up a proxy server." << endl);
349 BESDEBUG(
"curl",
"curl_utils::configureProxy() - Proxy host: " << proxyHost << endl);
350 BESDEBUG(
"curl",
"curl_utils::configureProxy() - Proxy port: " << proxyPort << endl);
352 curl_easy_setopt(curl, CURLOPT_PROXY, proxyHost.data());
353 curl_easy_setopt(curl, CURLOPT_PROXYPORT, proxyPort);
364 BESDEBUG(
"curl",
"curl_utils::configureProxy() - CURLOPT_PROXYAUTH = " << CURLOPT_PROXYAUTH << endl);
365 BESDEBUG(
"curl",
"curl_utils::configureProxy() - CURLAUTH_BASIC = " << CURLAUTH_BASIC << endl);
366 BESDEBUG(
"curl",
"curl_utils::configureProxy() - CURLAUTH_DIGEST = " << CURLAUTH_DIGEST << endl);
367 BESDEBUG(
"curl",
"curl_utils::configureProxy() - CURLAUTH_DIGEST_IE = " << CURLAUTH_DIGEST_IE << endl);
368 BESDEBUG(
"curl",
"curl_utils::configureProxy() - CURLAUTH_GSSNEGOTIATE = " << CURLAUTH_GSSNEGOTIATE << endl);
369 BESDEBUG(
"curl",
"curl_utils::configureProxy() - CURLAUTH_NTLM = " << CURLAUTH_NTLM << endl);
370 BESDEBUG(
"curl",
"curl_utils::configureProxy() - CURLAUTH_ANY = " << CURLAUTH_ANY << endl);
371 BESDEBUG(
"curl",
"curl_utils::configureProxy() - CURLAUTH_ANYSAFE = " << CURLAUTH_ANYSAFE << endl);
372 BESDEBUG(
"curl",
"curl_utils::configureProxy() - CURLAUTH_ONLY = " << CURLAUTH_ONLY << endl);
373 BESDEBUG(
"curl",
"curl_utils::configureProxy() - Using CURLOPT_PROXYAUTH = " << proxyAuthType << endl);
376 BESDEBUG(
"curl",
"curl_utils::configureProxy() - Using CURLOPT_PROXYAUTH = " << getCurlAuthTypeName(proxyAuthType) << endl);
377 curl_easy_setopt(curl, CURLOPT_PROXYAUTH, proxyAuthType);
382 if (!proxyUser.empty()){
383 curl_easy_setopt(curl, CURLOPT_PROXYUSERNAME, proxyUser.data());
384 BESDEBUG(
"curl",
"curl_utils::configureProxy() - CURLOPT_PROXYUSER : " << proxyUser << endl);
386 if (!proxyPassword.empty()){
387 curl_easy_setopt(curl, CURLOPT_PROXYPASSWORD, proxyPassword.data());
388 BESDEBUG(
"curl",
"curl_utils::configureProxy() - CURLOPT_PROXYPASSWORD: " << proxyPassword << endl);
391 else if (!proxyUserPW.empty()){
393 "curl_utils::configureProxy() - CURLOPT_PROXYUSERPWD : " << proxyUserPW << endl);
394 curl_easy_setopt(curl, CURLOPT_PROXYUSERPWD, proxyUserPW.data());
399 BESDEBUG(
"curl",
"curl_utils::configureProxy() - END." << endl);
429 CURL *curl = curl_easy_init();
431 throw libdap::InternalErr(__FILE__, __LINE__,
"Could not initialize libcurl.");
443 #ifndef CURLOPT_ACCEPT_ENCODING
444 curl_easy_setopt(curl, CURLOPT_ENCODING,
"");
446 curl_easy_setopt(curl, CURLOPT_ACCEPT_ENCODING,
"");
449 curl_easy_setopt(curl, CURLOPT_ERRORBUFFER, error_buffer);
452 curl_easy_setopt(curl, CURLOPT_FAILONERROR, 0);
457 curl_easy_setopt(curl, CURLOPT_HTTPAUTH, (
long)CURLAUTH_ANY);
459 curl_easy_setopt(curl, CURLOPT_NOPROGRESS, 1);
460 curl_easy_setopt(curl, CURLOPT_NOSIGNAL, 1);
461 curl_easy_setopt(curl, CURLOPT_HEADERFUNCTION, save_raw_http_headers);
466 curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1);
467 curl_easy_setopt(curl, CURLOPT_MAXREDIRS, 5);
471 curl_easy_setopt(curl, CURLOPT_USERAGENT, curl_version());
476 if (!d_rcr->get_validate_ssl() == 0) {
477 curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0);
478 curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 0);
485 if (!d_cookie_jar.empty()) {
486 BESDEBUG(cerr <<
"Setting the cookie jar to: " << d_cookie_jar << endl);
487 curl_easy_setopt(curl, CURLOPT_COOKIEJAR, d_cookie_jar.c_str());
488 curl_easy_setopt(curl, CURLOPT_COOKIESESSION, 1);
494 BESDEBUG(
"curl",
"curl_utils::www_lib_init() - Curl version: " << curl_version() << endl);
495 curl_easy_setopt(curl, CURLOPT_VERBOSE, 1);
496 BESDEBUG(
"curl",
"curl_utils::www_lib_init() - Curl in verbose mode."<< endl);
497 curl_easy_setopt(curl, CURLOPT_DEBUGFUNCTION, curl_debug);
498 BESDEBUG(
"curl",
"curl_utils::www_lib_init() - Curl debugging function installed."<< endl);
502 BESDEBUG(
"curl",
"curl_utils::www_lib_init() - curl: " << curl << endl);
530 vector<string> *resp_hdrs,
531 const vector<string> *request_headers,
535 BESDEBUG(
"curl",
"curl_utils::read_url() - BEGIN" << endl);
538 curl_easy_setopt(curl, CURLOPT_URL, url.c_str());
540 curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, writeToOpenfileDescriptor);
543 #ifdef CURLOPT_WRITEDATA
544 curl_easy_setopt(curl, CURLOPT_WRITEDATA, &fd);
546 curl_easy_setopt(curl, CURLOPT_FILE, &fd);
553 BuildHeaders req_hdrs;
557 req_hdrs = for_each(request_headers->begin(), request_headers->end(), req_hdrs);
558 curl_easy_setopt(curl, CURLOPT_HTTPHEADER, req_hdrs.get_headers());
564 curl_easy_setopt(curl, CURLOPT_WRITEHEADER, resp_hdrs);
567 CURLcode res = curl_easy_perform(curl);
570 curl_slist_free_all(req_hdrs.get_headers());
571 curl_easy_setopt(curl, CURLOPT_HTTPHEADER, 0);
575 BESDEBUG(
"curl",
"curl_utils::read_url() - OUCH! CURL returned an error! curl msg: " << curl_easy_strerror(res) << endl);
576 BESDEBUG(
"curl",
"curl_utils::read_url() - OUCH! CURL returned an error! error_buffer: " << error_buffer << endl);
577 throw libdap::Error(error_buffer);
581 res = curl_easy_getinfo(curl, CURLINFO_HTTP_CODE, &status);
582 BESDEBUG(
"curl",
"curl_utils::read_url() - HTTP Status " << status << endl);
584 throw libdap::Error(error_buffer);
585 BESDEBUG(
"curl",
"curl_utils::read_url() - END" << endl);
bool configureProxy(CURL *curl, const string &url)
Configure the proxy options for the passed curl object.
static string NoProxyRegex
const char * http_server_errors[SERVER_ERR_MAX-SERVER_ERR_MIN+1]
const char * http_client_errors[CLIENT_ERR_MAX-CLIENT_ERR_MIN+1]
string http_status_to_string(int status)
This function translates an HTTP status code into an error messages.
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.
#define BESDEBUG(x, y)
macro used to send debug information to the debug stream
static string ProxyUserPW
static string ProxyPassword