timeout support when create client or make request

This commit is contained in:
zhangzifa
2019-03-13 14:51:01 +08:00
committed by Jackson Tian
parent 8c9353a007
commit 619a7827de
29 changed files with 1005 additions and 97 deletions

View File

@@ -18,8 +18,15 @@
#define CORE_INCLUDE_ALIBABACLOUD_CORE_ALIBABACLOUD_H_
#include "CoreExport.h"
#include <limits>
namespace AlibabaCloud {
const long kInvalidTimeout = (std::numeric_limits<long>::min)();
const long kDefaultConnectTimeout = 5000;
const long kDefaultReadTimeout = 10000;
ALIBABACLOUD_CORE_EXPORT void InitializeSdk();
ALIBABACLOUD_CORE_EXPORT bool IsSdkInitialized();
ALIBABACLOUD_CORE_EXPORT void ShutdownSdk();

View File

@@ -38,10 +38,17 @@ class ALIBABACLOUD_CORE_EXPORT ClientConfiguration {
void setProxy(const NetworkProxy &proxy);
void setRegionId(const std::string &regionId);
long connectTimeout() const;
long readTimeout() const;
void setConnectTimeout(const long connectTimeout);
void setReadTimeout(const long readTimeout);
private:
std::string endpoint_;
NetworkProxy proxy_;
std::string regionId_;
long connectTimeout_;
long readTimeout_;
};
} // namespace AlibabaCloud

View File

@@ -42,10 +42,16 @@ class ALIBABACLOUD_CORE_EXPORT HttpRequest : public HttpMessage {
void setMethod(Method method);
void setUrl(const Url &url);
Url url()const;
long connectTimeout() const;
long readTimeout() const;
void setConnectTimeout(const long connectTimeout);
void setReadTimeout(const long readTimeout);
private:
Method method_;
Url url_;
long connectTimeout_;
long readTimeout_;
};
} // namespace AlibabaCloud
#endif // CORE_INCLUDE_ALIBABACLOUD_CORE_HTTPREQUEST_H_

View File

@@ -39,6 +39,10 @@ class ALIBABACLOUD_CORE_EXPORT ServiceRequest {
std::string resourcePath() const;
std::string version() const;
std::string scheme() const;
long connectTimeout() const;
long readTimeout() const;
void setConnectTimeout(const long connectTimeout);
void setReadTimeout(const long readTimeout);
protected:
ServiceRequest(const std::string &product, const std::string &version);
@@ -68,6 +72,8 @@ class ALIBABACLOUD_CORE_EXPORT ServiceRequest {
std::string resourcePath_;
std::string version_;
std::string scheme_;
long connectTimeout_;
long readTimeout_;
};
} // namespace AlibabaCloud

View File

@@ -26,14 +26,13 @@ class ALIBABACLOUD_CORE_EXPORT ServiceResult {
public:
ServiceResult();
virtual ~ServiceResult();
std::string requestId()const;
protected:
void setRequestId(const std::string &requestId);
private:
std::string requestId_;
std::string requestId_;
};
} // namespace AlibabaCloud

View File

