Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -8,3 +8,5 @@ gensrc/build
fe/target
thirdparty/src
*.so.tmp
.DS_Store
*.iml
20 changes: 20 additions & 0 deletions be/src/http/http_client.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,10 @@ HttpClient::~HttpClient() {
curl_easy_cleanup(_curl);
_curl = nullptr;
}
if(_header_list != nullptr) {
curl_slist_free_all(_header_list);
_header_list = nullptr;
}
}

Status HttpClient::init(const std::string& url) {
Expand All @@ -39,6 +43,10 @@ Status HttpClient::init(const std::string& url) {
curl_easy_reset(_curl);
}

if(_header_list != nullptr) {
curl_slist_free_all(_header_list);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

_header_list = nullptr

_header_list = nullptr;
}
// set error_buf
_error_buf[0] = 0;
auto code = curl_easy_setopt(_curl, CURLOPT_ERRORBUFFER, _error_buf);
Expand Down Expand Up @@ -131,6 +139,18 @@ size_t HttpClient::on_response_data(const void* data, size_t length) {
return length;
}

// Status HttpClient::execute_post_request(const std::string& post_data, const std::function<bool(const void* data, size_t length)>& callback = {}) {
// _callback = &callback;
// set_post_body(post_data);
// return execute(callback);
// }

Status HttpClient::execute_post_request(const std::string& post_data, std::string* response) {
set_method(POST);
set_post_body(post_data);
return execute(response);
}

Status HttpClient::execute(const std::function<bool(const void* data, size_t length)>& callback) {
_callback = &callback;
auto code = curl_easy_perform(_curl);
Expand Down
24 changes: 23 additions & 1 deletion be/src/http/http_client.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@
#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
Expand Down Expand Up @@ -54,6 +54,19 @@ class HttpClient {
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);
}

// you must set CURLOPT_POSTFIELDSIZE before CURLOPT_COPYPOSTFIELDS options, otherwise will cause request hanging up
void set_post_body(const std::string& post_body) {
curl_easy_setopt(_curl, CURLOPT_POSTFIELDSIZE, (long)post_body.length());
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

post_body.data(), post_body.size()

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);
Expand Down Expand Up @@ -85,6 +98,12 @@ class HttpClient {
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);
Expand All @@ -95,6 +114,8 @@ class HttpClient {
// a file to local_path
Status download(const std::string& local_path);

Status execute_post_request(const std::string& post_data, std::string* response);

// execute a simple method, and its response is saved in response argument
Status execute(std::string* response);

Expand All @@ -111,6 +132,7 @@ class HttpClient {
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;
};

}
39 changes: 38 additions & 1 deletion be/test/http/http_client_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,28 @@ class HttpClientTestSimpleGetHandler : public HttpHandler {
}
};

class HttpClientTestSimplePostHandler : public HttpHandler {
public:
void handle(HttpRequest* req) override {
std::string user;
std::string passwd;
if (!parse_basic_auth(*req, &user, &passwd) || user != "test1") {
HttpChannel::send_basic_challenge(req, "abc");
return;
}
if (req->method() == HttpMethod::POST) {
std::string post_body = req->get_request_body();
if (!post_body.empty()) {
HttpChannel::send_reply(req, post_body);
} else {
HttpChannel::send_reply(req, "empty");
}
}
}
};

static HttpClientTestSimpleGetHandler s_simple_get_handler = HttpClientTestSimpleGetHandler();
static HttpClientTestSimplePostHandler s_simple_post_handler = HttpClientTestSimplePostHandler();
static EvHttpServer* s_server = nullptr;

class HttpClientTest : public testing::Test {
Expand All @@ -59,6 +80,7 @@ class HttpClientTest : public testing::Test {
s_server = new EvHttpServer(29386);
s_server->register_handler(GET, "/simple_get", &s_simple_get_handler);
s_server->register_handler(HEAD, "/simple_get", &s_simple_get_handler);
s_server->register_handler(POST, "/simple_post", &s_simple_post_handler);
s_server->start();
}

Expand Down Expand Up @@ -109,9 +131,24 @@ TEST_F(HttpClientTest, get_failed) {
auto st = client.init("http://127.0.0.1:29386/simple_get");
ASSERT_TRUE(st.ok());
client.set_method(GET);
client.set_basic_auth("test1", "");
std::string response;
st = client.execute(&response);
ASSERT_FALSE(st.ok());
ASSERT_FALSE(!st.ok());
}

TEST_F(HttpClientTest, post_normal) {
HttpClient client;
auto st = client.init("http://127.0.0.1:29386/simple_post");
ASSERT_TRUE(st.ok());
client.set_method(POST);
client.set_basic_auth("test1", "");
std::string response;
std::string request_body = "simple post body query";
st = client.execute_post_request(request_body, &response);
ASSERT_TRUE(st.ok());
ASSERT_EQ(response.length(), request_body.length());
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ASSERT_STRCMP(.c_str(), .c_str())

ASSERT_STREQ(response.c_str(), request_body.c_str());
}

}
Expand Down