8
8
#include < aws/core/http/HttpResponse.h>
9
9
#include < aws/core/http/HttpClientFactory.h>
10
10
#include < aws/core/http/HttpClient.h>
11
+ #include < aws/core/http/standard/StandardHttpRequest.h>
11
12
#include < aws/core/client/ClientConfiguration.h>
13
+ #include < aws/core/utils/logging/LogMacros.h>
12
14
13
15
using namespace Aws ::Http;
14
16
using namespace Aws ::Utils;
15
17
using namespace Aws ::Client;
16
18
17
19
#ifndef NO_HTTP_CLIENT
18
- TEST (HttpClientTest, TestHttpResponseNetworkError )
20
+ TEST (HttpClientTest, TestRandomURL )
19
21
{
20
22
auto request = CreateHttpRequest (Aws::String (" http://some.unknown1234xxx.test.aws" ),
21
23
HttpMethod::HTTP_GET, Aws::Utils::Stream::DefaultResponseStreamFactoryMethod);
@@ -33,30 +35,180 @@ TEST(HttpClientTest, TestHttpResponseNetworkError)
33
35
{
34
36
ASSERT_EQ (HttpResponseCode::FORBIDDEN, response->GetResponseCode ());
35
37
}
36
-
37
38
}
38
39
39
- // Test CURL HTTP Client Settings.
40
- #if defined(ENABLE_CURL_CLIENT) && defined(ENABLE_HTTP_CLIENT_TESTING)
41
- #include < aws/core/platform/FileSystem.h>
42
- #include < aws/core/utils/DateTime.h>
43
- #include < unistd.h>
40
+ // Test Http Client timeout
41
+ // Run "scripts/dummy_web_server.py -l localhost -p 8778" to setup a dummy web server first.
42
+ #if ENABLE_HTTP_CLIENT_TESTING
43
+ static const char ALLOCATION_TAG[] = " HttpClientTest" ;
44
+
45
+ #if ENABLE_CURL_CLIENT
46
+ #include < aws/core/http/curl/CurlHttpClient.h>
44
47
#include < signal.h>
45
- #include < stdlib.h>
46
- #include < thread>
48
+ class LongRunningCurlHttpClient : public Aws ::Http::CurlHttpClient
49
+ {
50
+ public:
51
+ LongRunningCurlHttpClient (const Aws::Client::ClientConfiguration& clientConfig) : Aws::Http::CurlHttpClient(clientConfig) {}
47
52
48
- TEST (CURLHttpClientTest, TestCantResolveHost)
53
+ protected:
54
+ void OverrideOptionsOnConnectionHandle (CURL* connectionHandle) const override
55
+ {
56
+ // Override low speed limit and low speed time
57
+ curl_easy_setopt (connectionHandle, CURLOPT_LOW_SPEED_LIMIT, 1 );
58
+ curl_easy_setopt (connectionHandle, CURLOPT_LOW_SPEED_TIME, 10 );
59
+ }
60
+ };
61
+ #elif ENABLE_WINDOWS_CLIENT
62
+ #include < windows.h>
63
+ #if ENABLE_WINDOWS_IXML_HTTP_REQUEST_2_CLIENT
64
+ #include < aws/core/http/windows/IXmlHttpRequest2HttpClient.h>
65
+ #include < aws/core/platform/refs/IXmlHttpRequest2Ref.h>
66
+ class LongRunningIXmlHttpRequest2HttpClient : public Aws ::Http::IXmlHttpRequest2HttpClient
49
67
{
50
- auto request = CreateHttpRequest (Aws::String (" http://some.unknown1234xxx.test.aws" ),
68
+ public:
69
+ LongRunningIXmlHttpRequest2HttpClient (const Aws::Client::ClientConfiguration& clientConfig) : Aws::Http::IXmlHttpRequest2HttpClient(clientConfig) {}
70
+
71
+ protected:
72
+ // Override total timeout.
73
+ void OverrideOptionsOnRequestHandle (const Aws::Http::HttpRequestComHandle& handle) const override
74
+ {
75
+ handle->SetProperty (XHR_PROP_TIMEOUT, 10000 );
76
+ }
77
+ };
78
+ #if BYPASS_DEFAULT_PROXY
79
+ #include < aws/core/http/windows/WinHttpSyncHttpClient.h>
80
+ #include < winhttp.h>
81
+ class LongRunningWinHttpSyncHttpClient : public Aws ::Http::WinHttpSyncHttpClient
82
+ {
83
+ public:
84
+ LongRunningWinHttpSyncHttpClient (const Aws::Client::ClientConfiguration& clientConfig) : Aws::Http::WinHttpSyncHttpClient(clientConfig) {}
85
+
86
+ protected:
87
+ // Override receive timeout.
88
+ void OverrideOptionsOnRequestHandle (void * handle) const override
89
+ {
90
+ DWORD requestMs = 10000 ;
91
+ if (!WinHttpSetOption (handle, WINHTTP_OPTION_RECEIVE_TIMEOUT, &requestMs, sizeof (requestMs)))
92
+ {
93
+ AWS_LOGSTREAM_ERROR (ALLOCATION_TAG, " Error setting timeouts " << GetLastError ());
94
+ }
95
+ }
96
+ };
97
+ #endif
98
+ #else
99
+ #include < aws/core/http/windows/WinHttpSyncHttpClient.h>
100
+ #include < winhttp.h>
101
+ class LongRunningWinHttpSyncHttpClient : public Aws ::Http::WinHttpSyncHttpClient
102
+ {
103
+ public:
104
+ LongRunningWinHttpSyncHttpClient (const Aws::Client::ClientConfiguration& clientConfig) : Aws::Http::WinHttpSyncHttpClient(clientConfig) {}
105
+
106
+ protected:
107
+ // Override receive timeout.
108
+ void OverrideOptionsOnRequestHandle (void * handle) const override
109
+ {
110
+ DWORD requestMs = 10000 ;
111
+ if (!WinHttpSetOption (handle, WINHTTP_OPTION_RECEIVE_TIMEOUT, &requestMs, sizeof (requestMs)))
112
+ {
113
+ AWS_LOGSTREAM_ERROR (ALLOCATION_TAG, " Error setting timeouts " << GetLastError ());
114
+ }
115
+ }
116
+ };
117
+ #endif
118
+ #endif
119
+
120
+ class MockCustomHttpClientFactory : public Aws ::Http::HttpClientFactory
121
+ {
122
+ std::shared_ptr<Aws::Http::HttpClient> CreateHttpClient (const Aws::Client::ClientConfiguration& clientConfiguration) const override
123
+ {
124
+ #if ENABLE_CURL_CLIENT
125
+ return Aws::MakeShared<LongRunningCurlHttpClient>(ALLOCATION_TAG, clientConfiguration);
126
+ #elif ENABLE_WINDOWS_CLIENT
127
+ #if ENABLE_WINDOWS_IXML_HTTP_REQUEST_2_CLIENT
128
+ #if BYPASS_DEFAULT_PROXY
129
+ return Aws::MakeShared<LongRunningWinHttpSyncHttpClient>(ALLOCATION_TAG, clientConfiguration);
130
+ #else
131
+ return Aws::MakeShared<LongRunningIXmlHttpRequest2HttpClient>(ALLOCATION_TAG, clientConfiguration);
132
+ #endif // BYPASS_DEFAULT_PROXY
133
+ #else
134
+ return Aws::MakeShared<LongRunningWinHttpSyncHttpClient>(ALLOCATION_TAG, clientConfiguration);
135
+
136
+ #endif // ENABLE_WINDOWS_IXML_HTTP_REQUEST_2_CLIENT
137
+ #else
138
+ AWS_LOGSTREAM_ERROR (ALLOCATION_TAG, " For testing purpose, this factory will not fallback to default http client intentionally." );
139
+ return nullptr ;
140
+ #endif
141
+ }
142
+
143
+ std::shared_ptr<Aws::Http::HttpRequest> CreateHttpRequest (const Aws::String &uri, Aws::Http::HttpMethod method,
144
+ const Aws::IOStreamFactory &streamFactory) const override
145
+ {
146
+ return CreateHttpRequest (Aws::Http::URI (uri), method, streamFactory);
147
+ }
148
+
149
+ std::shared_ptr<Aws::Http::HttpRequest> CreateHttpRequest (const Aws::Http::URI& uri, Aws::Http::HttpMethod method, const Aws::IOStreamFactory& streamFactory) const override
150
+ {
151
+ auto request = Aws::MakeShared<Aws::Http::Standard::StandardHttpRequest>(ALLOCATION_TAG, uri, method);
152
+ request->SetResponseStreamFactory (streamFactory);
153
+
154
+ return request;
155
+ }
156
+
157
+ void InitStaticState () override
158
+ {
159
+ #if ENABLE_CURL_CLIENT
160
+ LongRunningCurlHttpClient::InitGlobalState ();
161
+ #elif ENABLE_WINDOWS_IXML_HTTP_REQUEST_2_CLIENT
162
+ LongRunningIXmlHttpRequest2HttpClient::InitCOM ();
163
+ #endif
164
+ }
165
+
166
+ void CleanupStaticState () override
167
+ {
168
+ #if ENABLE_CURL_CLIENT
169
+ LongRunningCurlHttpClient::CleanupGlobalState ();
170
+ #endif
171
+ }
172
+ };
173
+
174
+ TEST (HttpClientTest, TestHttpClientOverride)
175
+ {
176
+ auto request = CreateHttpRequest (Aws::String (" http://127.0.0.1:8778" ),
51
177
HttpMethod::HTTP_GET, Aws::Utils::Stream::DefaultResponseStreamFactoryMethod);
52
- auto httpClient = CreateHttpClient (Aws::Client::ClientConfiguration ());
178
+ request->SetHeaderValue (" WaitSeconds" , " 5" );
179
+ Aws::Client::ClientConfiguration config;
180
+ config.requestTimeoutMs = 1000 ; // http server wait 4 seconds to respond
181
+ auto httpClient = CreateHttpClient (config);
53
182
auto response = httpClient->MakeRequest (request);
54
- ASSERT_NE (nullptr , response);
183
+ EXPECT_NE (nullptr , response);
55
184
ASSERT_TRUE (response->HasClientError ());
56
185
ASSERT_EQ (CoreErrors::NETWORK_CONNECTION, response->GetClientErrorType ());
57
- ASSERT_EQ (Aws::Http::HttpResponseCode::REQUEST_NOT_MADE, response->GetResponseCode ());
186
+ EXPECT_EQ (Aws::Http::HttpResponseCode::REQUEST_NOT_MADE, response->GetResponseCode ());
187
+
188
+ // With custom HTTP client factory, the request timeout is 10 seconds for each HTTP client.
189
+ SetHttpClientFactory (Aws::MakeShared<MockCustomHttpClientFactory>(ALLOCATION_TAG));
190
+ request = CreateHttpRequest (Aws::String (" http://127.0.0.1:8778" ),
191
+ HttpMethod::HTTP_GET, Aws::Utils::Stream::DefaultResponseStreamFactoryMethod);
192
+ request->SetHeaderValue (" WaitSeconds" , " 5" );
193
+ httpClient = CreateHttpClient (config);
194
+ response = httpClient->MakeRequest (request);
195
+ EXPECT_NE (nullptr , response);
196
+ ASSERT_FALSE (response->HasClientError ());
197
+ EXPECT_EQ (Aws::Http::HttpResponseCode::OK, response->GetResponseCode ());
198
+
199
+ CleanupHttp ();
200
+ InitHttp ();
58
201
}
59
202
203
+ // Test CURL HTTP Client specific Settings.
204
+ #if ENABLE_CURL_CLIENT
205
+ #include < aws/core/platform/FileSystem.h>
206
+ #include < aws/core/utils/DateTime.h>
207
+ #include < unistd.h>
208
+ #include < signal.h>
209
+ #include < stdlib.h>
210
+ #include < thread>
211
+
60
212
TEST (CURLHttpClientTest, TestConnectionTimeout)
61
213
{
62
214
auto request = CreateHttpRequest (Aws::String (" https://8.8.8.8:53" ),// unless 8.8.8.8 is localhost, it's unlikely to succeed.
@@ -88,22 +240,6 @@ TEST(CURLHttpClientTest, TestHttpRequestTimeout)
88
240
EXPECT_TRUE (response->GetClientErrorMessage ().find (" curlCode: 28" ) == 0 );
89
241
}
90
242
91
- TEST (CURLHttpClientTest, TestHttpLowSpeedTimeout)
92
- {
93
- auto request = CreateHttpRequest (Aws::String (" http://127.0.0.1:8778" ),
94
- HttpMethod::HTTP_GET, Aws::Utils::Stream::DefaultResponseStreamFactoryMethod);
95
- request->SetHeaderValue (" WaitSeconds" , " 2" );
96
- Aws::Client::ClientConfiguration config;
97
- config.requestTimeoutMs = 1000 ; // http server wait 2 seconds to respond
98
- auto httpClient = CreateHttpClient (config);
99
- auto response = httpClient->MakeRequest (request);
100
- EXPECT_NE (nullptr , response);
101
- ASSERT_TRUE (response->HasClientError ());
102
- ASSERT_EQ (CoreErrors::NETWORK_CONNECTION, response->GetClientErrorType ());
103
- EXPECT_EQ (Aws::Http::HttpResponseCode::REQUEST_NOT_MADE, response->GetResponseCode ());
104
- EXPECT_TRUE (response->GetClientErrorMessage ().find (" curlCode: 28" ) == 0 );
105
- }
106
-
107
243
TEST (CURLHttpClientTest, TestHttpRequestTimeoutBeforeFinishing)
108
244
{
109
245
auto request = CreateHttpRequest (Aws::String (" http://127.0.0.1:8778" ),
@@ -136,6 +272,6 @@ TEST(CURLHttpClientTest, TestHttpRequestWorksFine)
136
272
EXPECT_EQ (Aws::Http::HttpResponseCode::OK, response->GetResponseCode ());
137
273
EXPECT_EQ (" " , response->GetClientErrorMessage ());
138
274
}
139
- #endif // ENABLE_CURL_CLIENT && ENABLE_HTTP_CLIENT_TESTING
140
-
275
+ #endif // ENABLE_CURL_CLIENT
276
+ # endif // ENABLE_HTTP_CLIENT_TESTING
141
277
#endif // NO_HTTP_CLIENT
0 commit comments