Unverified Commit 74377416 authored by Dennis Jenkins's avatar Dennis Jenkins Committed by GitHub

Merge pull request #4 from oktal/master

merge from upstream
parents 7884197d 5f62bfd7
...@@ -90,6 +90,11 @@ struct Connection : public std::enable_shared_from_this<Connection> { ...@@ -90,6 +90,11 @@ struct Connection : public std::enable_shared_from_this<Connection> {
std::chrono::milliseconds timeout, std::chrono::milliseconds timeout,
OnDone onDone); OnDone onDone);
Async::Promise<Response> asyncPerform(
const Http::Request& request,
std::chrono::milliseconds timeout,
OnDone onDone);
void performImpl( void performImpl(
const Http::Request& request, const Http::Request& request,
std::chrono::milliseconds timeout, std::chrono::milliseconds timeout,
......
...@@ -48,6 +48,8 @@ public: ...@@ -48,6 +48,8 @@ public:
Flags<Options> options = Options::None, Flags<Options> options = Options::None,
int backlog = Const::MaxBacklog); int backlog = Const::MaxBacklog);
void setHandler(const std::shared_ptr<Handler>& handler); void setHandler(const std::shared_ptr<Handler>& handler);
static bool systemSupportsIpv6();
void bind(); void bind();
void bind(const Address& address); void bind(const Address& address);
......
...@@ -52,6 +52,7 @@ public: ...@@ -52,6 +52,7 @@ public:
Ipv4(uint8_t a, uint8_t b, uint8_t c, uint8_t d); Ipv4(uint8_t a, uint8_t b, uint8_t c, uint8_t d);
static Ipv4 any(); static Ipv4 any();
static Ipv4 loopback();
std::string toString() const; std::string toString() const;
void toNetwork(in_addr_t*) const; void toNetwork(in_addr_t*) const;
...@@ -65,8 +66,10 @@ private: ...@@ -65,8 +66,10 @@ private:
class Ipv6 { class Ipv6 {
public: public:
Ipv6(uint16_t a, uint16_t b, uint16_t c, uint16_t d, uint16_t e, uint16_t f, uint16_t g, uint16_t h); Ipv6(uint16_t a, uint16_t b, uint16_t c, uint16_t d, uint16_t e, uint16_t f, uint16_t g, uint16_t h);
static Ipv6 any(); static Ipv6 any();
static Ipv6 loopback();
std::string toString() const; std::string toString() const;
void toNetwork(in6_addr*) const; void toNetwork(in6_addr*) const;
......
...@@ -338,7 +338,7 @@ Connection::connect(const Address& addr) ...@@ -338,7 +338,7 @@ Connection::connect(const Address& addr)
struct addrinfo hints; struct addrinfo hints;
struct addrinfo *addrs; struct addrinfo *addrs;
memset(&hints, 0, sizeof(struct addrinfo)); memset(&hints, 0, sizeof(struct addrinfo));
hints.ai_family = AF_UNSPEC; /* Allow IPv4 or IPv6 */ hints.ai_family = addr.family();
hints.ai_socktype = SOCK_STREAM; /* Stream socket */ hints.ai_socktype = SOCK_STREAM; /* Stream socket */
hints.ai_flags = 0; hints.ai_flags = 0;
hints.ai_protocol = 0; hints.ai_protocol = 0;
...@@ -477,17 +477,23 @@ Connection::perform( ...@@ -477,17 +477,23 @@ Connection::perform(
std::chrono::milliseconds timeout, std::chrono::milliseconds timeout,
Connection::OnDone onDone) { Connection::OnDone onDone) {
return Async::Promise<Response>([=](Async::Resolver& resolve, Async::Rejection& reject) { return Async::Promise<Response>([=](Async::Resolver& resolve, Async::Rejection& reject) {
if (!isConnected()) { performImpl(request, timeout, std::move(resolve), std::move(reject), std::move(onDone));
requestsQueue.push( });
RequestData( }
std::move(resolve),
std::move(reject), Async::Promise<Response>
request, Connection::asyncPerform(
timeout, const Http::Request& request,
std::move(onDone))); std::chrono::milliseconds timeout,
} else { Connection::OnDone onDone) {
performImpl(request, timeout, std::move(resolve), std::move(reject), std::move(onDone)); return Async::Promise<Response>([=](Async::Resolver& resolve, Async::Rejection& reject) {
} requestsQueue.push(
RequestData(
std::move(resolve),
std::move(reject),
request,
timeout,
std::move(onDone)));
}); });
} }
...@@ -796,7 +802,12 @@ Client::doRequest( ...@@ -796,7 +802,12 @@ Client::doRequest(
} }
if (!conn->isConnected()) { if (!conn->isConnected()) {
auto res = conn->asyncPerform(request, timeout, [=]() {
pool.releaseConnection(conn);
processRequestQueue();
});
conn->connect(helpers::httpAddr(s.first)); conn->connect(helpers::httpAddr(s.first));
return res;
} }
return conn->perform(request, timeout, [=]() { return conn->perform(request, timeout, [=]() {
......
...@@ -50,6 +50,12 @@ Ipv4::any() { ...@@ -50,6 +50,12 @@ Ipv4::any() {
return Ipv4(0, 0, 0, 0); return Ipv4(0, 0, 0, 0);
} }
Ipv4
Ipv4::loopback() {
return Ipv4(127, 0, 0, 1);
}
std::string std::string
Ipv4::toString() const { Ipv4::toString() const {
...@@ -86,6 +92,11 @@ Ipv6::any() { ...@@ -86,6 +92,11 @@ Ipv6::any() {
return Ipv6(0, 0, 0, 0, 0, 0, 0, 0); return Ipv6(0, 0, 0, 0, 0, 0, 0, 0);
} }
Ipv6
Ipv6::loopback() {
return Ipv6(0, 0, 0, 0, 0, 0, 0, 1);
}
std::string std::string
Ipv6::toString() const { Ipv6::toString() const {
...@@ -97,7 +108,7 @@ Ipv6::toString() const { ...@@ -97,7 +108,7 @@ Ipv6::toString() const {
inet_ntop(AF_INET6, &addr, buff6, INET6_ADDRSTRLEN); inet_ntop(AF_INET6, &addr, buff6, INET6_ADDRSTRLEN);
return std::string("[") + std::string(buff6) + std::string("]"); return std::string(buff6);
} }
void Ipv6::toNetwork(in6_addr *addr6) const { void Ipv6::toNetwork(in6_addr *addr6) const {
...@@ -196,7 +207,8 @@ Address::init(const std::string& addr) { ...@@ -196,7 +207,8 @@ Address::init(const std::string& addr) {
unsigned long s_pos = addr.find('['); unsigned long s_pos = addr.find('[');
if (pos != std::string::npos && s_pos != std::string::npos) { if (pos != std::string::npos && s_pos != std::string::npos) {
//IPv6 address //IPv6 address
host_ = addr.substr(s_pos, pos+1); host_ = addr.substr(s_pos+1, pos-1);
family_ = AF_INET6;
try { try {
in6_addr addr6; in6_addr addr6;
char buff6[INET6_ADDRSTRLEN+1]; char buff6[INET6_ADDRSTRLEN+1];
...@@ -212,13 +224,14 @@ Address::init(const std::string& addr) { ...@@ -212,13 +224,14 @@ Address::init(const std::string& addr) {
if (pos == std::string::npos) if (pos == std::string::npos)
throw std::invalid_argument("Invalid address"); throw std::invalid_argument("Invalid address");
host_ = addr.substr(0, pos); host_ = addr.substr(0, pos);
family_ = AF_INET;
if (host_ == "*") { if (host_ == "*") {
host_ = "0.0.0.0"; host_ = "0.0.0.0";
} }
try { try {
in_addr addr; in_addr addr;
char buff[INET_ADDRSTRLEN+1]; char buff[INET_ADDRSTRLEN+1];
memcpy(buff, host_.c_str(), INET6_ADDRSTRLEN); memcpy(buff, host_.c_str(), INET_ADDRSTRLEN);
inet_pton(AF_INET, buff, &(addr)); inet_pton(AF_INET, buff, &(addr));
} catch (std::runtime_error) { } catch (std::runtime_error) {
throw std::invalid_argument("Invalid IPv4 address"); throw std::invalid_argument("Invalid IPv4 address");
......
...@@ -190,16 +190,14 @@ namespace Polling { ...@@ -190,16 +190,14 @@ namespace Polling {
ready_fds = epoll_wait(epoll_fd, evs, maxEvents, timeout.count()); ready_fds = epoll_wait(epoll_fd, evs, maxEvents, timeout.count());
} while (ready_fds < 0 && errno == EINTR); } while (ready_fds < 0 && errno == EINTR);
if (ready_fds > 0) { for (int i = 0; i < ready_fds; ++i) {
for (int i = 0; i < ready_fds; ++i) { const struct epoll_event *ev = evs + i;
const struct epoll_event *ev = evs + i;
const Tag tag(ev->data.u64); const Tag tag(ev->data.u64);
Event event(tag); Event event(tag);
event.flags = toNotifyOn(ev->events); event.flags = toNotifyOn(ev->events);
events.push_back(event); events.push_back(event);
}
} }
return ready_fds; return ready_fds;
......
...@@ -14,6 +14,8 @@ ...@@ -14,6 +14,8 @@
#include <netinet/in.h> #include <netinet/in.h>
#include <netinet/tcp.h> #include <netinet/tcp.h>
#include <arpa/inet.h> #include <arpa/inet.h>
#include <sys/types.h>
#include <ifaddrs.h>
#include <netdb.h> #include <netdb.h>
#include <sys/epoll.h> #include <sys/epoll.h>
#include <sys/timerfd.h> #include <sys/timerfd.h>
...@@ -145,6 +147,29 @@ Listener::pinWorker(size_t worker, const CpuSet& set) ...@@ -145,6 +147,29 @@ Listener::pinWorker(size_t worker, const CpuSet& set)
#endif #endif
} }
bool
Listener::systemSupportsIpv6(){
struct ifaddrs *ifaddr, *ifa;
int family, n;
bool supportsIpv6 = false;
if (getifaddrs(&ifaddr) == -1) {
throw std::runtime_error("Call to getifaddrs() failed");
}
for (ifa = ifaddr, n = 0; ifa != NULL; ifa = ifa->ifa_next, n++) {
if (ifa->ifa_addr == NULL)
continue;
family = ifa->ifa_addr->sa_family;
if (family == AF_INET6) {
supportsIpv6 = true;
continue;
}
}
freeifaddrs(ifaddr);
return supportsIpv6;
}
void void
Listener::bind() { Listener::bind() {
bind(addr_); bind(addr_);
...@@ -234,6 +259,7 @@ Listener::getPort() const { ...@@ -234,6 +259,7 @@ Listener::getPort() const {
void void
Listener::run() { Listener::run() {
shutdownFd.bind(poller);
reactor_.run(); reactor_.run();
for (;;) { for (;;) {
...@@ -269,7 +295,6 @@ Listener::run() { ...@@ -269,7 +295,6 @@ Listener::run() {
void void
Listener::runThreaded() { Listener::runThreaded() {
shutdownFd.bind(poller);
acceptThread = std::thread([=]() { this->run(); }); acceptThread = std::thread([=]() { this->run(); });
} }
......
...@@ -25,7 +25,7 @@ struct CookieHandler : public Http::Handler { ...@@ -25,7 +25,7 @@ struct CookieHandler : public Http::Handler {
}; };
TEST(http_client_test, one_client_with_one_request_with_onecookie) { TEST(http_client_test, one_client_with_one_request_with_onecookie) {
const std::string address = "localhost:9086"; const Pistache::Address address("localhost", Pistache::Port(0));
Http::Endpoint server(address); Http::Endpoint server(address);
auto flags = Tcp::Options::InstallSignalHandler | Tcp::Options::ReuseAddr; auto flags = Tcp::Options::InstallSignalHandler | Tcp::Options::ReuseAddr;
...@@ -34,6 +34,9 @@ TEST(http_client_test, one_client_with_one_request_with_onecookie) { ...@@ -34,6 +34,9 @@ TEST(http_client_test, one_client_with_one_request_with_onecookie) {
server.setHandler(Http::make_handler<CookieHandler>()); server.setHandler(Http::make_handler<CookieHandler>());
server.serveThreaded(); server.serveThreaded();
const std::string server_address = "localhost:" + server.getPort().toString();
std::cout << "Server address: " << server_address << "\n";
Http::Client client; Http::Client client;
client.init(); client.init();
...@@ -41,7 +44,7 @@ TEST(http_client_test, one_client_with_one_request_with_onecookie) { ...@@ -41,7 +44,7 @@ TEST(http_client_test, one_client_with_one_request_with_onecookie) {
const std::string name = "FOO"; const std::string name = "FOO";
const std::string value = "bar"; const std::string value = "bar";
auto cookie = Http::Cookie(name, value); auto cookie = Http::Cookie(name, value);
auto rb = client.get(address).cookie(cookie); auto rb = client.get(server_address).cookie(cookie);
auto response = rb.send(); auto response = rb.send();
Http::CookieJar cj; Http::CookieJar cj;
...@@ -63,7 +66,7 @@ TEST(http_client_test, one_client_with_one_request_with_onecookie) { ...@@ -63,7 +66,7 @@ TEST(http_client_test, one_client_with_one_request_with_onecookie) {
} }
TEST(http_client_test, one_client_with_one_request_with_several_cookies) { TEST(http_client_test, one_client_with_one_request_with_several_cookies) {
const std::string address = "localhost:9088"; const Pistache::Address address("localhost", Pistache::Port(0));
Http::Endpoint server(address); Http::Endpoint server(address);
auto flags = Tcp::Options::InstallSignalHandler | Tcp::Options::ReuseAddr; auto flags = Tcp::Options::InstallSignalHandler | Tcp::Options::ReuseAddr;
...@@ -72,6 +75,9 @@ TEST(http_client_test, one_client_with_one_request_with_several_cookies) { ...@@ -72,6 +75,9 @@ TEST(http_client_test, one_client_with_one_request_with_several_cookies) {
server.setHandler(Http::make_handler<CookieHandler>()); server.setHandler(Http::make_handler<CookieHandler>());
server.serveThreaded(); server.serveThreaded();
const std::string server_address = "localhost:" + server.getPort().toString();
std::cout << "Server address: " << server_address << "\n";
Http::Client client; Http::Client client;
client.init(); client.init();
...@@ -85,7 +91,7 @@ TEST(http_client_test, one_client_with_one_request_with_several_cookies) { ...@@ -85,7 +91,7 @@ TEST(http_client_test, one_client_with_one_request_with_several_cookies) {
const std::string name3 = "Key"; const std::string name3 = "Key";
const std::string value3 = "value"; const std::string value3 = "value";
auto cookie3 = Http::Cookie(name3, value3); auto cookie3 = Http::Cookie(name3, value3);
auto rb = client.get(address).cookie(cookie1).cookie(cookie2).cookie(cookie3); auto rb = client.get(server_address).cookie(cookie1).cookie(cookie2).cookie(cookie3);
auto response = rb.send(); auto response = rb.send();
std::unordered_map<std::string, std::string> cookiesStorages; std::unordered_map<std::string, std::string> cookiesStorages;
......
...@@ -32,7 +32,7 @@ struct DelayHandler : public Http::Handler ...@@ -32,7 +32,7 @@ struct DelayHandler : public Http::Handler
TEST(http_client_test, one_client_with_one_request) TEST(http_client_test, one_client_with_one_request)
{ {
const std::string address = "localhost:9100"; const Pistache::Address address("localhost", Pistache::Port(0));
Http::Endpoint server(address); Http::Endpoint server(address);
auto flags = Tcp::Options::InstallSignalHandler | Tcp::Options::ReuseAddr; auto flags = Tcp::Options::InstallSignalHandler | Tcp::Options::ReuseAddr;
...@@ -41,10 +41,13 @@ TEST(http_client_test, one_client_with_one_request) ...@@ -41,10 +41,13 @@ TEST(http_client_test, one_client_with_one_request)
server.setHandler(Http::make_handler<HelloHandler>()); server.setHandler(Http::make_handler<HelloHandler>());
server.serveThreaded(); server.serveThreaded();
const std::string server_address = "localhost:" + server.getPort().toString();
std::cout << "Server address: " << server_address << "\n";
Http::Client client; Http::Client client;
client.init(); client.init();
auto rb = client.get(address); auto rb = client.get(server_address);
auto response = rb.send(); auto response = rb.send();
bool done = false; bool done = false;
response.then([&](Http::Response rsp) response.then([&](Http::Response rsp)
...@@ -63,7 +66,7 @@ TEST(http_client_test, one_client_with_one_request) ...@@ -63,7 +66,7 @@ TEST(http_client_test, one_client_with_one_request)
} }
TEST(http_client_test, one_client_with_multiple_requests) { TEST(http_client_test, one_client_with_multiple_requests) {
const std::string address = "localhost:9101"; const Pistache::Address address("localhost", Pistache::Port(0));
Http::Endpoint server(address); Http::Endpoint server(address);
auto flags = Tcp::Options::InstallSignalHandler | Tcp::Options::ReuseAddr; auto flags = Tcp::Options::InstallSignalHandler | Tcp::Options::ReuseAddr;
...@@ -72,6 +75,9 @@ TEST(http_client_test, one_client_with_multiple_requests) { ...@@ -72,6 +75,9 @@ TEST(http_client_test, one_client_with_multiple_requests) {
server.setHandler(Http::make_handler<HelloHandler>()); server.setHandler(Http::make_handler<HelloHandler>());
server.serveThreaded(); server.serveThreaded();
const std::string server_address = "localhost:" + server.getPort().toString();
std::cout << "Server address: " << server_address << "\n";
Http::Client client; Http::Client client;
client.init(); client.init();
...@@ -79,7 +85,7 @@ TEST(http_client_test, one_client_with_multiple_requests) { ...@@ -79,7 +85,7 @@ TEST(http_client_test, one_client_with_multiple_requests) {
const int RESPONSE_SIZE = 3; const int RESPONSE_SIZE = 3;
int response_counter = 0; int response_counter = 0;
auto rb = client.get(address); auto rb = client.get(server_address);
for (int i = 0; i < RESPONSE_SIZE; ++i) { for (int i = 0; i < RESPONSE_SIZE; ++i) {
auto response = rb.send(); auto response = rb.send();
response.then([&](Http::Response rsp) { response.then([&](Http::Response rsp) {
...@@ -101,7 +107,7 @@ TEST(http_client_test, one_client_with_multiple_requests) { ...@@ -101,7 +107,7 @@ TEST(http_client_test, one_client_with_multiple_requests) {
} }
TEST(http_client_test, multiple_clients_with_one_request) { TEST(http_client_test, multiple_clients_with_one_request) {
const std::string address = "localhost:9102"; const Pistache::Address address("localhost", Pistache::Port(0));
Http::Endpoint server(address); Http::Endpoint server(address);
auto flags = Tcp::Options::InstallSignalHandler | Tcp::Options::ReuseAddr; auto flags = Tcp::Options::InstallSignalHandler | Tcp::Options::ReuseAddr;
...@@ -110,6 +116,9 @@ TEST(http_client_test, multiple_clients_with_one_request) { ...@@ -110,6 +116,9 @@ TEST(http_client_test, multiple_clients_with_one_request) {
server.setHandler(Http::make_handler<HelloHandler>()); server.setHandler(Http::make_handler<HelloHandler>());
server.serveThreaded(); server.serveThreaded();
const std::string server_address = "localhost:" + server.getPort().toString();
std::cout << "Server address: " << server_address << "\n";
const int CLIENT_SIZE = 3; const int CLIENT_SIZE = 3;
Http::Client client1; Http::Client client1;
client1.init(); client1.init();
...@@ -121,21 +130,21 @@ TEST(http_client_test, multiple_clients_with_one_request) { ...@@ -121,21 +130,21 @@ TEST(http_client_test, multiple_clients_with_one_request) {
std::vector<Async::Promise<Http::Response>> responses; std::vector<Async::Promise<Http::Response>> responses;
std::atomic<int> response_counter(0); std::atomic<int> response_counter(0);
auto rb1 = client1.get(address); auto rb1 = client1.get(server_address);
auto response1 = rb1.send(); auto response1 = rb1.send();
response1.then([&](Http::Response rsp) { response1.then([&](Http::Response rsp) {
if (rsp.code() == Http::Code::Ok) if (rsp.code() == Http::Code::Ok)
++response_counter; ++response_counter;
}, Async::IgnoreException); }, Async::IgnoreException);
responses.push_back(std::move(response1)); responses.push_back(std::move(response1));
auto rb2 = client2.get(address); auto rb2 = client2.get(server_address);
auto response2 = rb2.send(); auto response2 = rb2.send();
response2.then([&](Http::Response rsp) { response2.then([&](Http::Response rsp) {
if (rsp.code() == Http::Code::Ok) if (rsp.code() == Http::Code::Ok)
++response_counter; ++response_counter;
}, Async::IgnoreException); }, Async::IgnoreException);
responses.push_back(std::move(response2)); responses.push_back(std::move(response2));
auto rb3 = client3.get(address); auto rb3 = client3.get(server_address);
auto response3 = rb3.send(); auto response3 = rb3.send();
response3.then([&](Http::Response rsp) { response3.then([&](Http::Response rsp) {
if (rsp.code() == Http::Code::Ok) if (rsp.code() == Http::Code::Ok)
...@@ -158,7 +167,7 @@ TEST(http_client_test, multiple_clients_with_one_request) { ...@@ -158,7 +167,7 @@ TEST(http_client_test, multiple_clients_with_one_request) {
TEST(http_client_test, timeout_reject) TEST(http_client_test, timeout_reject)
{ {
const std::string address = "localhost:9103"; const Pistache::Address address("localhost", Pistache::Port(0));
Http::Endpoint server(address); Http::Endpoint server(address);
auto flags = Tcp::Options::InstallSignalHandler | Tcp::Options::ReuseAddr; auto flags = Tcp::Options::InstallSignalHandler | Tcp::Options::ReuseAddr;
...@@ -167,10 +176,13 @@ TEST(http_client_test, timeout_reject) ...@@ -167,10 +176,13 @@ TEST(http_client_test, timeout_reject)
server.setHandler(Http::make_handler<DelayHandler>()); server.setHandler(Http::make_handler<DelayHandler>());
server.serveThreaded(); server.serveThreaded();
const std::string server_address = "localhost:" + server.getPort().toString();
std::cout << "Server address: " << server_address << "\n";
Http::Client client; Http::Client client;
client.init(); client.init();
auto rb = client.get(address).timeout(std::chrono::milliseconds(1000)); auto rb = client.get(server_address).timeout(std::chrono::milliseconds(1000));
auto response = rb.send(); auto response = rb.send();
bool is_reject = false; bool is_reject = false;
response.then([&is_reject](Http::Response /*rsp*/) response.then([&is_reject](Http::Response /*rsp*/)
...@@ -193,7 +205,7 @@ TEST(http_client_test, timeout_reject) ...@@ -193,7 +205,7 @@ TEST(http_client_test, timeout_reject)
TEST(http_client_test, one_client_with_multiple_requests_and_one_connection_per_host) TEST(http_client_test, one_client_with_multiple_requests_and_one_connection_per_host)
{ {
const std::string address = "localhost:9104"; const Pistache::Address address("localhost", Pistache::Port(0));
Http::Endpoint server(address); Http::Endpoint server(address);
auto flags = Tcp::Options::InstallSignalHandler | Tcp::Options::ReuseAddr; auto flags = Tcp::Options::InstallSignalHandler | Tcp::Options::ReuseAddr;
...@@ -202,6 +214,9 @@ TEST(http_client_test, one_client_with_multiple_requests_and_one_connection_per_ ...@@ -202,6 +214,9 @@ TEST(http_client_test, one_client_with_multiple_requests_and_one_connection_per_
server.setHandler(Http::make_handler<HelloHandler>()); server.setHandler(Http::make_handler<HelloHandler>());
server.serveThreaded(); server.serveThreaded();
const std::string server_address = "localhost:" + server.getPort().toString();
std::cout << "Server address: " << server_address << "\n";
Http::Client client; Http::Client client;
auto opts = Http::Client::options().maxConnectionsPerHost(1).threads(2); auto opts = Http::Client::options().maxConnectionsPerHost(1).threads(2);
client.init(opts); client.init(opts);
...@@ -210,7 +225,7 @@ TEST(http_client_test, one_client_with_multiple_requests_and_one_connection_per_ ...@@ -210,7 +225,7 @@ TEST(http_client_test, one_client_with_multiple_requests_and_one_connection_per_
const int RESPONSE_SIZE = 6; const int RESPONSE_SIZE = 6;
std::atomic<int> response_counter(0); std::atomic<int> response_counter(0);
auto rb = client.get(address); auto rb = client.get(server_address);
for (int i = 0; i < RESPONSE_SIZE; ++i) for (int i = 0; i < RESPONSE_SIZE; ++i)
{ {
auto response = rb.send(); auto response = rb.send();
......
...@@ -72,9 +72,9 @@ int clientLogicFunc(int response_size, const std::string& server_page, int wait_ ...@@ -72,9 +72,9 @@ int clientLogicFunc(int response_size, const std::string& server_page, int wait_
} }
TEST(http_server_test, client_disconnection_on_timeout_from_single_threaded_server) { TEST(http_server_test, client_disconnection_on_timeout_from_single_threaded_server) {
const std::string server_address = "localhost:9095"; const Pistache::Address address("localhost", Pistache::Port(0));
Http::Endpoint server(server_address); Http::Endpoint server(address);
auto flags = Tcp::Options::InstallSignalHandler | Tcp::Options::ReuseAddr; auto flags = Tcp::Options::InstallSignalHandler | Tcp::Options::ReuseAddr;
auto server_opts = Http::Endpoint::options().flags(flags); auto server_opts = Http::Endpoint::options().flags(flags);
server.init(server_opts); server.init(server_opts);
...@@ -82,6 +82,9 @@ TEST(http_server_test, client_disconnection_on_timeout_from_single_threaded_serv ...@@ -82,6 +82,9 @@ TEST(http_server_test, client_disconnection_on_timeout_from_single_threaded_serv
server.setHandler(Http::make_handler<HelloHandlerWithDelay>(SIX_SECONDS_DELAY)); server.setHandler(Http::make_handler<HelloHandlerWithDelay>(SIX_SECONDS_DELAY));
server.serveThreaded(); server.serveThreaded();
const std::string server_address = "localhost:" + server.getPort().toString();
std::cout << "Server address: " << server_address << "\n";
const int CLIENT_REQUEST_SIZE = 1; const int CLIENT_REQUEST_SIZE = 1;
int counter = clientLogicFunc(CLIENT_REQUEST_SIZE, server_address, SIX_SECONDS_DELAY); int counter = clientLogicFunc(CLIENT_REQUEST_SIZE, server_address, SIX_SECONDS_DELAY);
...@@ -91,9 +94,9 @@ TEST(http_server_test, client_disconnection_on_timeout_from_single_threaded_serv ...@@ -91,9 +94,9 @@ TEST(http_server_test, client_disconnection_on_timeout_from_single_threaded_serv
} }
TEST(http_server_test, client_multiple_requests_disconnection_on_timeout_from_single_threaded_server) { TEST(http_server_test, client_multiple_requests_disconnection_on_timeout_from_single_threaded_server) {
const std::string server_address = "localhost:9096"; const Pistache::Address address("localhost", Pistache::Port(0));
Http::Endpoint server(server_address); Http::Endpoint server(address);
auto flags = Tcp::Options::InstallSignalHandler | Tcp::Options::ReuseAddr; auto flags = Tcp::Options::InstallSignalHandler | Tcp::Options::ReuseAddr;
auto server_opts = Http::Endpoint::options().flags(flags); auto server_opts = Http::Endpoint::options().flags(flags);
server.init(server_opts); server.init(server_opts);
...@@ -102,6 +105,9 @@ TEST(http_server_test, client_multiple_requests_disconnection_on_timeout_from_si ...@@ -102,6 +105,9 @@ TEST(http_server_test, client_multiple_requests_disconnection_on_timeout_from_si
server.setHandler(Http::make_handler<HelloHandlerWithDelay>(SIX_SECONDS_DELAY)); server.setHandler(Http::make_handler<HelloHandlerWithDelay>(SIX_SECONDS_DELAY));
server.serveThreaded(); server.serveThreaded();
const std::string server_address = "localhost:" + server.getPort().toString();
std::cout << "Server address: " << server_address << "\n";
const int CLIENT_REQUEST_SIZE = 3; const int CLIENT_REQUEST_SIZE = 3;
int counter = clientLogicFunc(CLIENT_REQUEST_SIZE, server_address, SIX_SECONDS_DELAY); int counter = clientLogicFunc(CLIENT_REQUEST_SIZE, server_address, SIX_SECONDS_DELAY);
...@@ -111,15 +117,18 @@ TEST(http_server_test, client_multiple_requests_disconnection_on_timeout_from_si ...@@ -111,15 +117,18 @@ TEST(http_server_test, client_multiple_requests_disconnection_on_timeout_from_si
} }
TEST(http_server_test, multiple_client_with_requests_to_multithreaded_server) { TEST(http_server_test, multiple_client_with_requests_to_multithreaded_server) {
const std::string server_address = "localhost:9097"; const Pistache::Address address("localhost", Pistache::Port(0));
Http::Endpoint server(server_address); Http::Endpoint server(address);
auto flags = Tcp::Options::InstallSignalHandler | Tcp::Options::ReuseAddr; auto flags = Tcp::Options::InstallSignalHandler | Tcp::Options::ReuseAddr;
auto server_opts = Http::Endpoint::options().flags(flags).threads(3); auto server_opts = Http::Endpoint::options().flags(flags).threads(3);
server.init(server_opts); server.init(server_opts);
server.setHandler(Http::make_handler<HelloHandlerWithDelay>()); server.setHandler(Http::make_handler<HelloHandlerWithDelay>());
server.serveThreaded(); server.serveThreaded();
const std::string server_address = "localhost:" + server.getPort().toString();
std::cout << "Server address: " << server_address << "\n";
const int SIX_SECONDS_TIMOUT = 6; const int SIX_SECONDS_TIMOUT = 6;
const int FIRST_CLIENT_REQUEST_SIZE = 4; const int FIRST_CLIENT_REQUEST_SIZE = 4;
std::future<int> result1(std::async(clientLogicFunc, std::future<int> result1(std::async(clientLogicFunc,
...@@ -142,9 +151,9 @@ TEST(http_server_test, multiple_client_with_requests_to_multithreaded_server) { ...@@ -142,9 +151,9 @@ TEST(http_server_test, multiple_client_with_requests_to_multithreaded_server) {
} }
TEST(http_server_test, multiple_client_with_different_requests_to_multithreaded_server) { TEST(http_server_test, multiple_client_with_different_requests_to_multithreaded_server) {
const std::string server_address = "localhost:9098"; const Pistache::Address address("localhost", Pistache::Port(0));
Http::Endpoint server(server_address); Http::Endpoint server(address);
auto flags = Tcp::Options::InstallSignalHandler | Tcp::Options::ReuseAddr; auto flags = Tcp::Options::InstallSignalHandler | Tcp::Options::ReuseAddr;
auto server_opts = Http::Endpoint::options().flags(flags).threads(3); auto server_opts = Http::Endpoint::options().flags(flags).threads(3);
server.init(server_opts); server.init(server_opts);
...@@ -152,6 +161,9 @@ TEST(http_server_test, multiple_client_with_different_requests_to_multithreaded_ ...@@ -152,6 +161,9 @@ TEST(http_server_test, multiple_client_with_different_requests_to_multithreaded_
server.setHandler(Http::make_handler<SlowHandlerOnSpecialPage>(SIX_SECONDS_DELAY)); server.setHandler(Http::make_handler<SlowHandlerOnSpecialPage>(SIX_SECONDS_DELAY));
server.serveThreaded(); server.serveThreaded();
const std::string server_address = "localhost:" + server.getPort().toString();
std::cout << "Server address: " << server_address << "\n";
const int FIRST_CLIENT_REQUEST_SIZE = 1; const int FIRST_CLIENT_REQUEST_SIZE = 1;
std::future<int> result1(std::async(clientLogicFunc, std::future<int> result1(std::async(clientLogicFunc,
FIRST_CLIENT_REQUEST_SIZE, FIRST_CLIENT_REQUEST_SIZE,
......
...@@ -123,6 +123,7 @@ TEST(listener_test, listener_bind_port_free) { ...@@ -123,6 +123,7 @@ TEST(listener_test, listener_bind_port_free) {
ASSERT_TRUE(true); ASSERT_TRUE(true);
} }
// Listener should not crash if an additional member is added to the listener class. This test // Listener should not crash if an additional member is added to the listener class. This test
// is there to prevent regression for PR 303 // is there to prevent regression for PR 303
TEST(listener_test, listener_uses_default) { TEST(listener_test, listener_uses_default) {
...@@ -180,8 +181,9 @@ TEST(listener_test, listener_bind_port_not_free_throw_runtime) { ...@@ -180,8 +181,9 @@ TEST(listener_test, listener_bind_port_not_free_throw_runtime) {
} }
} }
// Listener should be able to bind port 0 directly to get an ephemeral port. // Listener should be able to bind port 0 directly to get an ephemeral port.
TEST(listener_test, listener_bind_ephemeral_port) { TEST(listener_test, listener_bind_ephemeral_v4_port) {
Pistache::Port port(0); Pistache::Port port(0);
Pistache::Address address(Pistache::Ipv4::any(), port); Pistache::Address address(Pistache::Ipv4::any(), port);
...@@ -192,3 +194,20 @@ TEST(listener_test, listener_bind_ephemeral_port) { ...@@ -192,3 +194,20 @@ TEST(listener_test, listener_bind_ephemeral_port) {
Pistache::Port bound_port = listener.getPort(); Pistache::Port bound_port = listener.getPort();
ASSERT_TRUE(bound_port > (uint16_t)0); ASSERT_TRUE(bound_port > (uint16_t)0);
} }
TEST(listener_test, listener_bind_ephemeral_v6_port) {
Pistache::Tcp::Listener listener;
if (listener.systemSupportsIpv6()) {
Pistache::Port port(0);
Pistache::Address address(Pistache::Ipv6::any(), port);
Pistache::Flags<Pistache::Tcp::Options> options;
listener.setHandler(Pistache::Http::make_handler<DummyHandler>());
listener.bind(address);
Pistache::Port bound_port = listener.getPort();
ASSERT_TRUE(bound_port > (uint16_t)0);
}
ASSERT_TRUE(true);
}
...@@ -50,29 +50,37 @@ TEST(net_test, address_creation) ...@@ -50,29 +50,37 @@ TEST(net_test, address_creation)
ASSERT_EQ(address5.port(), 8080); ASSERT_EQ(address5.port(), 8080);
Address address6("[::1]:8080"); Address address6("[::1]:8080");
ASSERT_EQ(address6.host(), "[::1]"); ASSERT_EQ(address6.host(), "::1");
ASSERT_EQ(address6.port(), 8080); ASSERT_EQ(address6.port(), 8080);
std::string addr2 = "[::1]"; std::string addr2 = "[::1]";
Address address7(addr2, Port(8080)); Address address7(addr2, Port(8080));
ASSERT_EQ(address7.host(), "[::1]"); ASSERT_EQ(address7.host(), "::1");
ASSERT_EQ(address7.port(), 8080); ASSERT_EQ(address7.port(), 8080);
Address address8(Ipv6(0, 0, 0, 0, 0, 0, 0, 1), Port(8080)); Address address8(Ipv6(0, 0, 0, 0, 0, 0, 0, 1), Port(8080));
ASSERT_EQ(address8.host(), "[::1]"); ASSERT_EQ(address8.host(), "::1");
ASSERT_EQ(address8.port(), 8080); ASSERT_EQ(address8.port(), 8080);
Address address9(Ipv6::any(), Port(8080)); Address address9(Ipv6::any(), Port(8080));
ASSERT_EQ(address9.host(), "[::]"); ASSERT_EQ(address9.host(), "::");
ASSERT_EQ(address9.port(), 8080); ASSERT_EQ(address9.port(), 8080);
Address address10("[::]:8080"); Address address10("[::]:8080");
ASSERT_EQ(address10.host(), "[::]"); ASSERT_EQ(address10.host(), "::");
ASSERT_EQ(address10.port(), 8080); ASSERT_EQ(address10.port(), 8080);
Address address11("[2001:0DB8:AABB:CCDD:EEFF:0011:2233:4455]:8080"); Address address11("[2001:0DB8:AABB:CCDD:EEFF:0011:2233:4455]:8080");
ASSERT_EQ(address11.host(), "[2001:0DB8:AABB:CCDD:EEFF:0011:2233:4455]"); ASSERT_EQ(address11.host(), "2001:0DB8:AABB:CCDD:EEFF:0011:2233:4455");
ASSERT_EQ(address11.port(), 8080); ASSERT_EQ(address11.port(), 8080);
Address address12(Ipv4::loopback(), Port(8080));
ASSERT_EQ(address12.host(), "127.0.0.1");
ASSERT_EQ(address12.port(), 8080);
Address address13(Ipv6::loopback(), Port(8080));
ASSERT_EQ(address13.host(), "::1");
ASSERT_EQ(address13.port(), 8080);
} }
TEST(net_test, invalid_address) TEST(net_test, invalid_address)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment