ErrorHttpRequestFailed::ErrorHttpRequestFailed(const ApiRequest& request, const internal::HttpRequest& httpRequest, const internal::HttpResponse& httpResponse) : ApiError() { status = FREDCPP_FAIL_HTTP; std::ostringstream buf; buf << "Bad Response." << " " << " Could not connect to API URI or received unexpected content type." << " http-status:" << httpResponse.getHttpStatus() << " content-type:" << httpResponse.getContentType() << " http-request:" << httpRequest ; message = buf.str(); buf.str(""); buf << httpResponse.getHttpStatus(); code = buf.str(); }
bool CurlHttpClient::execute(const internal::HttpRequest& request, internal::HttpResponse& response) { CURLStatus_ = CURLE_FAILED_INIT; errorBuf_[0] = '\0'; bool retry(false); unsigned retryCount(0); response.clear(); CURL* curl = curl_easy_init(); if (NULL == curl) { return (internal::HttpResponse::HTTP_OK == response.getHttpStatus()); } std::string URI(getRequestString(request)); FREDCPP_LOG_DEBUG("CURL:URI:" << URI); if (!CACertFile_.empty()) { std::ifstream ifs(CACertFile_.c_str()); FREDCPP_LOG_DEBUG("CURL:CACertFile:" << CACertFile_ << " found:" << ifs.good()); } if (CURLE_OK == (CURLStatus_ = curl_easy_setopt(curl, CURLOPT_USERAGENT, userAgent_.c_str())) && CURLE_OK == (CURLStatus_ = curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, writeDataCallback_)) && CURLE_OK == (CURLStatus_ = curl_easy_setopt(curl, CURLOPT_NOPROGRESS, 1L)) && CURLE_OK == (CURLStatus_ = curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1L)) && CURLE_OK == (CURLStatus_ = curl_easy_setopt(curl, CURLOPT_FILE, &response.getContentStream())) && CURLE_OK == (CURLStatus_ = curl_easy_setopt(curl, CURLOPT_TIMEOUT, timeoutSecs_)) && CURLE_OK == (CURLStatus_ = curl_easy_setopt(curl, CURLOPT_URL, URI.c_str())) && CURLE_OK == (CURLStatus_ = curl_easy_setopt(curl, CURLOPT_ERRORBUFFER, errorBuf_)) && (!request.isHttps() || CURLE_OK == (CURLStatus_ = curl_easy_setopt(curl, CURLOPT_CAINFO, CACertFile_.c_str()))) ) { do { CURLStatus_ = curl_easy_perform(curl); if (CURLE_OK == CURLStatus_) { // on successfull call get http-status and content-type long code(0L); char *strInfo(NULL); if (CURLE_OK == curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &code) && CURLE_OK == curl_easy_getinfo(curl, CURLINFO_CONTENT_TYPE, &strInfo)) { response.setHttpStatus(httpStatusFromCode(code)); response.setContentType(strInfo); } } else { FREDCPP_LOG_DEBUG("CURL:Request failed CURLStatus:" << CURLStatus_ << "|" << errorBuf_); } retry = (CURLE_OPERATION_TIMEDOUT == CURLStatus_ || CURLE_COULDNT_RESOLVE_HOST == CURLStatus_ || CURLE_COULDNT_RESOLVE_PROXY == CURLStatus_ || CURLE_COULDNT_CONNECT == CURLStatus_); if (retry) { if (retryCount < retryMaxCount_) { ++retryCount; FREDCPP_LOG_DEBUG("CURL:Waiting " << retryWaitSecs_ << "ms" << " before request retry " << retryCount << " ..."); internal::sleep(retryWaitSecs_); } else { retry = false; FREDCPP_LOG_DEBUG("CURL:Retry maximum count " << retryMaxCount_ << " reached - giving up."); } } } while (retry); } if (CURLE_OK == CURLStatus_) { FREDCPP_LOG_DEBUG("CURL:http-response:" << response.getHttpStatus() << " " << "content-type:" << response.getContentType()); } curl_easy_cleanup(curl); return (internal::HttpResponse::HTTP_OK == response.getHttpStatus()); }