diff options
author | Jaeseung Ha <ipknhama@gmail.com> | 2016-05-23 21:51:30 +0900 |
---|---|---|
committer | Jaeseung Ha <ipknhama@gmail.com> | 2016-05-23 21:51:30 +0900 |
commit | eb5a3b55f9e9b4077be7caeac67b403d345dc2d1 (patch) | |
tree | 75ed1a09a3d8504381f780e7b94a4b06e75098fc | |
parent | f96f65938dcf4d6ad7e6fd95a0cf5c3537970015 (diff) | |
parent | 1b1210685efc252e5e9053cb75e8e8ade7dc4371 (diff) | |
download | crow-eb5a3b55f9e9b4077be7caeac67b403d345dc2d1.tar.gz crow-eb5a3b55f9e9b4077be7caeac67b403d345dc2d1.zip |
Merge pull request #126 from gmaisto/master
Added support to bind to a specific interface
-rw-r--r-- | .gitignore | 1 | ||||
-rw-r--r-- | include/crow.h | 19 | ||||
-rw-r--r-- | include/http_server.h | 12 | ||||
-rw-r--r-- | tests/unittest.cpp | 105 |
4 files changed, 75 insertions, 62 deletions
@@ -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&) { } |