blob: d54bc680d33aaf57672408b401e0dd7ae4abcf45 [file] [log] [blame]
// 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.
#pragma once
#include <cstdio>
#include <string>
#include <curl/curl.h>
#include "common/status.h"
#include "http/http_headers.h"
#include "http/http_method.h"
#include "http/utils.h"
#include "http/http_response.h"
namespace doris {
// Helper class to access HTTP resource
class HttpClient {
public:
HttpClient();
~HttpClient();
// you can call this function to execute HTTP request with retry,
// if callback return OK, this function will end and return OK.
// This function will return FAIL if three are more than retry_times
// that callback return FAIL.
static Status execute_with_retry(int retry_times, int sleep_time,
const std::function<Status(HttpClient*)>& callback);
// this function must call before other function,
// you can call this multiple times to reuse this object
Status init(const std::string& url);
void set_method(HttpMethod method);
void set_basic_auth(const std::string& user, const std::string& passwd) {
curl_easy_setopt(_curl, CURLOPT_HTTPAUTH, CURLAUTH_BASIC);
curl_easy_setopt(_curl, CURLOPT_USERNAME, user.c_str());
curl_easy_setopt(_curl, CURLOPT_PASSWORD, passwd.c_str());
}
// content_type such as "application/json"
void set_content_type(const std::string content_type) {
std::string scratch_str = "Content-Type: " + content_type;
_header_list = curl_slist_append(_header_list, scratch_str.c_str());
curl_easy_setopt(_curl, CURLOPT_HTTPHEADER, _header_list);
}
void set_payload(const std::string& post_body) {
curl_easy_setopt(_curl, CURLOPT_POSTFIELDSIZE, (long)post_body.length());
curl_easy_setopt(_curl, CURLOPT_COPYPOSTFIELDS, post_body.c_str());
}
// TODO(zc): support set header
// void set_header(const std::string& key, const std::string& value) {
// _cntl.http_request().SetHeader(key, value);
// }
std::string get_response_content_type() {
char *ct = nullptr;
auto code = curl_easy_getinfo(_curl, CURLINFO_CONTENT_TYPE, &ct);
if(code == CURLE_OK && ct != nullptr) {
return ct;
}
return std::string();
}
// Set the long gohead parameter to 1L to continue send authentication (user+password)
// credentials when following locations, even when hostname changed.
void set_unrestricted_auth(int gohead) {
curl_easy_setopt(_curl, CURLOPT_UNRESTRICTED_AUTH, gohead);
}
void set_timeout_ms(int64_t timeout_ms) {
curl_easy_setopt(_curl, CURLOPT_TIMEOUT_MS, timeout_ms);
}
// used to get content length
int64_t get_content_length() const {
double cl = 0.0f;
curl_easy_getinfo(_curl, CURLINFO_CONTENT_LENGTH_DOWNLOAD, &cl);
return cl;
}
long get_http_status() const {
long code;
curl_easy_getinfo(_curl, CURLINFO_RESPONSE_CODE, &code);
return code;
}
// execute a head method
Status head() {
set_method(HEAD);
return execute();
}
// helper function to download a file, you can call this function to downlaod
// a file to local_path
Status download(const std::string& local_path);
Status execute_post_request(const std::string& payload, std::string* response);
Status execute_delete_request(const std::string& payload, std::string* response);
// execute a simple method, and its response is saved in response argument
Status execute(std::string* response);
// execute remote call action
Status execute(const std::function<bool(const void* data, size_t length)>& callback = {});
size_t on_response_data(const void* data, size_t length);
private:
const char* _to_errmsg(CURLcode code);
private:
CURL* _curl = nullptr;
using HttpCallback = std::function<bool(const void* data, size_t length)>;
const HttpCallback* _callback = nullptr;
char _error_buf[CURL_ERROR_SIZE];
curl_slist *_header_list = nullptr;
};
}