2019-06-03 21:23:35 +02:00
|
|
|
/*
|
|
|
|
* IXSocketTest.cpp
|
|
|
|
* Author: Benjamin Sergeant
|
|
|
|
* Copyright (c) 2019 Machine Zone. All rights reserved.
|
|
|
|
*/
|
|
|
|
|
2019-09-23 19:25:23 +02:00
|
|
|
#include "catch.hpp"
|
2019-06-03 21:23:35 +02:00
|
|
|
#include <iostream>
|
|
|
|
#include <ixwebsocket/IXHttpClient.h>
|
|
|
|
|
|
|
|
using namespace ix;
|
|
|
|
|
2019-09-27 23:07:01 +02:00
|
|
|
TEST_CASE("http_client", "[http]")
|
2019-06-03 21:23:35 +02:00
|
|
|
{
|
|
|
|
SECTION("Connect to a remote HTTP server")
|
|
|
|
{
|
2019-06-06 02:04:24 +02:00
|
|
|
HttpClient httpClient;
|
|
|
|
WebSocketHttpHeaders headers;
|
|
|
|
|
2019-06-03 21:23:35 +02:00
|
|
|
std::string url("http://httpbin.org/");
|
2019-06-06 02:04:24 +02:00
|
|
|
auto args = httpClient.createRequest(url);
|
|
|
|
|
|
|
|
args->extraHeaders = headers;
|
|
|
|
args->connectTimeout = 60;
|
|
|
|
args->transferTimeout = 60;
|
|
|
|
args->followRedirects = true;
|
|
|
|
args->maxRedirects = 10;
|
|
|
|
args->verbose = true;
|
|
|
|
args->compress = true;
|
2019-09-23 19:25:23 +02:00
|
|
|
args->logger = [](const std::string& msg) { std::cout << msg; };
|
|
|
|
args->onProgressCallback = [](int current, int total) -> bool {
|
|
|
|
std::cerr << "\r"
|
|
|
|
<< "Downloaded " << current << " bytes out of " << total;
|
2019-06-06 02:04:24 +02:00
|
|
|
return true;
|
|
|
|
};
|
|
|
|
|
|
|
|
auto response = httpClient.get(url, args);
|
2019-06-03 21:23:35 +02:00
|
|
|
|
2019-06-06 02:04:24 +02:00
|
|
|
for (auto it : response->headers)
|
|
|
|
{
|
|
|
|
std::cerr << it.first << ": " << it.second << std::endl;
|
|
|
|
}
|
|
|
|
|
|
|
|
std::cerr << "Upload size: " << response->uploadSize << std::endl;
|
|
|
|
std::cerr << "Download size: " << response->downloadSize << std::endl;
|
|
|
|
std::cerr << "Status: " << response->statusCode << std::endl;
|
|
|
|
std::cerr << "Error message: " << response->errorMsg << std::endl;
|
|
|
|
|
|
|
|
REQUIRE(response->errorCode == HttpErrorCode::Ok);
|
|
|
|
REQUIRE(response->statusCode == 200);
|
|
|
|
}
|
|
|
|
|
|
|
|
SECTION("Connect to a remote HTTPS server")
|
|
|
|
{
|
|
|
|
HttpClient httpClient;
|
2019-06-03 21:23:35 +02:00
|
|
|
WebSocketHttpHeaders headers;
|
2019-06-06 02:04:24 +02:00
|
|
|
|
|
|
|
std::string url("https://httpbin.org/");
|
|
|
|
auto args = httpClient.createRequest(url);
|
|
|
|
|
|
|
|
args->extraHeaders = headers;
|
|
|
|
args->connectTimeout = 60;
|
|
|
|
args->transferTimeout = 60;
|
|
|
|
args->followRedirects = true;
|
|
|
|
args->maxRedirects = 10;
|
|
|
|
args->verbose = true;
|
|
|
|
args->compress = true;
|
2019-09-23 19:25:23 +02:00
|
|
|
args->logger = [](const std::string& msg) { std::cout << msg; };
|
|
|
|
args->onProgressCallback = [](int current, int total) -> bool {
|
|
|
|
std::cerr << "\r"
|
|
|
|
<< "Downloaded " << current << " bytes out of " << total;
|
2019-06-03 21:23:35 +02:00
|
|
|
return true;
|
|
|
|
};
|
|
|
|
|
2019-06-06 02:04:24 +02:00
|
|
|
auto response = httpClient.get(url, args);
|
2019-06-04 07:12:52 +02:00
|
|
|
|
2019-06-06 02:04:24 +02:00
|
|
|
for (auto it : response->headers)
|
2019-06-03 21:23:35 +02:00
|
|
|
{
|
|
|
|
std::cerr << it.first << ": " << it.second << std::endl;
|
|
|
|
}
|
|
|
|
|
2019-06-06 02:04:24 +02:00
|
|
|
std::cerr << "Upload size: " << response->uploadSize << std::endl;
|
|
|
|
std::cerr << "Download size: " << response->downloadSize << std::endl;
|
|
|
|
std::cerr << "Status: " << response->statusCode << std::endl;
|
|
|
|
std::cerr << "Error message: " << response->errorMsg << std::endl;
|
2019-06-03 21:23:35 +02:00
|
|
|
|
2019-06-06 02:04:24 +02:00
|
|
|
REQUIRE(response->errorCode == HttpErrorCode::Ok);
|
|
|
|
REQUIRE(response->statusCode == 200);
|
2019-06-03 21:23:35 +02:00
|
|
|
}
|
|
|
|
|
2019-06-06 02:04:24 +02:00
|
|
|
SECTION("Async API, one call")
|
2019-06-03 21:23:35 +02:00
|
|
|
{
|
2019-06-06 02:04:24 +02:00
|
|
|
bool async = true;
|
|
|
|
HttpClient httpClient(async);
|
|
|
|
WebSocketHttpHeaders headers;
|
|
|
|
|
2019-06-03 21:23:35 +02:00
|
|
|
std::string url("https://httpbin.org/");
|
2019-06-06 02:04:24 +02:00
|
|
|
auto args = httpClient.createRequest(url);
|
|
|
|
|
|
|
|
args->extraHeaders = headers;
|
|
|
|
args->connectTimeout = 60;
|
|
|
|
args->transferTimeout = 60;
|
|
|
|
args->followRedirects = true;
|
|
|
|
args->maxRedirects = 10;
|
|
|
|
args->verbose = true;
|
|
|
|
args->compress = true;
|
2019-09-23 19:25:23 +02:00
|
|
|
args->logger = [](const std::string& msg) { std::cout << msg; };
|
|
|
|
args->onProgressCallback = [](int current, int total) -> bool {
|
|
|
|
std::cerr << "\r"
|
|
|
|
<< "Downloaded " << current << " bytes out of " << total;
|
2019-06-06 02:04:24 +02:00
|
|
|
return true;
|
|
|
|
};
|
|
|
|
|
|
|
|
std::atomic<bool> requestCompleted(false);
|
|
|
|
std::atomic<int> statusCode(0);
|
|
|
|
|
2019-09-23 19:25:23 +02:00
|
|
|
httpClient.performRequest(
|
|
|
|
args, [&requestCompleted, &statusCode](const HttpResponsePtr& response) {
|
2019-06-06 02:04:24 +02:00
|
|
|
std::cerr << "Upload size: " << response->uploadSize << std::endl;
|
|
|
|
std::cerr << "Download size: " << response->downloadSize << std::endl;
|
|
|
|
std::cerr << "Status: " << response->statusCode << std::endl;
|
|
|
|
std::cerr << "Error message: " << response->errorMsg << std::endl;
|
|
|
|
|
|
|
|
// In case of failure, print response->errorMsg
|
|
|
|
statusCode = response->statusCode;
|
|
|
|
requestCompleted = true;
|
2019-09-23 19:25:23 +02:00
|
|
|
});
|
2019-06-06 02:04:24 +02:00
|
|
|
|
|
|
|
int wait = 0;
|
|
|
|
while (wait < 5000)
|
|
|
|
{
|
|
|
|
if (requestCompleted) break;
|
2019-06-03 21:23:35 +02:00
|
|
|
|
2019-06-06 02:04:24 +02:00
|
|
|
std::chrono::duration<double, std::milli> duration(10);
|
|
|
|
std::this_thread::sleep_for(duration);
|
|
|
|
wait += 10;
|
|
|
|
}
|
|
|
|
|
|
|
|
std::cerr << "Done" << std::endl;
|
|
|
|
REQUIRE(statusCode == 200);
|
|
|
|
}
|
|
|
|
|
|
|
|
SECTION("Async API, multiple calls")
|
|
|
|
{
|
|
|
|
bool async = true;
|
|
|
|
HttpClient httpClient(async);
|
2019-06-03 21:23:35 +02:00
|
|
|
WebSocketHttpHeaders headers;
|
2019-06-06 02:04:24 +02:00
|
|
|
|
|
|
|
std::string url("http://httpbin.org/");
|
|
|
|
auto args = httpClient.createRequest(url);
|
|
|
|
|
|
|
|
args->extraHeaders = headers;
|
|
|
|
args->connectTimeout = 60;
|
|
|
|
args->transferTimeout = 60;
|
|
|
|
args->followRedirects = true;
|
|
|
|
args->maxRedirects = 10;
|
|
|
|
args->verbose = true;
|
|
|
|
args->compress = true;
|
2019-09-23 19:25:23 +02:00
|
|
|
args->logger = [](const std::string& msg) { std::cout << msg; };
|
|
|
|
args->onProgressCallback = [](int current, int total) -> bool {
|
|
|
|
std::cerr << "\r"
|
|
|
|
<< "Downloaded " << current << " bytes out of " << total;
|
2019-06-03 21:23:35 +02:00
|
|
|
return true;
|
|
|
|
};
|
|
|
|
|
2019-06-06 02:04:24 +02:00
|
|
|
std::atomic<bool> requestCompleted(false);
|
|
|
|
std::atomic<int> statusCode0(0);
|
|
|
|
std::atomic<int> statusCode1(0);
|
|
|
|
std::atomic<int> statusCode2(0);
|
2019-06-04 07:12:52 +02:00
|
|
|
|
2019-06-06 02:04:24 +02:00
|
|
|
for (int i = 0; i < 3; ++i)
|
2019-06-03 21:23:35 +02:00
|
|
|
{
|
2019-09-23 19:25:23 +02:00
|
|
|
httpClient.performRequest(
|
|
|
|
args,
|
|
|
|
[i, &requestCompleted, &statusCode0, &statusCode1, &statusCode2](
|
|
|
|
const HttpResponsePtr& response) {
|
2019-06-06 02:04:24 +02:00
|
|
|
std::cerr << "Upload size: " << response->uploadSize << std::endl;
|
|
|
|
std::cerr << "Download size: " << response->downloadSize << std::endl;
|
|
|
|
std::cerr << "Status: " << response->statusCode << std::endl;
|
|
|
|
std::cerr << "Error message: " << response->errorMsg << std::endl;
|
|
|
|
|
|
|
|
// In case of failure, print response->errorMsg
|
|
|
|
if (i == 0)
|
|
|
|
{
|
|
|
|
statusCode0 = response->statusCode;
|
|
|
|
}
|
|
|
|
else if (i == 1)
|
|
|
|
{
|
|
|
|
statusCode1 = response->statusCode;
|
|
|
|
}
|
|
|
|
else if (i == 2)
|
|
|
|
{
|
|
|
|
statusCode2 = response->statusCode;
|
|
|
|
requestCompleted = true;
|
|
|
|
}
|
2019-09-23 19:25:23 +02:00
|
|
|
});
|
2019-06-03 21:23:35 +02:00
|
|
|
}
|
|
|
|
|
2019-06-06 02:04:24 +02:00
|
|
|
int wait = 0;
|
|
|
|
while (wait < 10000)
|
|
|
|
{
|
|
|
|
if (requestCompleted) break;
|
|
|
|
|
|
|
|
std::chrono::duration<double, std::milli> duration(10);
|
|
|
|
std::this_thread::sleep_for(duration);
|
|
|
|
wait += 10;
|
|
|
|
}
|
2019-06-03 21:23:35 +02:00
|
|
|
|
2019-06-06 02:04:24 +02:00
|
|
|
std::cerr << "Done" << std::endl;
|
|
|
|
REQUIRE(statusCode0 == 200);
|
|
|
|
REQUIRE(statusCode1 == 200);
|
|
|
|
REQUIRE(statusCode2 == 200);
|
2019-06-03 21:23:35 +02:00
|
|
|
}
|
|
|
|
}
|