コード例 #1
0
ファイル: CurlHttpClient.cpp プロジェクト: nomadbyte/fredcpp
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());
}
コード例 #2
0
ファイル: Api.cpp プロジェクト: fpcMotif/fredcpp
bool Api::get(const ApiRequest& request, ApiResponse& response) {

  response.clear();

  // validate
  bool requireValidExecutor(executor_ != NULL);
  if (!requireValidExecutor) {
    assert(requireValidExecutor && "Valid HttpRequestExecutor implementation expected.");
    response.setError( FatalInternalError("Api Executor is not set.") );
    return (response.good());
  }

  bool requireValidParser(parser_ != NULL);
  if (!requireValidParser) {
    assert(requireValidParser && "Valid XmlResponseParser implementation expected.");
    response.setError( FatalInternalError("Api Parser is not set.") );
    return (response.good());
  }

  FREDCPP_LOG_DEBUG("request:" << request);


  // prepare request (ApiRequest >> HttpRequest)

  std::string URI(std::string(apiURI_).append("/").append(request.getPath()));

  internal::HttpRequest httpRequest(URI, request);
  httpRequest.with(FRED_PARAM_API_KEY, apiKey_);
  if (!apiFileType_.empty()) {
    httpRequest.with(FRED_PARAM_FILE_TYPE, apiFileType_);
  }

  FREDCPP_LOG_DEBUG("http-request:" << httpRequest);


  // execute request

  internal::HttpResponse httpResponse;

  executor_->execute(httpRequest, httpResponse);

  if (!httpResponse.isXmlContent()) {
    response.setError( ErrorHttpRequestFailed(request, httpRequest, httpResponse) );
    FREDCPP_LOG_ERROR( response.error.message);

    return (response.good());
  }

  // process response

  //std::ofstream os("fred_dbg.bin",std::ifstream::binary);
  //os << httpResponse.getContentStream().str();

  std::istringstream xmlContent(httpResponse.getContentStream().str());

  FREDCPP_LOG_DEBUG("http-response:" << httpResponse.getHttpStatus()
                    << " " << "content-type:" << httpResponse.getContentType());

  FREDCPP_LOG_DBGN(2, "content:{\n" << xmlContent.str() << "\n}");

  if ( !parser_->parse(xmlContent, response) ) {
    response.setError( ErrorXmlParseFailed(request, xmlContent) );
    FREDCPP_LOG_ERROR( response.error.message );

    return (response.good());
  }

  response.setErrorFromResult();

  //TOADD:FREDCPP_LOG_INFO(response.result, timed)

  return ( response.good() );
}