0xdead4ead / beasthttp Goto Github PK
View Code? Open in Web Editor NEWProvides helper tools for creating RESTful services using Boost.Beast
License: BSD 2-Clause "Simplified" License
Provides helper tools for creating RESTful services using Boost.Beast
License: BSD 2-Clause "Simplified" License
I use the following code to create a modular route.
http::basic_router<http_session> router{std::regex::ECMAScript};
http::basic_router<http_session> router__{std::regex::ECMAScript};
router__.get(R"(^/$)", [](http_request beast_http_request, http_context context) {
context.send(make_200<beast::http::string_body>(beast_http_request, "Main page\n", "text/html"));
});
router.use(R"(/animal$)", router__);
I get this error :
bazel-out/darwin-fastbuild/bin/external/beast_http/_virtual_includes/beast_http/http/base/impl/router.hxx:64:28: error: indirection requires pointer operand ('const _0xdead4ead::http::base::cb::storage<_0xdead4ead::http::reactor::session<boost::beast::http::basic_string_body<char, std::__1::char_traits<char>, std::__1::allocator<char> >, boost::beast::http::parser<true, boost::beast::http::basic_string_body<char, std::__1::char_traits<char>, std::__1::allocator<char> >, std::__1::allocator<char> >, boost::beast::http::serializer<false, boost::beast::http::basic_string_body<char, std::__1::char_traits<char>, std::__1::allocator<char> >, boost::beast::http::basic_fields<std::__1::allocator<char> > >, boost::beast::basic_flat_buffer<std::__1::allocator<char> >, boost::asio::ip::tcp, boost::asio::basic_stream_socket<boost::asio::ip::tcp, boost::asio::executor>, std::__1::chrono::steady_clock, boost::asio::basic_waitable_timer<std::__1::chrono::steady_clock, boost::asio::wait_traits<std::__1::chrono::steady_clock>, boost::asio::executor>, std::function, std::vector, std::map, std::unordered_map, std::function, std::function>, function, vector>' invalid) auto storage = *value.second; ^~~~~~~~~~~~~ bazel-out/darwin-fastbuild/bin/external/beast_http/_virtual_includes/beast_http/http/basic_router.hxx:368:20: note: in instantiation of member function '_0xdead4ead::http::base::router<_0xdead4ead::http::reactor::session<boost::beast::http::basic_string_body<char, std::__1::char_traits<char>, std::__1::allocator<char> >, boost::beast::http::parser<true, boost::beast::http::basic_string_body<char, std::__1::char_traits<char>, std::__1::allocator<char> >, std::__1::allocator<char> >, boost::beast::http::serializer<false, boost::beast::http::basic_string_body<char, std::__1::char_traits<char>, std::__1::allocator<char> >, boost::beast::http::basic_fields<std::__1::allocator<char> > >, boost::beast::basic_flat_buffer<std::__1::allocator<char> >, boost::asio::ip::tcp, boost::asio::basic_stream_socket<boost::asio::ip::tcp, boost::asio::executor>, std::__1::chrono::steady_clock, boost::asio::basic_waitable_timer<std::__1::chrono::steady_clock, boost::asio::wait_traits<std::__1::chrono::steady_clock>, boost::asio::executor>, std::function, std::vector, std::map, std::unordered_map, std::function, std::function> >::use' requested here base_type::use(path_to_resource, other); ^ src/server.cpp:21:12: note: in instantiation of member function '_0xdead4ead::http::basic_router<_0xdead4ead::http::reactor::session<boost::beast::http::basic_string_body<char, std::__1::char_traits<char>, std::__1::allocator<char> >, boost::beast::http::parser<true, boost::beast::http::basic_string_body<char, std::__1::char_traits<char>, std::__1::allocator<char> >, std::__1::allocator<char> >, boost::beast::http::serializer<false, boost::beast::http::basic_string_body<char, std::__1::char_traits<char>, std::__1::allocator<char> >, boost::beast::http::basic_fields<std::__1::allocator<char> > >, boost::beast::basic_flat_buffer<std::__1::allocator<char> >, boost::asio::ip::tcp, boost::asio::basic_stream_socket<boost::asio::ip::tcp, boost::asio::executor>, std::__1::chrono::steady_clock, boost::asio::basic_waitable_timer<std::__1::chrono::steady_clock, boost::asio::wait_traits<std::__1::chrono::steady_clock>, boost::asio::executor>, std::function, std::vector, std::map, std::unordered_map, std::function, std::function> >::use' requested here router.use(R"(/animal$)", router__); ^ In file included from src/server.cpp:1: In file included from src/utils.hpp:4: In file included from bazel-out/darwin-fastbuild/bin/external/beast_http/_virtual_includes/beast_http/http/basic_router.hxx:4: In file included from bazel-out/darwin-fastbuild/bin/external/beast_http/_virtual_includes/beast_http/http/base/router.hxx:110: bazel-out/darwin-fastbuild/bin/external/beast_http/_virtual_includes/beast_http/http/base/impl/router.hxx:76:32: error: indirection requires pointer operand ('const _0xdead4ead::http::base::cb::storage<_0xdead4ead::http::reactor::session<boost::beast::http::basic_string_body<char, std::__1::char_traits<char>, std::__1::allocator<char> >, boost::beast::http::parser<true, boost::beast::http::basic_string_body<char, std::__1::char_traits<char>, std::__1::allocator<char> >, std::__1::allocator<char> >, boost::beast::http::serializer<false, boost::beast::http::basic_string_body<char, std::__1::char_traits<char>, std::__1::allocator<char> >, boost::beast::http::basic_fields<std::__1::allocator<char> > >, boost::beast::basic_flat_buffer<std::__1::allocator<char> >, boost::asio::ip::tcp, boost::asio::basic_stream_socket<boost::asio::ip::tcp, boost::asio::executor>, std::__1::chrono::steady_clock, boost::asio::basic_waitable_timer<std::__1::chrono::steady_clock, boost::asio::wait_traits<std::__1::chrono::steady_clock>, boost::asio::executor>, std::function, std::vector, std::map, std::unordered_map, std::function, std::function>, function, vector>' invalid) auto storage = *value_r.second;
Essentially it looks like line :
is causing some issue.C++ 11; Bazel; Mac
Hi,
-- The CXX compiler identification is GNU 5.4.0 -- Check for working CXX compiler: /usr/bin/c++ -- Check for working CXX compiler: /usr/bin/c++ -- works -- Detecting CXX compiler ABI info -- Detecting CXX compiler ABI info - done -- Detecting CXX compile features -- Detecting CXX compile features - done -- Looking for C++ include pthread.h -- Looking for C++ include pthread.h - found -- Looking for pthread_create -- Looking for pthread_create - not found -- Looking for pthread_create in pthreads -- Looking for pthread_create in pthreads - not found -- Looking for pthread_create in pthread -- Looking for pthread_create in pthread - found -- Found Threads: TRUE -- Boost version: 1.69.0 -- Found the following Boost libraries: -- system -- thread -- chrono -- date_time -- atomic CXX=/usr/bin/c++ CXXFLAGS= -std=c++14 -Wall CMAKE_BUILD_TYPE=Debug -- Found OpenSSL: /usr/lib/x86_64-linux-gnu/libcrypto.so (found version "1.0.2g") found components: SSL Crypto -- Boost version: 1.69.0 -- Found the following Boost libraries: -- unit_test_framework -- Boost version: 1.69.0 -- Found the following Boost libraries: -- unit_test_framework -- Boost version: 1.69.0 -- Found the following Boost libraries: -- unit_test_framework -- Boost version: 1.69.0 -- Found the following Boost libraries: -- unit_test_framework -- Configuring done -- Generating done
/home/sp/imx_unification/tmp/ClionProjects/httpbeast/BeastHttp/BeastHttp/src/examples/reactor/main.cxx: In instantiation of ‘main()::<lambda(auto:41)> [with auto:41 = boost::asio::basic_stream_socketboost::asio::ip::tcp]’:
/home/sp/imx_unification/tmp/ClionProjects/httpbeast/BeastHttp/BeastHttp/src/../include/http/base/traits.hxx:448:37: required by substitution of ‘template<class auto:1, class ... auto:2> _0xdead4ead::http::base::traits::detail::tryInvoke(F&&, Args&& ...)::<lambda(auto:1&&, auto:2&& ...)> [with auto:1 = const main()::<lambda(auto:41)>&; auto:2 = {boost::asio::basic_stream_socketboost::asio::ip::tcp}]’
/home/sp/imx_unification/tmp/ClionProjects/httpbeast/BeastHttp/BeastHttp/src/../include/http/base/traits.hxx:32:26: required by substitution of ‘template<class R, class F, class ... Args> typename std::enable_if<(std::is_convertible<typename _0xdead4ead::http::base::traits::detail::invoke_result<decltype (f)(decltype (args)...)>::type, R>::value || std::is_same<R, void>::value), std::integral_constant<bool, true> >::type _0xdead4ead::http::base::traits::detail::is_invocable_impl(F&&, int, Args&& ...) [with R = void; F = _0xdead4ead::http::base::traits::detail::tryInvoke(F&&, Args&& ...) [with R = void; F = const main()::<lambda(auto:41)>&; Args = {boost::asio::basic_stream_socketboost::asio::ip::tcp}]::<lambda(auto:1&&, auto:2&& ...)>; Args = {const main()::<lambda(auto:41)>&, boost::asio::basic_stream_socketboost::asio::ip::tcp}]’
/home/sp/imx_unification/tmp/ClionProjects/httpbeast/BeastHttp/BeastHttp/src/../include/http/base/traits.hxx:56:36: required from ‘struct _0xdead4ead::http::base::traits::detail::is_invocable<_0xdead4ead::http::base::traits::detail::tryInvoke(F&&, Args&& ...) [with R = void; F = const main()::<lambda(auto:41)>&; Args = {boost::asio::basic_stream_socketboost::asio::ip::tcp}]::<lambda(auto:1&&, auto:2&& ...)>, void(const main()::<lambda(auto:41)>&, boost::asio::basic_stream_socketboost::asio::ip::tcp&&)>’
/home/sp/imx_unification/tmp/ClionProjects/httpbeast/BeastHttp/BeastHttp/src/../include/http/base/traits.hxx:432:55: required from ‘constexpr auto _0xdead4ead::http::base::traits::detail::validity_checker<R, F>::operator()(Args&& ...) const [with Args = {const main()::<lambda(auto:41)>&, boost::asio::basic_stream_socketboost::asio::ip::tcp}; R = void; F = _0xdead4ead::http::base::traits::detail::tryInvoke(F&&, Args&& ...) [with R = void; F = const main()::<lambda(auto:41)>&; Args = {boost::asio::basic_stream_socketboost::asio::ip::tcp}]::<lambda(auto:1&&, auto:2&& ...)>]’
/home/sp/imx_unification/tmp/ClionProjects/httpbeast/BeastHttp/BeastHttp/src/../include/http/base/traits.hxx:449:13: required from ‘constexpr auto _0xdead4ead::http::base::traits::detail::tryInvoke(F&&, Args&& ...) [with R = void; F = const main()::<lambda(auto:41)>&; Args = {boost::asio::basic_stream_socketboost::asio::ip::tcp}]’
/home/sp/imx_unification/tmp/ClionProjects/httpbeast/BeastHttp/BeastHttp/src/../include/http/base/traits.hxx:746:37: required from ‘struct _0xdead4ead::http::base::traits::TryInvoke<const main()::<lambda(auto:41)>&, void(boost::asio::basic_stream_socketboost::asio::ip::tcp)>’
/home/sp/imx_unification/tmp/ClionProjects/httpbeast/BeastHttp/BeastHttp/src/../include/http/reactor/impl/listener.hxx:31:1: required by substitution of ‘template _0xdead4ead::http::reactor::listener<OnAccept, OnError, Protocol, Acceptor, Socket, Endpoint>::listener(_0xdead4ead::http::reactor::listener<OnAccept, OnError, Protocol, Acceptor, Socket, Endpoint>::io_context&, _OnAccept&&, typename std::enable_if<_0xdead4ead::http::base::traits::TryInvoke<_OnAccept, void(Socket)>::value, int>::type) [with _OnAccept = const main()::<lambda(auto:41)>&]’
/home/sp/imx_unification/tmp/ClionProjects/httpbeast/BeastHttp/BeastHttp/src/../include/http/reactor/impl/listener.hxx:22:77: required by substitution of ‘template<class ... _OnAction> static decltype ((_0xdead4ead::http::reactor::listener<OnAccept, OnError, Protocol, Acceptor, Socket, Endpoint>::self_type{declval<_0xdead4ead::http::reactor::listener<OnAccept, OnError, Protocol, Acceptor, Socket, Endpoint>::io_context&>(), (declval<_OnAction>)()...}, void())) _0xdead4ead::http::reactor::listener<OnAccept, OnError, Protocol, Acceptor, Socket, Endpoint>::launch(_0xdead4ead::http::reactor::listener<OnAccept, OnError, Protocol, Acceptor, Socket, Endpoint>::io_context&, const endpoint_type&, _OnAction&& ...) [with _OnAction = {const main()::<lambda(auto:41)>&, const main()::<lambda(auto:39, auto:40)>&}]’
/home/sp/imx_unification/tmp/ClionProjects/httpbeast/BeastHttp/BeastHttp/src/examples/reactor/main.cxx:97:65: required from here
/home/sp/imx_unification/tmp/ClionProjects/httpbeast/BeastHttp/BeastHttp/src/examples/reactor/main.cxx:86:26: error: no matching function for call to ‘_0xdead4ead::http::reactor::session<>::recv(std::remove_reference<boost::asio::basic_stream_socketboost::asio::ip::tcp&>::type, _0xdead4ead::http::basic_router<_0xdead4ead::http::reactor::session<> >&, const main()::<lambda(auto:39, auto:40)>&)’
HttpSession::recv(std::move(asioSocket), router, onError);
when i try to build it in windows with vs2019 (use Clion as IDE).
it have many error #37 #34 #33
after i fix above issue in my this folk https://github.com/Lyoko-Jeremie/BeastHttp Lyoko-Jeremie@f3c6e98 Lyoko-Jeremie@4d273be Lyoko-Jeremie@ca4b4be Lyoko-Jeremie@6121cba , i get new error static_assert "Invalid session type!"
from class request_processor
i want to use this framework in windows , but seems like it need some adapter work for msvc and windows . can you help me ?
As you see,I want to use beasthttp on windows platform. Is that OK ?
Very cool library; thanks for writing!
One issue: I went through the examples, but did not see any that processed post requests, only gets. Could an example of accepting a post request be added?
(I see that POST requests are supported in the unit tests; working through understanding those now.)
It'd be great if this library could also support HTTP/2. If this library's still being maintained, please consider doing this.
I also have another query: I have this web server I wrote in Boost.Beast that I'd like to port to this library if possible. I have an "unknown protocol" error from the ClientHello that I think is because of a pending HTTP/2 upgrade request, so I tried to look into setting ALPN for that but I haven't had had much luck in finding good examples for implementing the callbacks some of the OpenSSL API functions for this expect. If someone could write a library that builds and works well on Windows and that also takes care of that or at least has working examples showing how to do it, that'd be great.
hi, how do you like this idea?
Your readme says its C++14 but in CMakeLists.txt you require C++17?
How do you verify the server certificate against the domain when establishing an HTTPS connection?
when i try the code of BeastHttp/src/examples/reactor/main.cxx
in vs2019 . it tell me warning C4067: unexpected tokens following preprocessor directive - expected a newline
.
and i check it, the listener.hxx(1) is : #if not defined BEASTHTTP_REACTOR_LISTENER_HXX
when i change it to #ifndef BEASTHTTP_REACTOR_LISTENER_HXX
, the error disappear .
seems like the msvc c++ not support #if not defined
, only support #ifndef
.
can change all the #if not defined
to #ifndef
to support msvc ?
follow is some of the error info :
H:\Code\CLionProjects\VorzeControlServer\src\3thlib\BeastHttp\BeastHttp\include\http/reactor/listener.hxx(1): warning C4067: unexpected tokens following preprocessor directive - expected a newline
H:\Code\CLionProjects\VorzeControlServer\src\3thlib\BeastHttp\BeastHttp\include\http/reactor/session.hxx(1): warning C4067: unexpected tokens following preprocessor directive - expected a newline
H:\Code\CLionProjects\VorzeControlServer\src\3thlib\BeastHttp\BeastHttp\include\http/basic_router.hxx(1): warning C4067: unexpected tokens following preprocessor directive - expected a newline
H:\Code\CLionProjects\VorzeControlServer\src\3thlib\BeastHttp\BeastHttp\include\http/out.hxx(1): warning C4067: unexpected tokens following preprocessor directive - expected a newline
H:\Code\CLionProjects\VorzeControlServer\src\main.cpp(112): error C2871: "_0xdead4ead" : a namespace with this name does not exist
H:\Code\CLionProjects\VorzeControlServer\src\main.cpp(114): error C2871: "http" : a namespace with this name does not exist
Make it possible to create Websocket (plain/SSL) session. (Other repository!)
So, I am used to webservers always having SO_REUSEADDR, but right now BeastHttp is going out of its way to disable this feature. If nothing else, you have the problem that if the server dies for some reason, you are unable to start it again until all of the sockets it previously had exit the TIME_WAIT state, which is pure devastating downtime (you just can't start the server due to "system:48 bind/loop").
I would think if this value is to be hardcoded it should hardcoded to true, not false. FWIW, Apache firmly turns this on for all platforms other than Windows (where the behavior of the flag is apparently both different and unnecessary? so not turning it on on Windows is equivalent to turning it on on Linux, but turning it on on Windows is more like SO_REUSEPORT; see warmcat/libwebsockets#65).
static apr_status_t make_sock(apr_pool_t *p, ap_listen_rec *server)
{
apr_socket_t *s = server->sd;
int one = 1;
...
#ifndef WIN32
stat = apr_socket_opt_set(s, APR_SO_REUSEADDR, one);
if (stat != APR_SUCCESS && stat != APR_ENOTIMPL) {
ap_log_perror(APLOG_MARK, APLOG_CRIT, stat, p, APLOGNO(00067)
"make_sock: for address %pI, apr_socket_opt_set: (SO_REUSEADDR)",
server->bind_addr);
apr_socket_close(s);
return stat;
}
#endif
(Frankly, I'd think that Boost should fix that upstream, though, with reuse_address being a no-op on Windows and binding it under some different name. FWIW, if you want to do a special case in this code, I'd highly recommend having the code turn SO_EXCLUSIVEADDRUSE on on Windows, to prevent the ability to use the Windows SO_REUSEADDR to hijack the port from a running instance.)
Here is a list of links to the code from various web servers showing they all turn this feature on, as well as a citation from Unix Network Programming, which asserts "all TCP servers should specify this socket option to allow the server to be restarted in this situation" (though the context in the original book is subtly different--a server that implements post-fork--it still applies as you might fork).
https://stackoverflow.com/questions/6960219/why-not-using-so-reuseaddr-on-unix-tcp-ip-servers
说明说要求最低c++11,但是尝试下来在windows平台编译不过
如果说平台差异那么仅仅是特有的一些函数可能不过 ,但是很多语法感觉都编译不过
例如listener.hxx:112
_OnAccept, void(socket_type)>::value and
base::traits::TryInvoke<_OnError, void(
boost::system::error_code, boost::string_view)>::value, int>::type)
目前好像c++没看到过有and语法
感觉整个项目通用性不强
Hi
With this framework is it possible to connect to a REST SSL endpoint and do multiple GET requests without disconnecting, for example (using the example code as and
this is an excerpt from the SSL example...
http::ssl::client my_https_client{ctx};
const auto & host = "www.google.com";
uint32_t port = 443;
const auto & on_connect = [](auto & session){
http::base::out("Successful connected!");
session.do_handshake();
};
const auto & on_handshake = [&host](auto & session){
http::base::out("Successful handshake!");
boost::beast::http::request<boost::beast::http::string_body> req;
req.version(11); // HTTP 1.1
req.method(boost::beast::http::verb::get); // GET
req.target("/ENDPOINT1");
req.set(boost::beast::http::field::host, host);
req.set(boost::beast::http::field::user_agent, BOOST_BEAST_VERSION_STRING);
session.do_write(std::move(req));
};
const auto & on_receive = [](auto & res, auto & session){
cout << res << endl;
// session.do_close();
http::base::processor::get().stop();
};
my_https_client.invoke(host, port, on_connect, on_handshake, on_receive);
uint32_t pool_size = boost::thread::hardware_concurrency();
http::base::processor::get().start(pool_size == 0 ? 4 : pool_size << 1);
http::base::processor::get().wait();
return 0;
}
If i make the changes above (not close the session in the on_receive lambda) is there a way i can
do something like send a request to a different endpoint (on the same host) without closing the connection?
That makes downloading releases slightly less obvious (like you need to get a commit hash to target a specific version, and you cannot clone a specific version with a single command anymore)
I have been setting up to run clang-tidy against my codebase, and during my "this isn't even integrated into my build environment yet" one-off test of a totally unconfigured clang-tidy, it popped up with a single issue that seems to be a legitimate error in this codebase ;P.
session::handshake returns something that kind of feels like a typo--a decltype over a comma expression, though I'm guessing you are doing that as a different way to simulate std::enable_if?--resulting in what is effectively decltype(std::declval<context_type>())
, which definitely isn't how std::declval is supposed to be used, and results in an r-value reference.
You then std::move a stack variable into that r-value reference, but the stack variable is going to be deallocated before anyone can consume that. Without having read any of the rest of the code, I feel like maybe you actually wanting to return a concrete context_type, to which you don't need to std::move (as you will get a named return value optimization on the result).
Regardless, here is the output from clang-tidy.
./BeastHttp/BeastHttp/include/http/reactor/ssl/impl/session.hxx:671:5: warning: Address of stack memory associated with local variable 'ctx_' returned to caller [clang-analyzer-core.StackAddressEscape]
return std::move(ctx_);
^
server.cpp:746:9: note: Calling 'session::handshake'
SslHttpSession::handshake(context, std::move(socket), router, [](auto context) {
^
./BeastHttp/BeastHttp/include/http/reactor/ssl/impl/session.hxx:684:12: note: Calling 'session::handshake'
return handshake(ctx, std::move(socket), router, std::move(buffer),
^
./BeastHttp/BeastHttp/include/http/reactor/ssl/impl/session.hxx:671:5: note: Address of stack memory associated with local variable 'ctx_' returned to caller
return std::move(ctx_);
^
Suppressed 1 warnings (1 in non-user code).
with this define I can't compile the project:
add_definitions(-DBOOST_ASIO_NO_DEPRECATED=1)
Claus-iMac:.build-src-Debug clausklein$ ninja -j 1 -v
[1/12] /usr/local/bin/ccache /usr/bin/c++ -DBOOST_ALL_NO_LIB -DBOOST_ASIO_NO_DEPRECATED=1 -DBOOST_ASIO_SEPARATE_COMPILATION=1 -DBOOST_BEAST_SEPARATE_COMPILATION=1 -DBOOST_SYSTEM_DYN_LINK -DBOOST_THREAD_DYN_LINK -I/Users/clausklein/Workspace/cpp/BeastHttp/BeastHttp/src/../include -isystem /usr/local/Cellar/boost/1.72.0_2/include -isystem /usr/local/opt/openssl/include -isystem /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include/c++/v1 -isystem /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/lib/clang/11.0.3/include -isystem /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.15.sdk/usr/include -isystem /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include -std=c++17 -Wall -Wextra -Wpedantic -g -isysroot /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.15.sdk -Wall -Wextra -Wpedantic -Wno-unknown-warning-option "-Wno-#pragma-messages" -Wno-deprecated-declarations -Wno-unused-parameter -Wno-unused-variable -std=c++17 -MD -MT examples/reactor_flex/CMakeFiles/reactor_flex.dir/main.o -MF examples/reactor_flex/CMakeFiles/reactor_flex.dir/main.d -o examples/reactor_flex/CMakeFiles/reactor_flex.dir/main.o -c /Users/clausklein/Workspace/cpp/BeastHttp/BeastHttp/src/examples/reactor_flex/main.cxx
FAILED: examples/reactor_flex/CMakeFiles/reactor_flex.dir/main.o
/usr/local/bin/ccache /usr/bin/c++ -DBOOST_ALL_NO_LIB -DBOOST_ASIO_NO_DEPRECATED=1 -DBOOST_ASIO_SEPARATE_COMPILATION=1 -DBOOST_BEAST_SEPARATE_COMPILATION=1 -DBOOST_SYSTEM_DYN_LINK -DBOOST_THREAD_DYN_LINK -I/Users/clausklein/Workspace/cpp/BeastHttp/BeastHttp/src/../include -isystem /usr/local/Cellar/boost/1.72.0_2/include -isystem /usr/local/opt/openssl/include -isystem /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include/c++/v1 -isystem /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/lib/clang/11.0.3/include -isystem /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.15.sdk/usr/include -isystem /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include -std=c++17 -Wall -Wextra -Wpedantic -g -isysroot /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.15.sdk -Wall -Wextra -Wpedantic -Wno-unknown-warning-option "-Wno-#pragma-messages" -Wno-deprecated-declarations -Wno-unused-parameter -Wno-unused-variable -std=c++17 -MD -MT examples/reactor_flex/CMakeFiles/reactor_flex.dir/main.o -MF examples/reactor_flex/CMakeFiles/reactor_flex.dir/main.d -o examples/reactor_flex/CMakeFiles/reactor_flex.dir/main.o -c /Users/clausklein/Workspace/cpp/BeastHttp/BeastHttp/src/examples/reactor_flex/main.cxx
# ...
/Users/clausklein/Workspace/cpp/BeastHttp/BeastHttp/src/../include/http/reactor/ssl/session.hxx:56:71: warning: token pasting of ',' and __VA_ARGS__ is a GNU extension [-Wgnu-zero-variadic-macro-arguments]
In file included from /Users/clausklein/Workspace/cpp/BeastHttp/BeastHttp/src/examples/reactor_flex/main.cxx:2:
In file included from /Users/clausklein/Workspace/cpp/BeastHttp/BeastHttp/src/../include/http/reactor/session.hxx:11:
In file included from /Users/clausklein/Workspace/cpp/BeastHttp/BeastHttp/src/../include/http/base/timer.hxx:58:
/Users/clausklein/Workspace/cpp/BeastHttp/BeastHttp/src/../include/http/base/impl/timer.hxx:59:19: error: too many arguments to function call, expected 0, have 1
timer_.cancel(ec);
~~~~~~~~~~~~~ ^~
/Users/clausklein/Workspace/cpp/BeastHttp/BeastHttp/src/../include/http/common/impl/detect.hxx:300:22: note: in instantiation of member function '_0xdead4ead::http::base::timer<boost::asio::basic_waitable_timer<std::__1::chrono::steady_clock, boost::asio::wait_traits<std::__1::chrono::steady_clock>, boost::asio::executor>, boost::asio::strand<boost::asio::executor> >::cancel' requested here
auto ec = timer_.cancel();
^
/Users/clausklein/Workspace/cpp/BeastHttp/BeastHttp/src/../include/http/common/impl/detect.hxx:197:9: note: in instantiation of member function '_0xdead4ead::http::common::detect<boost::beast::basic_flat_buffer<std::__1::allocator<char> >, boost::asio::ip::tcp, boost::asio::basic_stream_socket<boost::asio::ip::tcp, boost::asio::executor>, std::__1::chrono::steady_clock, boost::asio::basic_waitable_timer<std::__1::chrono::steady_clock, boost::asio::wait_traits<std::__1::chrono::steady_clock>, boost::asio::executor>, std::function, std::function, std::function>::do_timer_cancel' requested here
do_timer_cancel();
^
/Users/clausklein/Workspace/cpp/BeastHttp/BeastHttp/src/../include/http/common/impl/detect.hxx:35:92: note: in instantiation of member function '_0xdead4ead::http::common::detect<boost::beast::basic_flat_buffer<std::__1::allocator<char> >, boost::asio::ip::tcp, boost::asio::basic_stream_socket<boost::asio::ip::tcp, boost::asio::executor>, std::__1::chrono::steady_clock, boost::asio::basic_waitable_timer<std::__1::chrono::steady_clock, boost::asio::wait_traits<std::__1::chrono::steady_clock>, boost::asio::executor>, std::function, std::function, std::function>::do_async' requested here
std::make_shared<self_type>(std::move(socket), std::forward<_OnAction>(on_action)...)->do_async();
^
/Users/clausklein/Workspace/cpp/BeastHttp/BeastHttp/src/examples/reactor_flex/main.cxx:201:21: note: in instantiation of function template specialization '_0xdead4ead::http::common::detect<boost::beast::basic_flat_buffer<std::__1::allocator<char> >, boost::asio::ip::tcp, boost::asio::basic_stream_socket<boost::asio::ip::tcp, boost::asio::executor>, std::__1::chrono::steady_clock, boost::asio::basic_waitable_timer<std::__1::chrono::steady_clock, boost::asio::wait_traits<std::__1::chrono::steady_clock>, boost::asio::executor>, std::function, std::function, std::function>::async<const (lambda at /Users/clausklein/Workspace/cpp/BeastHttp/BeastHttp/src/examples/reactor_flex/main.cxx:181:28) &, const (lambda at /Users/clausklein/Workspace/cpp/BeastHttp/BeastHttp/src/examples/reactor_flex/main.cxx:171:27) &>' requested here
ssl_detect::async(std::move(asio_socket), onDetect, onError);
^
/usr/local/Cellar/boost/1.72.0_2/include/boost/asio/basic_waitable_timer.hpp:361:3: note: 'cancel' declared here
std::size_t cancel()
^
18 warnings and 1 error generated.
ninja: build stopped: subcommand failed.
Claus-iMac:.build-src-Debug clausklein$
The first example in the USAGE section of the README.md does not compile. To wit, it is not clear which files must be #include'd in order to get it t run. After cycling through quite a different number of compile errors and header combinations, I got stuck here:
BeastHttp$ g++ --std=c++14 -Wfatal-errors -I./include -I../moetsi/dependencies/boost server.cpp -o runserver
In file included from server.cpp:6:0:
./include/reactor/listener.hxx:102:32: error: type/value mismatch at argument 4 in template parameter list for ‘template<template<class> class OnAccept, template<class> class OnError, class Protocol, template<class> class Acceptor, template<class> class Socket, template<class> class Endpoint> class _0xdead4ead::http::reactor::listener’
using listener_type = listener<>;
^
where server.cpp
consists of
#include <iostream>
#include <base/cb.hxx>
#include <base/regex.hxx>
#include <base/request_processor.hxx>
#include <reactor/listener.hxx>
#include <reactor/session.hxx>
#include <basic_router.hxx>
#include <out.hxx>
#include <boost/asio/posix/stream_descriptor.hpp>
#include <boost/asio/signal_set.hpp>
#include <thread>
#include <param.hxx>
#include <basic_router.hxx>
#include <chain_router.hxx>
#include <literals.hxx>
#include <boost/beast/http.hpp>
using namespace _0xdead4ead;
using HttpSession = http::reactor::_default::session_type;
using HttpListener = http::reactor::_default::listener_type;
int main()
{
http::basic_router<HttpSession> router;
router.get("^/$", [](auto request, auto context) {
context.send(make_response(request, "MAIN PAGE\n"));
});
}
I got a little closer by #include <unordered_map>
in session.hxx
, but still didn't get it to go through.
I am trying to complie the examples on the library and i am getting this error
error: incomplete type ‘boost::asio::execution::is_executor<_0xdead4ead::http::base::strand_stream>’ used in nested name specifier
476 | struct is_valid_target_executor :
| ^~~~~~~~~~~~~~~~~~~~~~~~
I happens then there is a reference to router or listener in the file. I have tried to solve it but failed. Thank you.
As I include your code into my own, you have files like <basic_router.hxx> which perhaps needs to be put in my syspath to work. However, more idiomatic would be a directory structure of the form <beast_http/basic_router.hxx>, which would allow visual distinction of dependency code.
Also, this would allow some understanding of what constitutes the public API, as currently I don't understand whether I should be #include'ing files in base/
reactor/
and shared/
.
I get a lot of warning like -Wreorder when I set the g++ -Wall option in CMakeLists.txt.
And I have looked code like this
BEASTHTTP_REACTOR_SESSION_TMPL_DECLARE
template<class _OnError, class _OnTimer>
session<BEASTHTTP_REACTOR_SESSION_TMPL_ATTRIBUTES>::flesh::flesh(
connection_type&& connection,
std::shared_ptr<resource_map_type> const& resource_map,
std::shared_ptr<method_map_type> const& method_map,
regex_flag_type flags,
buffer_type&& buffer,
_OnError&& on_error, _OnTimer&& on_timer,
typename std::enable_if<
base::traits::TryInvoke<_OnError,
void(boost::system::error_code,
const char*)>::value and
base::traits::TryInvoke<_OnTimer,
void(reference_wrapper)>::value, int>::type)
: base_type{resource_map, method_map, flags},
connection_{std::move(connection)},
timer_{connection.stream().get_executor(), (time_point_type::max)()},
on_error_{std::forward<_OnError>(on_error)},
on_timer_{std::forward<_OnTimer>(on_timer)},
buffer_{std::move(buffer)},
queue_{*this}
{
}
The "connection" variable was moved and used again。Will there be a problem with this?
Is this library still maintained? If yes are there any plans to update it? If no is there an alternative?
middlewares are great to check for credentials and permissions e.g. authentication and authorization.
auto authMiddleware = [](HttpRequest request, HttpContext context, auto iterator) {
if (request[boost::beast::http::field::authorization] != "my_token") {
context.send(make_401<boost::beast::http::string_body>(request));
} else {
std::next(iterator)();
}
};
const std::string route_base{R"(^/$)"};
http::basic_router<HttpSession> main_router{std::regex::ECMAScript};
const std::string route_api{R"(^/api/v0)"};
http::basic_router<HttpSession> api_router{std::regex::ECMAScript};
api_router.get("^[/]??$", [](auto request, auto context) {
context.send(make_200<boost::beast::http::string_body>(request, R"({"status": "ok"})"));
});
// this does work
api_router.get("^/asdf$",
std::bind(authMiddleware, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3),
[](auto request, auto context) {
context.send(make_200<boost::beast::http::string_body>(request, R"({"status": "ok"})"));
});
// this does not work
main_router.use(route_api, authMiddleware, api_router);
basically all routes would need authentication, instead of adding a middleware to all http methods
[user@ser_latitude VSCode]$ g++ -std=c++17 -o start_reactor -I/libs/backend/BeastHttp/BeastHttp/include -I/libs/boost/include/ main.cpp
In file included from /libs/boost/include/boost/asio/execution.hpp:19,
from /libs/boost/include/boost/asio/detail/strand_executor_service.hpp:27,
from /libs/boost/include/boost/asio/strand.hpp:19,
from /libs/backend/BeastHttp/BeastHttp/include/http/base/strand_stream.hxx:4,
from /libs/backend/BeastHttp/BeastHttp/include/http/reactor/listener.hxx:5,
from main.cpp:1:
/libs/boost/include/boost/asio/execution/any_executor.hpp: In instantiation of 'struct boost::asio::execution::detail::is_valid_target_executor<_0xdead4ead::http::base::strand_stream, void(boost::asio::execution::context_as_tboost::asio::execution_context&, boost::asio::execution::detail::blocking::never_t<0>, boost::asio::execution::prefer_only<boost::asio::execution::detail::blocking::possibly_t<0> >, boost::asio::execution::prefer_only<boost::asio::execution::detail::outstanding_work::tracked_t<0> >, boost::asio::execution::prefer_only<boost::asio::execution::detail::outstanding_work::untracked_t<0> >, boost::asio::execution::prefer_only<boost::asio::execution::detail::relationship::fork_t<0> >, boost::asio::execution::prefer_only<boost::asio::execution::detail::relationship::continuation_t<0> >)>':
/libs/boost/include/boost/asio/any_io_executor.hpp:145:3: required by substitution of 'template boost::asio::any_io_executor::any_io_executor(Executor, typename boost::asio::constraint<typename std::conditional<((! std::is_same<Executor, boost::asio::any_io_executor>::value) && (! std::is_base_of<boost::asio::execution::detail::any_executor_base, Executor>::value)), boost::asio::execution::detail::is_valid_target_executor<Executor, void(boost::asio::execution::context_as_tboost::asio::execution_context&, boost::asio::execution::detail::blocking::never_t<0>, boost::asio::execution::prefer_only<boost::asio::execution::detail::blocking::possibly_t<0> >, boost::asio::execution::prefer_only<boost::asio::execution::detail::outstanding_work::tracked_t<0> >, boost::asio::execution::prefer_only<boost::asio::execution::detail::outstanding_work::untracked_t<0> >, boost::asio::execution::prefer_only<boost::asio::execution::detail::relationship::fork_t<0> >, boost::asio::execution::prefer_only<boost::asio::execution::detail::relationship::continuation_t<0> >)>, std::integral_constant<bool, false> >::type::value>::type) [with Executor = _0xdead4ead::http::base::strand_stream]'
/usr/include/c++/11.2.0/type_traits:971:25: required by substitution of 'template<class _Tp, class ... _Args> using __is_nothrow_constructible_impl = std::__bool_constant<__is_nothrow_constructible(_Tp)> [with _Tp = _0xdead4ead::http::base::strand_stream; _Args = {const _0xdead4ead::http::base::strand_stream&}]'
/usr/include/c++/11.2.0/type_traits:1000:12: required from 'struct std::__is_nothrow_copy_constructible_impl<_0xdead4ead::http::base::strand_stream, true>'
/usr/include/c++/11.2.0/type_traits:1006:12: required from 'struct std::is_nothrow_copy_constructible<_0xdead4ead::http::base::strand_stream>'
/libs/boost/include/boost/asio/execution/executor.hpp:124:8: [ skipping 8 instantiation contexts, use -ftemplate-backtrace-limit=0 to disable ]
/libs/backend/BeastHttp/BeastHttp/include/http/base/traits.hxx:399:55: required from 'constexpr auto _0xdead4ead::http::base::traits::detail::validity_checker<R, F>::operator()(Args&& ...) const [with Args = {main()::<lambda(auto:29, auto:30)>, boost::beast::http::message<true, boost::beast::http::basic_string_body<char, std::char_traits, std::allocator >, boost::beast::http::basic_fields<std::allocator > >, _0xdead4ead::http::reactor::session<>::context<_0xdead4ead::http::reactor::session<>::flesh, _0xdead4ead::http::reactor::session<boost::beast::http::basic_string_body<char, std::char_traits, std::allocator >, boost::beast::http::parser<true, boost::beast::http::basic_string_body<char, std::char_traits, std::allocator >, std::allocator >, boost::beast::http::serializer<false, boost::beast::http::basic_string_body<char, std::char_traits, std::allocator >, boost::beast::http::basic_fields<std::allocator > >, boost::beast::basic_flat_buffer<std::allocator >, boost::asio::ip::tcp, boost::asio::basic_stream_socket<boost::asio::ip::tcp, boost::asio::any_io_executor>, std::chrono::_V2::steady_clock, boost::asio::basic_waitable_timer<std::chrono::_V2::steady_clock, boost::asio::wait_traitsstd::chrono::_V2::steady_clock, boost::asio::any_io_executor>, std::function, std::vector, std::map, std::unordered_map, std::function, std::function>::context_policy::shared>}; R = void; F = _0xdead4ead::http::base::traits::detail::tryInvoke<void, main()::<lambda(auto:29, auto:30)>, boost::beast::http::message<true, boost::beast::http::basic_string_body<char, std::char_traits, std::allocator >, boost::beast::http::basic_fields<std::allocator > >, _0xdead4ead::http::reactor::session<>::context<_0xdead4ead::http::reactor::session<>::flesh, _0xdead4ead::http::reactor::session<boost::beast::http::basic_string_body<char, std::char_traits, std::allocator >, boost::beast::http::parser<true, boost::beast::http::basic_string_body<char, std::char_traits, std::allocator >, std::allocator >, boost::beast::http::serializer<false, boost::beast::http::basic_string_body<char, std::char_traits, std::allocator >, boost::beast::http::basic_fields<std::allocator > >, boost::beast::basic_flat_buffer<std::allocator >, boost::asio::ip::tcp, boost::asio::basic_stream_socket<boost::asio::ip::tcp, boost::asio::any_io_executor>, std::chrono::_V2::steady_clock, boost::asio::basic_waitable_timer<std::chrono::_V2::steady_clock, boost::asio::wait_traitsstd::chrono::_V2::steady_clock, boost::asio::any_io_executor>, std::function, std::vector, std::map, std::unordered_map, std::function, std::function>::context_policy::shared> >(main()::<lambda(auto:29, auto:30)>&&, boost::beast::http::message<true, boost::beast::http::basic_string_body, boost::beast::http::basic_fields<std::allocator > >&&, _0xdead4ead::http::reactor::session<>::context<_0xdead4ead::http::reactor::session<>::flesh, _0xdead4ead::http::reactor::session<boost::beast::http::basic_string_body<char, std::char_traits, std::allocator >, boost::beast::http::parser<true, boost::beast::http::basic_string_body<char, std::char_traits, std::allocator >, std::allocator >, boost::beast::http::serializer<false, boost::beast::http::basic_string_body<char, std::char_traits, std::allocator >, boost::beast::http::basic_fields<std::allocator > >, boost::beast::basic_flat_buffer<std::allocator >, boost::asio::ip::tcp, boost::asio::basic_stream_socket<boost::asio::ip::tcp, boost::asio::any_io_executor>, std::chrono::_V2::steady_clock, boost::asio::basic_waitable_timer<std::chrono::_V2::steady_clock, boost::asio::wait_traitsstd::chrono::_V2::steady_clock, boost::asio::any_io_executor>, std::function, std::vector, std::map, std::unordered_map, std::function, std::function>::context_policy::shared>&&)::<lambda(auto:1&&, auto:2&& ...)>]'
/libs/backend/BeastHttp/BeastHttp/include/http/base/traits.hxx:416:13: required from 'constexpr auto _0xdead4ead::http::base::traits::detail::tryInvoke(F&&, Args&& ...) [with R = void; F = main()::<lambda(auto:29, auto:30)>; Args = {boost::beast::http::message<true, boost::beast::http::basic_string_body<char, std::char_traits, std::allocator >, boost::beast::http::basic_fields<std::allocator > >, _0xdead4ead::http::reactor::session<>::context<_0xdead4ead::http::reactor::session<>::flesh, _0xdead4ead::http::reactor::session<boost::beast::http::basic_string_body<char, std::char_traits, std::allocator >, boost::beast::http::parser<true, boost::beast::http::basic_string_body<char, std::char_traits, std::allocator >, std::allocator >, boost::beast::http::serializer<false, boost::beast::http::basic_string_body<char, std::char_traits, std::allocator >, boost::beast::http::basic_fields<std::allocator > >, boost::beast::basic_flat_buffer<std::allocator >, boost::asio::ip::tcp, boost::asio::basic_stream_socket<boost::asio::ip::tcp, boost::asio::any_io_executor>, std::chrono::_V2::steady_clock, boost::asio::basic_waitable_timer<std::chrono::_V2::steady_clock, boost::asio::wait_traitsstd::chrono::_V2::steady_clock, boost::asio::any_io_executor>, std::function, std::vector, std::map, std::unordered_map, std::function, std::function>::context_policy::shared>}]'
/libs/backend/BeastHttp/BeastHttp/include/http/base/traits.hxx:674:37: required from 'struct _0xdead4ead::http::base::traits::TryInvoke<main()::<lambda(auto:29, auto:30)>, void(boost::beast::http::message<true, boost::beast::http::basic_string_body, boost::beast::http::basic_fields<std::allocator > >, _0xdead4ead::http::reactor::session<>::context<_0xdead4ead::http::reactor::session<>::flesh, _0xdead4ead::http::reactor::session<boost::beast::http::basic_string_body<char, std::char_traits, std::allocator >, boost::beast::http::parser<true, boost::beast::http::basic_string_body<char, std::char_traits, std::allocator >, std::allocator >, boost::beast::http::serializer<false, boost::beast::http::basic_string_body<char, std::char_traits, std::allocator >, boost::beast::http::basic_fields<std::allocator > >, boost::beast::basic_flat_buffer<std::allocator >, boost::asio::ip::tcp, boost::asio::basic_stream_socket<boost::asio::ip::tcp, boost::asio::any_io_executor>, std::chrono::_V2::steady_clock, boost::asio::basic_waitable_timer<std::chrono::_V2::steady_clock, boost::asio::wait_traitsstd::chrono::_V2::steady_clock, boost::asio::any_io_executor>, std::function, std::vector, std::map, std::unordered_map, std::function, std::function>::context_policy::shared>)>'
/libs/backend/BeastHttp/BeastHttp/include/http/base/traits.hxx:689:55: required from 'constexpr const bool _0xdead4ead::http::base::traits::TryInvokeConjunction<0, void(boost::beast::http::message<true, boost::beast::http::basic_string_body, boost::beast::http::basic_fields<std::allocator > >, _0xdead4ead::http::reactor::session<>::context<_0xdead4ead::http::reactor::session<>::flesh, _0xdead4ead::http::reactor::session<boost::beast::http::basic_string_body<char, std::char_traits, std::allocator >, boost::beast::http::parser<true, boost::beast::http::basic_string_body<char, std::char_traits, std::allocator >, std::allocator >, boost::beast::http::serializer<false, boost::beast::http::basic_string_body<char, std::char_traits, std::allocator >, boost::beast::http::basic_fields<std::allocator > >, boost::beast::basic_flat_buffer<std::allocator >, boost::asio::ip::tcp, boost::asio::basic_stream_socket<boost::asio::ip::tcp, boost::asio::any_io_executor>, std::chrono::_V2::steady_clock, boost::asio::basic_waitable_timer<std::chrono::_V2::steady_clock, boost::asio::wait_traitsstd::chrono::_V2::steady_clock, boost::asio::any_io_executor>, std::function, std::vector, std::map, std::unordered_map, std::function, std::function>::context_policy::shared>, _0xdead4ead::http::base::cb::const_iterator<_0xdead4ead::http::reactor::session<>, std::function, std::vector>), void(boost::beast::http::message<true, boost::beast::http::basic_string_body, boost::beast::http::basic_fields<std::allocator > >, _0xdead4ead::http::reactor::session<>::context<_0xdead4ead::http::reactor::session<>::flesh, _0xdead4ead::http::reactor::session<boost::beast::http::basic_string_body<char, std::char_traits, std::allocator >, boost::beast::http::parser<true, boost::beast::http::basic_string_body<char, std::char_traits, std::allocator >, std::allocator >, boost::beast::http::serializer<false, boost::beast::http::basic_string_body<char, std::char_traits, std::allocator >, boost::beast::http::basic_fields<std::allocator > >, boost::beast::basic_flat_buffer<std::allocator >, boost::asio::ip::tcp, boost::asio::basic_stream_socket<boost::asio::ip::tcp, boost::asio::any_io_executor>, std::chrono::_V2::steady_clock, boost::asio::basic_waitable_timer<std::chrono::_V2::steady_clock, boost::asio::wait_traitsstd::chrono::_V2::steady_clock, boost::asio::any_io_executor>, std::function, std::vector, std::map, std::unordered_map, std::function, std::function>::context_policy::shared>), main()::<lambda(auto:29, auto:30)> >::value'
/libs/backend/BeastHttp/BeastHttp/include/http/base/cb.hxx:137:18: required by substitution of 'template<class F, class ... Fn, class> _0xdead4ead::http::base::cb::storage<_0xdead4ead::http::reactor::session<>, std::function, std::vector>::storage(F&&, Fn&& ...) [with F = main()::<lambda(auto:29, auto:30)>; Fn = {}; = void]'
/libs/backend/BeastHttp/BeastHttp/include/http/basic_router.hxx:59:23: required by substitution of 'template<class ... OnRequest> decltype ((void)((_0xdead4ead::http::basic_router<_0xdead4ead::http::reactor::session<> >::storage_type)((declval)()...))) _0xdead4ead::http::basic_router<_0xdead4ead::http::reactor::session<> >::post<OnRequest ...>(const resource_regex_type&, OnRequest&& ...) & [with OnRequest = {main()::<lambda(auto:29, auto:30)>}]'
main.cpp:32:16: required from here
/libs/boost/include/boost/asio/execution/any_executor.hpp:476:8: error: incomplete type 'boost::asio::execution::is_executor<_0xdead4ead::http::base::strand_stream>' used in nested name specifier
** 476 | struct is_valid_target_executor : **
| ^~~~~~~~~~~~~~~~~~~~~~~~
什么编译器支持的额,能不能改成通用点的#ifndef呢
When defining a route that contains parameters, it seems that the arguments parsing code is not thread safe (or I'm doing something horribly wrong and I cannot see it).
Setting the number of launched threads to 1 fixes the issue. Here's the code:
void web_server::run()
{
using namespace _0xdead4ead;
using http_session = http::reactor::_default::session_type;
using http_listener = http::reactor::_default::listener_type;
boost::asio::io_context ioc;
boost::asio::posix::stream_descriptor out{ioc, ::dup(STDERR_FILENO)};
boost::asio::signal_set sig_set(ioc, SIGINT, SIGTERM);
http::basic_router<http_session> router{std::regex::ECMAScript};
using pack2 = http::param::pack<int, std::string>;
router.param<pack2>().get("/api/mails/(\\d+)/(\\w+)",
[this](auto request, auto context, auto args) {
auto id = std::get<0>(args);
auto type = std::get<1>(args);
LOG4CXX_DEBUG(logger, "Got arguments id "<<id<<" and type "<<type<<" for url:"<<request.target().to_string());
context.send(/*some answer*/);
});
// ..onAccept and onError as in your examples
auto const address = boost::asio::ip::address_v4::any();
auto const port = static_cast<unsigned short>(8080);
uint32_t pool_size = std::thread::hardware_concurrency();
// Run the I/O service on the requested number of threads
std::vector<std::thread> threads;
threads.reserve(pool_size > 0 ? pool_size : 2);
for(uint32_t i = 0; i < pool_size; i++)
threads.emplace_back(std::bind(static_cast<std::size_t (boost::asio::io_context::*)()>
(&boost::asio::io_context::run), std::ref(ioc)));
// Block until all the threads exit
for(auto& t : threads)
t.join();
}
When calling the endpoint 1 at a time, it's all good, the id and the type have the expected values. When a browser makes multiple requests, the id and the type in all requests tend to have the same value.
Here's a possible output from the log:
Got arguments id 1 and type raw for url:/api/mails/1/raw
Got arguments id 1 and type raw for url:/api/mails/1/text
Got arguments id 1 and type raw for url:/api/mails/1/html
As we can see the target() from beast request is fine. The arguments are not.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.