Example #1
0
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();
}
Example #2
0
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());
}