@@ -15,6 +15,7 @@
*/
#include <alibabacloud/core/ClientConfiguration.h>
#include <alibabacloud/core/AlibabaCloud.h>
namespace AlibabaCloud {
@@ -22,7 +23,9 @@ ClientConfiguration::ClientConfiguration(const std::string &regionId,
const NetworkProxy &proxy):
regionId_(regionId),
proxy_(proxy),
endpoint_() {
endpoint_(),
connectTimeout_(kDefaultConnectTimeout),
readTimeout_(kDefaultReadTimeout) {
}
ClientConfiguration::~ClientConfiguration() {
@@ -52,4 +55,20 @@ void ClientConfiguration::setRegionId(const std::string &regionId) {
regionId_ = regionId;
}
long ClientConfiguration::connectTimeout() const {
return connectTimeout_;
}
long ClientConfiguration::readTimeout() const {
return readTimeout_;
}
void ClientConfiguration::setConnectTimeout(const long connectTimeout) {
connectTimeout_ = connectTimeout;
}
void ClientConfiguration::setReadTimeout(const long readTimeout) {
readTimeout_ = readTimeout;
}
} // namespace AlibabaCloud

View File

@@ -14,6 +14,7 @@
* limitations under the License.
*/
#include <alibabacloud/core/AlibabaCloud.h>
#include <alibabacloud/core/CommonClient.h>
#include <alibabacloud/core/location/LocationClient.h>
#include <alibabacloud/core/SimpleCredentialsProvider.h>
@@ -145,6 +146,19 @@ HttpRequest CommonClient::buildRoaHttpRequest(const std::string & endpoint,
HttpRequest request(url);
request.setMethod(method);
if (msg.connectTimeout() != kInvalidTimeout) {
request.setConnectTimeout(msg.connectTimeout());
} else {
request.setConnectTimeout(configuration().connectTimeout());
}
if (msg.readTimeout() != kInvalidTimeout) {
request.setReadTimeout(msg.readTimeout());
} else {
request.setReadTimeout(configuration().readTimeout());
}
if (msg.headerParameter("Accept").empty()) {
request.setHeader("Accept", "application/json");
} else {
@@ -260,6 +274,18 @@ HttpRequest CommonClient::buildRpcHttpRequest(const std::string & endpoint,
url.setQuery(queryString.str().substr(1));
HttpRequest request(url);
if (msg.connectTimeout() != kInvalidTimeout) {
request.setConnectTimeout(msg.connectTimeout());
} else {
request.setConnectTimeout(configuration().connectTimeout());
}
if (msg.readTimeout() != kInvalidTimeout) {
request.setReadTimeout(msg.readTimeout());
} else {
request.setReadTimeout(configuration().readTimeout());
}
request.setMethod(method);
request.setHeader("Host", url.host());
request.setHeader("x-sdk-client",

View File

@@ -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()));
}
}
}

View File

@@ -15,13 +15,16 @@
*/
#include <alibabacloud/core/HttpRequest.h>
#include <alibabacloud/core/AlibabaCloud.h>
namespace AlibabaCloud {
HttpRequest::HttpRequest(const Url &url, Method method) :
HttpMessage(),
url_(url),
method_(method) {
method_(method),
connectTimeout_(kDefaultConnectTimeout),
readTimeout_(kDefaultReadTimeout) {
}
HttpRequest::~HttpRequest() {
@@ -44,4 +47,20 @@ Url HttpRequest::url()const {
return url_;
}
long HttpRequest::connectTimeout() const {
return connectTimeout_;
}
long HttpRequest::readTimeout() const {
return readTimeout_;
}
void HttpRequest::setConnectTimeout(const long connectTimeout) {
connectTimeout_ = connectTimeout;
}
void HttpRequest::setReadTimeout(const long readTimeout) {
readTimeout_ = readTimeout;
}
} // namespace AlibabaCloud

View File

@@ -14,6 +14,7 @@
* limitations under the License.
*/
#include <alibabacloud/core/AlibabaCloud.h>
#include <alibabacloud/core/RoaServiceClient.h>
#include <alibabacloud/core/HmacSha1Signer.h>
#include <algorithm>
@@ -85,6 +86,18 @@ HttpRequest RoaServiceClient::buildHttpRequest(const std::string & endpoint,
HttpRequest request(url);
request.setMethod(method);
if (msg.connectTimeout() != kInvalidTimeout) {
request.setConnectTimeout(msg.connectTimeout());
} else {
request.setConnectTimeout(configuration().connectTimeout());
}
if (msg.readTimeout() != kInvalidTimeout) {
request.setReadTimeout(msg.readTimeout());
} else {
request.setReadTimeout(configuration().readTimeout());
}
if (msg.parameter("Accept").empty()) {
request.setHeader("Accept", "application/json");
} else {

View File

@@ -14,6 +14,7 @@
* limitations under the License.
*/
#include <alibabacloud/core/AlibabaCloud.h>
#include <alibabacloud/core/RpcServiceClient.h>
#include <alibabacloud/core/HmacSha1Signer.h>
#include <algorithm>
@@ -107,6 +108,18 @@ HttpRequest RpcServiceClient::buildHttpRequest(const std::string & endpoint,
url.setQuery(queryString.str().substr(1));
HttpRequest request(url);
if (msg.connectTimeout() != kInvalidTimeout) {
request.setConnectTimeout(msg.connectTimeout());
} else {
request.setConnectTimeout(configuration().connectTimeout());
}
if (msg.readTimeout() != kInvalidTimeout) {
request.setReadTimeout(msg.readTimeout());
} else {
request.setReadTimeout(configuration().readTimeout());
}
request.setMethod(method);
request.setHeader("Host", url.host());
request.setHeader("x-sdk-client",

View File

@@ -31,7 +31,6 @@ std::string RpcServiceRequest::actionName()const {
return parameter("Action");
}
void RpcServiceRequest::setActionName(const std::string & name) {
setParameter("Action", name);
}

View File

@@ -15,6 +15,7 @@
*/
#include <alibabacloud/core/ServiceRequest.h>
#include <alibabacloud/core/AlibabaCloud.h>
namespace AlibabaCloud {
@@ -26,7 +27,9 @@ ServiceRequest::ServiceRequest(const std::string &product,
product_(product),
resourcePath_("/"),
version_(version),
scheme_("https") {
scheme_("https"),
connectTimeout_(kInvalidTimeout),
readTimeout_(kInvalidTimeout) {
}
ServiceRequest::ServiceRequest(const ServiceRequest &other) :
@@ -36,7 +39,9 @@ ServiceRequest::ServiceRequest(const ServiceRequest &other) :
product_(other.product_),
resourcePath_(other.resourcePath_),
version_(other.version_),
scheme_(other.scheme_) {
scheme_(other.scheme_),
connectTimeout_(other.connectTimeout_),
readTimeout_(other.readTimeout_) {
setContent(other.content_, other.contentSize_);
}
@@ -49,6 +54,8 @@ ServiceRequest& ServiceRequest::operator=(const ServiceRequest &other) {
content_ = nullptr;
contentSize_ = 0;
params_ = other.params_;
connectTimeout_ = other.connectTimeout_;
readTimeout_ = other.readTimeout_;
setContent(other.content_, other.contentSize_);
}
return *this;
@@ -152,4 +159,20 @@ std::string ServiceRequest::scheme() const {
return scheme_;
}
long ServiceRequest::connectTimeout() const{
return connectTimeout_;
}
long ServiceRequest::readTimeout() const{
return readTimeout_;
}
void ServiceRequest::setConnectTimeout(const long connectTimeout) {
connectTimeout_ = connectTimeout;
}
void ServiceRequest::setReadTimeout(const long readTimeout) {
readTimeout_ = readTimeout;
}
} // namespace AlibabaCloud