Github user wengyanqing commented on a diff in the pull request:

    https://github.com/apache/incubator-hawq/pull/1265#discussion_r126637139
  
    --- Diff: depends/libhdfs3/src/client/HttpClient.cpp ---
    @@ -0,0 +1,337 @@
    +/********************************************************************
    + * 2014 -
    + * open source under Apache License Version 2.0
    + ********************************************************************/
    +/**
    + * Licensed to the Apache Software Foundation (ASF) under one
    + * or more contributor license agreements.  See the NOTICE file
    + * distributed with this work for additional information
    + * regarding copyright ownership.  The ASF licenses this file
    + * to you under the Apache License, Version 2.0 (the
    + * "License"); you may not use this file except in compliance
    + * with the License.  You may obtain a copy of the License at
    + *
    + *     http://www.apache.org/licenses/LICENSE-2.0
    + *
    + * Unless required by applicable law or agreed to in writing, software
    + * distributed under the License is distributed on an "AS IS" BASIS,
    + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    + * See the License for the specific language governing permissions and
    + * limitations under the License.
    + */
    +
    +#include "HttpClient.h"
    +#include "Logger.h"
    +
    +using namespace Hdfs::Internal;
    +
    +namespace Hdfs {
    +
    +#define CURL_SETOPT(handle, option, optarg, fmt, ...) \
    +    res = curl_easy_setopt(handle, option, optarg); \
    +    if (res != CURLE_OK) { \
    +        THROW(HdfsIOException, fmt, ##__VA_ARGS__); \
    +    }
    +
    +#define CURL_SETOPT_ERROR1(handle, option, optarg, fmt) \
    +    CURL_SETOPT(handle, option, optarg, fmt, curl_easy_strerror(res));
    +
    +#define CURL_SETOPT_ERROR2(handle, option, optarg, fmt) \
    +    CURL_SETOPT(handle, option, optarg, fmt, curl_easy_strerror(res), \
    +        errorString().c_str())
    +
    +#define CURL_PERFORM(handle, fmt) \
    +    res = curl_easy_perform(handle); \
    +    if (res != CURLE_OK) { \
    +        THROW(HdfsIOException, fmt, curl_easy_strerror(res), 
errorString().c_str()); \
    +    }
    +
    +
    +#define CURL_GETOPT_ERROR2(handle, option, optarg, fmt) \
    +    res = curl_easy_getinfo(handle, option, optarg); \
    +    if (res != CURLE_OK) { \
    +        THROW(HdfsIOException, fmt, curl_easy_strerror(res), 
errorString().c_str()); \
    +    }
    +
    +#define CURL_GET_RESPONSE(handle, code, fmt) \
    +    CURL_GETOPT_ERROR2(handle, CURLINFO_RESPONSE_CODE, code, fmt);
    +
    +HttpClient::HttpClient() : curl(NULL), list(NULL) {
    +
    +}
    +
    +/**
    + * Construct a HttpClient instance.
    + * @param url a url which is the address to send the request to the 
corresponding http server.
    + */
    +HttpClient::HttpClient(const std::string &url) {
    +   curl = NULL;
    +   list = NULL;
    +   this->url = url;
    +}
    +
    +/**
    + * Destroy a HttpClient instance.
    + */
    +HttpClient::~HttpClient()
    +{
    +   destroy();
    +}
    +
    +/**
    + * Receive error string from curl.
    + */
    +std::string HttpClient::errorString() {
    +   if (strlen(errbuf) == 0)
    +           return "";
    +   return errbuf;
    +}
    +
    +/**
    + * Curl call back function to receive the reponse messages.
    + * @return return the size of reponse messages. 
    + */
    +size_t HttpClient::CurlWriteMemoryCallback(void *contents, size_t size, 
size_t nmemb, void *userp)
    +{
    +      size_t realsize = size * nmemb;
    +     if (userp == NULL || contents == NULL) {
    +             return 0;
    +     }
    +      ((std::string *)userp)->append((const char *)contents, realsize);
    +     LOG(DEBUG2, "HttpClient : Http response is : %s", ((std::string 
*)userp)->c_str());
    +      return realsize;
    +}
    +
    +/**
    + * Init curl handler and set curl options.
    + */
    +void HttpClient::init() {
    +   if (!initialized)
    +   {
    +           initialized = true;
    +           if (curl_global_init(CURL_GLOBAL_ALL)) {
    +                   THROW(HdfsIOException, "Cannot initialize curl client 
for KMS");
    +           }
    +   }
    +
    +   curl = curl_easy_init();
    +   if (!curl) {
    +           THROW(HdfsIOException, "Cannot initialize curl handle for KMS");
    +   }
    +   
    +    CURL_SETOPT_ERROR1(curl, CURLOPT_ERRORBUFFER, errbuf,
    +        "Cannot initialize curl error buffer for KMS: %s");
    +
    +    errbuf[0] = 0;
    +
    +    CURL_SETOPT_ERROR2(curl, CURLOPT_NOPROGRESS, 1,
    +        "Cannot initialize no progress in HttpClient: %s: %s");
    +
    +    CURL_SETOPT_ERROR2(curl, CURLOPT_VERBOSE, 0,
    +        "Cannot initialize no verbose in HttpClient: %s: %s");
    +
    +    CURL_SETOPT_ERROR2(curl, CURLOPT_COOKIEFILE, "",
    +        "Cannot initialize cookie behavior in HttpClient: %s: %s");
    +
    +    CURL_SETOPT_ERROR2(curl, CURLOPT_HTTPHEADER, list,
    +        "Cannot initialize headers in HttpClient: %s: %s");
    +
    +    CURL_SETOPT_ERROR2(curl, CURLOPT_WRITEFUNCTION, 
HttpClient::CurlWriteMemoryCallback,
    +        "Cannot initialize body reader in HttpClient: %s: %s");
    +
    +    CURL_SETOPT_ERROR2(curl, CURLOPT_WRITEDATA, (void *)&response,
    +        "Cannot initialize body reader data in HttpClient: %s: %s");
    +
    +    /* Some servers don't like requests that are made without a user-agent
    +        field, so we provide one */
    +    CURL_SETOPT_ERROR2(curl, CURLOPT_USERAGENT, "libcurl-agent/1.0",
    +        "Cannot initialize user agent in HttpClient: %s: %s");
    +   list = NULL;
    +
    +}
    +
    +/**
    + * Do clean up for curl.
    + */
    +void HttpClient::destroy() {
    +   if (curl) {
    +           curl_easy_cleanup(curl);
    +   }
    +   if (list) {
    +           curl_slist_free_all(list);
    +   }
    +}
    +
    +/**
    + * Set url for http client.
    + */
    +void HttpClient::setURL(const std::string &url) {
    +   this->url = url;
    +}
    +
    +/**
    + * Set retry times for http request which can be configured in config file.
    + */
    +void HttpClient::setRequestRetryTimes(int request_retry_times) {
    +   if (request_retry_times < 0) {
    +           THROW(InvalidParameter, "HttpClient : Invalid value for 
request_retry_times.");
    +   }
    +   this->request_retry_times = request_retry_times;
    +}
    +
    +/**
    + * Set request timeout which can be configured in config file.
    + */
    +void HttpClient::setRequestTimeout(int64_t curl_timeout) {
    +   if (curl_timeout < 0) {
    +           THROW(InvalidParameter, "HttpClient : Invalid value for 
curl_timeout.");
    +   }
    +   this->curl_timeout = curl_timeout;
    +}
    +
    +/**
    + * Set headers for http client.
    + */
    +void HttpClient::setHeaders(const std::vector<std::string> &headers) {
    +   if (!headers.empty()) {
    +           this->headers = headers;
    +           for (std::string header : headers) {
    +                   list = curl_slist_append(list, header.c_str());
    +                   if (!list) {
    +                           THROW(HdfsIOException, "Cannot add header in 
HttpClient.");
    +                   }
    +           }       
    +   }
    +   else {
    +           LOG(DEBUG1, "HttpClient : Header is empty.");                   
        
    +   }
    +}
    +
    +
    +/**
    + * Set body for http client.
    + */
    +void HttpClient::setBody(const std::string &body) {
    +   this->body = body;
    +}
    +
    +/**
    + * Set expected response code.
    + */
    +void HttpClient::setExpectedResponseCode(int64_t response_code_ok) {
    +   this->response_code_ok = response_code_ok;
    +}
    +
    +/**
    + * Http common method to get response info by sending request to http 
server.
    + * @param method : define different http methods.
    + * @return return response info.
    + */
    +std::string HttpClient::httpCommon(httpMethod method) {
    +   
    +    /* Set headers and url. */
    +   if (list != NULL) {
    +           CURL_SETOPT_ERROR2(curl, CURLOPT_HTTPHEADER, list,
    +                   "Cannot initialize headers in HttpClient: %s: %s");
    +   } else {
    +           LOG(DEBUG1, "HttpClient : Http Header is NULL");
    +   }
    +
    +   if (curl != NULL) {
    +           CURL_SETOPT_ERROR2(curl, CURLOPT_URL, url.c_str(),
    +                   "Cannot initialize url in HttpClient: %s: %s");
    +   } else {
    +           LOG(DEBUG1, "HttpClient : Http URL is NULL");
    --- End diff --
    
    It should be error if URL is NULL


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastruct...@apache.org or file a JIRA ticket
with INFRA.
---

Reply via email to