aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJaeseung Ha <ipknhama@gmail.com>2016-05-23 21:51:30 +0900
committerJaeseung Ha <ipknhama@gmail.com>2016-05-23 21:51:30 +0900
commiteb5a3b55f9e9b4077be7caeac67b403d345dc2d1 (patch)
tree75ed1a09a3d8504381f780e7b94a4b06e75098fc
parentf96f65938dcf4d6ad7e6fd95a0cf5c3537970015 (diff)
parent1b1210685efc252e5e9053cb75e8e8ade7dc4371 (diff)
downloadcrow-eb5a3b55f9e9b4077be7caeac67b403d345dc2d1.tar.gz
crow-eb5a3b55f9e9b4077be7caeac67b403d345dc2d1.zip
Merge pull request #126 from gmaisto/master
Added support to bind to a specific interface
-rw-r--r--.gitignore1
-rw-r--r--include/crow.h19
-rw-r--r--include/http_server.h12
-rw-r--r--tests/unittest.cpp105
4 files changed, 75 insertions, 62 deletions
diff --git a/.gitignore b/.gitignore
index f3e7b9f..6dcb0a2 100644
--- a/.gitignore
+++ b/.gitignore
@@ -32,3 +32,4 @@ unittest
build
.directory
+crow_all.h
diff --git a/include/crow.h b/include/crow.h
index ec4c0ee..31b96cb 100644
--- a/include/crow.h
+++ b/include/crow.h
@@ -9,7 +9,7 @@
#include <thread>
#include "settings.h"
-#include "logging.h"
+#include "logging.h"
#include "utility.h"
#include "routing.h"
#include "middleware_context.h"
@@ -64,6 +64,12 @@ namespace crow
return *this;
}
+ self_t& bindaddr(std::string bindaddr)
+ {
+ bindaddr_ = bindaddr;
+ return *this;
+ }
+
self_t& multithreaded()
{
return concurrency(std::thread::hardware_concurrency());
@@ -88,13 +94,13 @@ namespace crow
#ifdef CROW_ENABLE_SSL
if (use_ssl_)
{
- ssl_server_t server(this, port_, &middlewares_, concurrency_, &ssl_context_);
+ ssl_server_t server(this, bindaddr_, port_, &middlewares_, concurrency_, &ssl_context_);
server.run();
}
else
#endif
{
- server_t server(this, port_, &middlewares_, concurrency_, nullptr);
+ server_t server(this, bindaddr_, port_, &middlewares_, concurrency_, nullptr);
server.run();
}
}
@@ -151,7 +157,7 @@ namespace crow
// We can't call .ssl() member function unless CROW_ENABLE_SSL is defined.
static_assert(
// make static_assert dependent to T; always false
- std::is_base_of<T, void>::value,
+ std::is_base_of<T, void>::value,
"Define CROW_ENABLE_SSL to enable ssl support.");
return *this;
}
@@ -162,7 +168,7 @@ namespace crow
// We can't call .ssl() member function unless CROW_ENABLE_SSL is defined.
static_assert(
// make static_assert dependent to T; always false
- std::is_base_of<T, void>::value,
+ std::is_base_of<T, void>::value,
"Define CROW_ENABLE_SSL to enable ssl support.");
return *this;
}
@@ -187,7 +193,7 @@ namespace crow
private:
uint16_t port_ = 80;
uint16_t concurrency_ = 1;
-
+ std::string bindaddr_ = "0.0.0.0";
Router router_;
std::tuple<Middlewares...> middlewares_;
@@ -196,4 +202,3 @@ namespace crow
using App = Crow<Middlewares...>;
using SimpleApp = Crow<>;
};
-
diff --git a/include/http_server.h b/include/http_server.h
index 80ef7a4..4696450 100644
--- a/include/http_server.h
+++ b/include/http_server.h
@@ -20,16 +20,17 @@ namespace crow
{
using namespace boost;
using tcp = asio::ip::tcp;
-
+
template <typename Handler, typename Adaptor = SocketAdaptor, typename ... Middlewares>
class Server
{
public:
- Server(Handler* handler, uint16_t port, std::tuple<Middlewares...>* middlewares = nullptr, uint16_t concurrency = 1, typename Adaptor::context* adaptor_ctx = nullptr)
- : acceptor_(io_service_, tcp::endpoint(asio::ip::address(), port)),
+ Server(Handler* handler, std::string bindaddr, uint16_t port, std::tuple<Middlewares...>* middlewares = nullptr, uint16_t concurrency = 1, typename Adaptor::context* adaptor_ctx = nullptr)
+ : acceptor_(io_service_, tcp::endpoint(boost::asio::ip::address::from_string(bindaddr), port)),
signals_(io_service_, SIGINT, SIGTERM),
- handler_(handler),
+ handler_(handler),
concurrency_(concurrency),
+ bindaddr_(bindaddr),
port_(port),
middlewares_(middlewares),
adaptor_ctx_(adaptor_ctx)
@@ -145,7 +146,7 @@ namespace crow
is, handler_, server_name_, middlewares_,
get_cached_date_str_pool_[roundrobin_index_], *timer_queue_pool_[roundrobin_index_],
adaptor_ctx_);
- acceptor_.async_accept(p->socket(),
+ acceptor_.async_accept(p->socket(),
[this, p, &is](boost::system::error_code ec)
{
if (!ec)
@@ -171,6 +172,7 @@ namespace crow
uint16_t concurrency_{1};
std::string server_name_ = "Crow/0.1";
uint16_t port_;
+ std::string bindaddr_;
unsigned int roundrobin_index_{};
std::tuple<Middlewares...>* middlewares_;
diff --git a/tests/unittest.cpp b/tests/unittest.cpp
index d2cb231..164cbf0 100644
--- a/tests/unittest.cpp
+++ b/tests/unittest.cpp
@@ -48,7 +48,7 @@ void fail(Args...args) { error_print(args...);failed__ = true; }
} \
catch(std::exception&) \
{ \
- }
+ }
@@ -57,13 +57,17 @@ void fail(Args...args) { error_print(args...);failed__ = true; }
#define DISABLE_TEST(x) struct test##x{void test();}x##_; \
void test##x::test()
+
+#define LOCALHOST_ADDRESS "127.0.0.1"
+
+
TEST(Rule)
{
TaggedRule<> r("/http/");
r.name("abc");
// empty handler - fail to validate
- try
+ try
{
r.validate();
fail("empty handler should fail to validate");
@@ -310,22 +314,22 @@ TEST(http_method)
CROW_ROUTE(app, "/")
.methods("POST"_method, "GET"_method)
- ([](const request& req){
- if (req.method == "GET"_method)
- return "2";
- else
- return "1";
+ ([](const request& req){
+ if (req.method == "GET"_method)
+ return "2";
+ else
+ return "1";
});
CROW_ROUTE(app, "/get_only")
.methods("GET"_method)
- ([](const request& req){
- return "get";
+ ([](const request& req){
+ return "get";
});
CROW_ROUTE(app, "/post_only")
.methods("POST"_method)
- ([](const request& req){
- return "post";
+ ([](const request& req){
+ return "post";
});
@@ -382,13 +386,13 @@ TEST(server_handling_error_request)
static char buf[2048];
SimpleApp app;
CROW_ROUTE(app, "/")([]{return "A";});
- Server<SimpleApp> server(&app, 45451);
+ Server<SimpleApp> server(&app, LOCALHOST_ADDRESS, 45451);
auto _ = async(launch::async, [&]{server.run();});
std::string sendmsg = "POX";
asio::io_service is;
{
asio::ip::tcp::socket c(is);
- c.connect(asio::ip::tcp::endpoint(asio::ip::address::from_string("127.0.0.1"), 45451));
+ c.connect(asio::ip::tcp::endpoint(asio::ip::address::from_string(LOCALHOST_ADDRESS), 45451));
c.send(asio::buffer(sendmsg));
@@ -413,8 +417,8 @@ TEST(multi_server)
CROW_ROUTE(app1, "/").methods("GET"_method, "POST"_method)([]{return "A";});
CROW_ROUTE(app2, "/").methods("GET"_method, "POST"_method)([]{return "B";});
- Server<SimpleApp> server1(&app1, 45451);
- Server<SimpleApp> server2(&app2, 45452);
+ Server<SimpleApp> server1(&app1, LOCALHOST_ADDRESS, 45451);
+ Server<SimpleApp> server2(&app2, LOCALHOST_ADDRESS, 45452);
auto _ = async(launch::async, [&]{server1.run();});
auto _2 = async(launch::async, [&]{server2.run();});
@@ -423,7 +427,7 @@ TEST(multi_server)
asio::io_service is;
{
asio::ip::tcp::socket c(is);
- c.connect(asio::ip::tcp::endpoint(asio::ip::address::from_string("127.0.0.1"), 45451));
+ c.connect(asio::ip::tcp::endpoint(asio::ip::address::from_string(LOCALHOST_ADDRESS), 45451));
c.send(asio::buffer(sendmsg));
@@ -433,7 +437,7 @@ TEST(multi_server)
{
asio::ip::tcp::socket c(is);
- c.connect(asio::ip::tcp::endpoint(asio::ip::address::from_string("127.0.0.1"), 45452));
+ c.connect(asio::ip::tcp::endpoint(asio::ip::address::from_string(LOCALHOST_ADDRESS), 45452));
for(auto ch:sendmsg)
{
@@ -452,7 +456,7 @@ TEST(multi_server)
TEST(json_read)
{
{
- const char* json_error_tests[] =
+ const char* json_error_tests[] =
{
"{} 3", "{{}", "{3}",
"3.4.5", "+3", "3-2", "00", "03", "1e3e3", "1e+.3",
@@ -681,10 +685,11 @@ struct NullSimpleMiddleware
{}
};
+
TEST(middleware_simple)
{
App<NullMiddleware, NullSimpleMiddleware> app;
- decltype(app)::server_t server(&app, 45451);
+ decltype(app)::server_t server(&app, LOCALHOST_ADDRESS, 45451);
CROW_ROUTE(app, "/")([&](const crow::request& req)
{
app.get_context<NullMiddleware>(req);
@@ -714,9 +719,9 @@ std::vector<std::string> test_middleware_context_vector;
struct FirstMW
{
- struct context
- {
- std::vector<string> v;
+ struct context
+ {
+ std::vector<string> v;
};
void before_handle(request& req, response& res, context& ctx)
@@ -799,13 +804,13 @@ TEST(middleware_context)
return "";
});
- decltype(app)::server_t server(&app, 45451);
+ decltype(app)::server_t server(&app, LOCALHOST_ADDRESS, 45451);
auto _ = async(launch::async, [&]{server.run();});
std::string sendmsg = "GET /\r\n\r\n";
asio::io_service is;
{
asio::ip::tcp::socket c(is);
- c.connect(asio::ip::tcp::endpoint(asio::ip::address::from_string("127.0.0.1"), 45451));
+ c.connect(asio::ip::tcp::endpoint(asio::ip::address::from_string(LOCALHOST_ADDRESS), 45451));
c.send(asio::buffer(sendmsg));
@@ -828,7 +833,7 @@ TEST(middleware_context)
std::string sendmsg2 = "GET /break\r\n\r\n";
{
asio::ip::tcp::socket c(is);
- c.connect(asio::ip::tcp::endpoint(asio::ip::address::from_string("127.0.0.1"), 45451));
+ c.connect(asio::ip::tcp::endpoint(asio::ip::address::from_string(LOCALHOST_ADDRESS), 45451));
c.send(asio::buffer(sendmsg2));
@@ -865,13 +870,13 @@ TEST(middleware_cookieparser)
return "";
});
- decltype(app)::server_t server(&app, 45451);
+ decltype(app)::server_t server(&app, LOCALHOST_ADDRESS, 45451);
auto _ = async(launch::async, [&]{server.run();});
std::string sendmsg = "GET /\r\nCookie: key1=value1; key2=\"val\\\"ue2\"\r\n\r\n";
asio::io_service is;
{
asio::ip::tcp::socket c(is);
- c.connect(asio::ip::tcp::endpoint(asio::ip::address::from_string("127.0.0.1"), 45451));
+ c.connect(asio::ip::tcp::endpoint(asio::ip::address::from_string(LOCALHOST_ADDRESS), 45451));
c.send(asio::buffer(sendmsg));
@@ -895,7 +900,7 @@ TEST(bug_quick_repeated_request)
return "hello";
});
- decltype(app)::server_t server(&app, 45451);
+ decltype(app)::server_t server(&app, LOCALHOST_ADDRESS, 45451);
auto _ = async(launch::async, [&]{server.run();});
std::string sendmsg = "GET / HTTP/1.1\r\nHost: localhost\r\n\r\n";
asio::io_service is;
@@ -903,11 +908,11 @@ TEST(bug_quick_repeated_request)
std::vector<std::future<void>> v;
for(int i = 0; i < 5; i++)
{
- v.push_back(async(launch::async,
+ v.push_back(async(launch::async,
[&]
{
asio::ip::tcp::socket c(is);
- c.connect(asio::ip::tcp::endpoint(asio::ip::address::from_string("127.0.0.1"), 45451));
+ c.connect(asio::ip::tcp::endpoint(asio::ip::address::from_string(LOCALHOST_ADDRESS), 45451));
for(int j = 0; j < 5; j ++)
{
@@ -939,7 +944,7 @@ TEST(simple_url_params)
///params?h=1&foo=bar&lol&count[]=1&count[]=4&pew=5.2
- decltype(app)::server_t server(&app, 45451);
+ decltype(app)::server_t server(&app, LOCALHOST_ADDRESS, 45451);
auto _ = async(launch::async, [&]{server.run();});
asio::io_service is;
std::string sendmsg;
@@ -948,7 +953,7 @@ TEST(simple_url_params)
sendmsg = "GET /params\r\n\r\n";
{
asio::ip::tcp::socket c(is);
- c.connect(asio::ip::tcp::endpoint(asio::ip::address::from_string("127.0.0.1"), 45451));
+ c.connect(asio::ip::tcp::endpoint(asio::ip::address::from_string(LOCALHOST_ADDRESS), 45451));
c.send(asio::buffer(sendmsg));
c.receive(asio::buffer(buf, 2048));
c.close();
@@ -962,7 +967,7 @@ TEST(simple_url_params)
sendmsg = "GET /params?foobar\r\n\r\n";
{
asio::ip::tcp::socket c(is);
- c.connect(asio::ip::tcp::endpoint(asio::ip::address::from_string("127.0.0.1"), 45451));
+ c.connect(asio::ip::tcp::endpoint(asio::ip::address::from_string(LOCALHOST_ADDRESS), 45451));
c.send(asio::buffer(sendmsg));
c.receive(asio::buffer(buf, 2048));
c.close();
@@ -975,7 +980,7 @@ TEST(simple_url_params)
sendmsg = "GET /params?foo&bar&baz\r\n\r\n";
{
asio::ip::tcp::socket c(is);
- c.connect(asio::ip::tcp::endpoint(asio::ip::address::from_string("127.0.0.1"), 45451));
+ c.connect(asio::ip::tcp::endpoint(asio::ip::address::from_string(LOCALHOST_ADDRESS), 45451));
c.send(asio::buffer(sendmsg));
c.receive(asio::buffer(buf, 2048));
c.close();
@@ -989,10 +994,10 @@ TEST(simple_url_params)
sendmsg = "GET /params?hello=world\r\n\r\n";
{
asio::ip::tcp::socket c(is);
- c.connect(asio::ip::tcp::endpoint(asio::ip::address::from_string("127.0.0.1"), 45451));
+ c.connect(asio::ip::tcp::endpoint(asio::ip::address::from_string(LOCALHOST_ADDRESS), 45451));
c.send(asio::buffer(sendmsg));
c.receive(asio::buffer(buf, 2048));
- c.close();
+ c.close();
ASSERT_EQUAL(string(last_url_params.get("hello")), "world");
}
@@ -1000,7 +1005,7 @@ TEST(simple_url_params)
sendmsg = "GET /params?hello=world&left=right&up=down\r\n\r\n";
{
asio::ip::tcp::socket c(is);
- c.connect(asio::ip::tcp::endpoint(asio::ip::address::from_string("127.0.0.1"), 45451));
+ c.connect(asio::ip::tcp::endpoint(asio::ip::address::from_string(LOCALHOST_ADDRESS), 45451));
c.send(asio::buffer(sendmsg));
c.receive(asio::buffer(buf, 2048));
c.close();
@@ -1013,10 +1018,10 @@ TEST(simple_url_params)
sendmsg = "GET /params?int=100&double=123.45&boolean=1\r\n\r\n";
{
asio::ip::tcp::socket c(is);
- c.connect(asio::ip::tcp::endpoint(asio::ip::address::from_string("127.0.0.1"), 45451));
+ c.connect(asio::ip::tcp::endpoint(asio::ip::address::from_string(LOCALHOST_ADDRESS), 45451));
c.send(asio::buffer(sendmsg));
- c.receive(asio::buffer(buf, 2048));
- c.close();
+ c.receive(asio::buffer(buf, 2048));
+ c.close();
ASSERT_EQUAL(boost::lexical_cast<int>(last_url_params.get("int")), 100);
ASSERT_EQUAL(boost::lexical_cast<double>(last_url_params.get("double")), 123.45);
@@ -1027,11 +1032,11 @@ TEST(simple_url_params)
{
asio::ip::tcp::socket c(is);
- c.connect(asio::ip::tcp::endpoint(asio::ip::address::from_string("127.0.0.1"), 45451));
+ c.connect(asio::ip::tcp::endpoint(asio::ip::address::from_string(LOCALHOST_ADDRESS), 45451));
c.send(asio::buffer(sendmsg));
c.receive(asio::buffer(buf, 2048));
- c.close();
-
+ c.close();
+
ASSERT_TRUE(last_url_params.get("tmnt") == nullptr);
ASSERT_EQUAL(last_url_params.get_list("tmnt").size(), 1);
ASSERT_EQUAL(string(last_url_params.get_list("tmnt")[0]), "leonardo");
@@ -1041,11 +1046,11 @@ TEST(simple_url_params)
{
asio::ip::tcp::socket c(is);
- c.connect(asio::ip::tcp::endpoint(asio::ip::address::from_string("127.0.0.1"), 45451));
+ c.connect(asio::ip::tcp::endpoint(asio::ip::address::from_string(LOCALHOST_ADDRESS), 45451));
c.send(asio::buffer(sendmsg));
c.receive(asio::buffer(buf, 2048));
- c.close();
-
+ c.close();
+
ASSERT_EQUAL(last_url_params.get_list("tmnt").size(), 3);
ASSERT_EQUAL(string(last_url_params.get_list("tmnt")[0]), "leonardo");
ASSERT_EQUAL(string(last_url_params.get_list("tmnt")[1]), "donatello");
@@ -1081,7 +1086,7 @@ TEST(route_dynamic)
return "";
});
- try
+ try
{
app.route_dynamic("/invalid_test/<double>/<path>")
([](){
@@ -1089,17 +1094,17 @@ TEST(route_dynamic)
});
fail();
}
- catch(std::exception&)
+ catch(std::exception&)
{
}
// app is in an invalid state when route_dynamic throws an exception.
- try
+ try
{
app.validate();
fail();
}
- catch(std::exception&)
+ catch(std::exception&)
{
}