timeout support when create client or make request
This commit is contained in:
@@ -20,12 +20,7 @@
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include <iostream>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
|
||||
using namespace std;
|
||||
|
||||
namespace AlibabaCloud {
|
||||
|
||||
@@ -56,7 +51,6 @@ static size_t readCallback(void *ptr, size_t size, size_t nmemb, void *stream) {
|
||||
return len;
|
||||
}
|
||||
|
||||
|
||||
size_t recvBody(char *ptr, size_t size, size_t nmemb, void *userdata) {
|
||||
std::ostringstream &out = *static_cast<std::ostringstream*>(userdata);
|
||||
out << std::string(ptr, nmemb*size);
|
||||
@@ -120,49 +114,52 @@ CurlHttpClient::makeRequest(const HttpRequest &request) {
|
||||
curl_easy_reset(curlHandle_);
|
||||
HttpResponse response(request);
|
||||
|
||||
long connect_timeout = request.connectTimeout();
|
||||
long read_timeout = request.readTimeout();
|
||||
|
||||
std::string url = request.url().toString();
|
||||
switch (request.method()) {
|
||||
case HttpRequest::Method::Get:
|
||||
break;
|
||||
case HttpRequest::Method::Post: {
|
||||
if (request.bodySize() > 0) {
|
||||
curl_easy_setopt(curlHandle_, CURLOPT_POSTFIELDS, request.body());
|
||||
} else {
|
||||
curl_easy_setopt(curlHandle_, CURLOPT_POSTFIELDS, "");
|
||||
case HttpRequest::Method::Get:
|
||||
break;
|
||||
case HttpRequest::Method::Post: {
|
||||
if (request.bodySize() > 0) {
|
||||
curl_easy_setopt(curlHandle_, CURLOPT_POSTFIELDS, request.body());
|
||||
} else {
|
||||
curl_easy_setopt(curlHandle_, CURLOPT_POSTFIELDS, "");
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
break;
|
||||
|
||||
case HttpRequest::Method::Put: {
|
||||
uploadContext* ctx = (uploadContext *)malloc(sizeof(uploadContext));
|
||||
// this is impossible, as the size is 24 Bytes
|
||||
if (ctx == nullptr) {
|
||||
return HttpResponseOutcome(
|
||||
Error("MemoryAllocateError",
|
||||
"There is not enough memory for http transfer."));
|
||||
case HttpRequest::Method::Put: {
|
||||
uploadContext* ctx = (uploadContext *)malloc(sizeof(uploadContext));
|
||||
// this is impossible, as the size is 24 Bytes
|
||||
if (ctx == nullptr) {
|
||||
return HttpResponseOutcome(
|
||||
Error("MemoryAllocateError",
|
||||
"There is not enough memory for http transfer."));
|
||||
}
|
||||
ctx->data = request.body();
|
||||
ctx->pos = request.body();
|
||||
ctx->last = ctx->pos + request.bodySize();
|
||||
|
||||
curl_easy_setopt(curlHandle_, CURLOPT_READFUNCTION, readCallback);
|
||||
curl_easy_setopt(curlHandle_, CURLOPT_UPLOAD, 1L);
|
||||
curl_easy_setopt(curlHandle_, CURLOPT_READDATA, ctx);
|
||||
}
|
||||
ctx->data = request.body();
|
||||
ctx->pos = request.body();
|
||||
ctx->last = ctx->pos + request.bodySize();
|
||||
break;
|
||||
|
||||
curl_easy_setopt(curlHandle_, CURLOPT_READFUNCTION, readCallback);
|
||||
curl_easy_setopt(curlHandle_, CURLOPT_UPLOAD, 1L);
|
||||
curl_easy_setopt(curlHandle_, CURLOPT_READDATA, ctx);
|
||||
}
|
||||
break;
|
||||
|
||||
case HttpRequest::Method::Delete: {
|
||||
curl_easy_setopt(curlHandle_, CURLOPT_CUSTOMREQUEST, "DELETE");
|
||||
if (request.bodySize() > 0) {
|
||||
curl_easy_setopt(curlHandle_, CURLOPT_POSTFIELDS, request.body());
|
||||
} else {
|
||||
curl_easy_setopt(curlHandle_, CURLOPT_POSTFIELDS, "");
|
||||
case HttpRequest::Method::Delete: {
|
||||
curl_easy_setopt(curlHandle_, CURLOPT_CUSTOMREQUEST, "DELETE");
|
||||
if (request.bodySize() > 0) {
|
||||
curl_easy_setopt(curlHandle_, CURLOPT_POSTFIELDS, request.body());
|
||||
} else {
|
||||
curl_easy_setopt(curlHandle_, CURLOPT_POSTFIELDS, "");
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
curl_easy_setopt(curlHandle_, CURLOPT_URL, url.c_str());
|
||||
@@ -171,6 +168,14 @@ CurlHttpClient::makeRequest(const HttpRequest &request) {
|
||||
curl_easy_setopt(curlHandle_, CURLOPT_HEADERDATA, &response);
|
||||
curl_easy_setopt(curlHandle_, CURLOPT_HEADERFUNCTION, recvHeaders);
|
||||
|
||||
if (connect_timeout > 0) {
|
||||
curl_easy_setopt(curlHandle_, CURLOPT_CONNECTTIMEOUT_MS, connect_timeout);
|
||||
}
|
||||
|
||||
if (read_timeout > 0) {
|
||||
curl_easy_setopt(curlHandle_, CURLOPT_TIMEOUT_MS, read_timeout);
|
||||
}
|
||||
|
||||
curl_slist *list = nullptr;
|
||||
auto headers = request.headers();
|
||||
for (const auto &p : headers) {
|
||||
@@ -190,22 +195,31 @@ CurlHttpClient::makeRequest(const HttpRequest &request) {
|
||||
|
||||
CURLcode res = curl_easy_perform(curlHandle_);
|
||||
switch (res) {
|
||||
case CURLE_OK: {
|
||||
long response_code;
|
||||
curl_easy_getinfo(curlHandle_, CURLINFO_RESPONSE_CODE, &response_code);
|
||||
response.setStatusCode(response_code);
|
||||
response.setBody(out.str().c_str(), out.str().length());
|
||||
return HttpResponseOutcome(response);
|
||||
}
|
||||
case CURLE_SSL_CONNECT_ERROR:
|
||||
return HttpResponseOutcome(
|
||||
Error("SSLConnectError",
|
||||
"A problem occurred somewhere in the SSL/TLS handshake."));
|
||||
default:
|
||||
return HttpResponseOutcome(
|
||||
Error("NetworkError",
|
||||
"Failed to connect to host or proxy: " +
|
||||
HttpMethodToString(request.method()) + " " + request.url().toString()));
|
||||
case CURLE_OK: {
|
||||
long response_code;
|
||||
curl_easy_getinfo(curlHandle_, CURLINFO_RESPONSE_CODE, &response_code);
|
||||
response.setStatusCode(response_code);
|
||||
response.setBody(out.str().c_str(), out.str().length());
|
||||
return HttpResponseOutcome(response);
|
||||
}
|
||||
case CURLE_SSL_CONNECT_ERROR:
|
||||
return HttpResponseOutcome(
|
||||
Error("SSLConnectError",
|
||||
"A problem occurred somewhere in the SSL/TLS handshake."));
|
||||
case CURLE_OPERATION_TIMEDOUT:
|
||||
return HttpResponseOutcome(
|
||||
Error("OperationTimeoutError",
|
||||
"Timeout (connectTimeout: " +
|
||||
std::to_string(connect_timeout) + "ms, readTimeout: " +
|
||||
std::to_string(read_timeout) + "ms) when connect or read data: " +
|
||||
HttpMethodToString(request.method()) + " " + request.url().toString()));
|
||||
|
||||
default: {
|
||||
return HttpResponseOutcome(
|
||||
Error("NetworkError",
|
||||
"Failed to connect to host or proxy: " +
|
||||
HttpMethodToString(request.method()) + " " + request.url().toString()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user