I am trying to compile the example code located here libs/beast/example/http/server/small/http_server_small.cpp - 1.70.0 but I am getting an error right out of the box that I am unsure how to fix.
The error occurs on this line below
Code:
// The timer for putting a deadline on connection processing.
net::basic_waitable_timer<std::chrono::steady_clock> deadline_{
socket_.get_executor(), std::chrono::seconds(60)}; <-- error occurs here
// Error
Code:
error: could not convert ‘{((http_connection*)this)->http_connection::socket_.boost::asio::basic_stream_socket<boost::asio::ip::tcp>::<anonymous>.boost::asio::basic_socket<boost::asio::ip::tcp>::get_executor(), std::chrono::duration<long int>(60)}’ from ‘<brace-enclosed initializer list>’ to ‘boost::asio::basic_waitable_timer<std::chrono::_V2::steady_clock>’
Full Error
Code:
-------------- Build: Debug in TestBoostAsioBeast (compiler: GNU GCC Compiler)---------------
g++ -Wall -fexceptions -g -Iinclude -c "/home/code/TestBoostAsioBeast/main.cpp" -o obj/Debug/main.o
/home/code/TestBoostAsioBeast/main.cpp:94:57: error: could not convert ‘{((http_connection*)this)->http_connection::socket_.boost::asio::basic_stream_socket<boost::asio::ip::tcp>::<anonymous>.boost::asio::basic_socket<boost::asio::ip::tcp>::get_executor(), std::chrono::duration<long int>(60)}’ from ‘<brace-enclosed initializer list>’ to ‘boost::asio::basic_waitable_timer<std::chrono::_V2::steady_clock>’
socket_.get_executor(), std::chrono::seconds(60)};
^
/home/code/TestBoostAsioBeast/main.cpp: In function ‘time_t ConvertStringToTimeTWithTimezone(std::__cxx11::string)’:
/home/code/TestBoostAsioBeast/main.cpp:820:12: warning: unused variable ‘tCurrentTime2’ [-Wunused-variable]
time_t tCurrentTime2 = mktime(&tmTime);
^~~~~~~~~~~~~
/home/code/TestBoostAsioBeast/main.cpp: In function ‘int main()’:
/home/code/TestBoostAsioBeast/main.cpp:1053:18: error: ‘do_session’ was not declared in this scope
&do_session,
^~~~~~~~~~
/home/code/TestBoostAsioBeast/main.cpp:1055:26: error: no matching function for call to ‘std::thread::thread(<brace-enclosed initializer list>)’
doc_root)}.detach();
^
In file included from /usr/include/c++/7/future:39:0,
from /usr/local/include/boost/asio/detail/future.hpp:20,
from /usr/local/include/boost/asio/packaged_task.hpp:19,
from /usr/local/include/boost/asio.hpp:101,
from /home/code/TestBoostAsioBeast/main.cpp:17:
/usr/include/c++/7/thread:118:7: note: candidate: template<class _Callable, class ... _Args> std::thread::thread(_Callable&&, _Args&& ...)
thread(_Callable&& __f, _Args&&... __args)
^~~~~~
/usr/include/c++/7/thread:118:7: note: template argument deduction/substitution failed:
/usr/include/c++/7/thread:113:5: note: candidate: std::thread::thread(std::thread&&)
thread(thread&& __t) noexcept
^~~~~~
/usr/include/c++/7/thread:113:5: note: conversion of argument 1 would be ill-formed:
/usr/include/c++/7/thread:106:5: note: candidate: std::thread::thread()
thread() noexcept = default;
^~~~~~
/usr/include/c++/7/thread:106:5: note: candidate expects 0 arguments, 1 provided
Process terminated with status 1 (0 minute(s), 3 second(s))
3 error(s), 1 warning(s) (0 minute(s), 3 second(s))
Full Code
Code:
//
// Copyright (c) 2017 Christopher M. Kohlhoff (chris at kohlhoff dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
// Official repository: GitHub - boostorg/beast: HTTP and WebSocket built on Boost.Asio in C++11
//
//------------------------------------------------------------------------------
//
// Example: HTTP server, small
//
//------------------------------------------------------------------------------
#include <boost/beast/core.hpp>
#include <boost/beast/http.hpp>
#include <boost/beast/version.hpp>
#include <boost/asio.hpp>
#include <chrono>
#include <cstdlib>
#include <ctime>
#include <iostream>
#include <memory>
#include <string>
namespace beast = boost::beast; // from <boost/beast.hpp>
namespace http = beast::http; // from <boost/beast/http.hpp>
namespace net = boost::asio; // from <boost/asio.hpp>
using tcp = boost::asio::ip::tcp; // from <boost/asio/ip/tcp.hpp>
namespace my_program_state
{
std::size_t
request_count()
{
static std::size_t count = 0;
return ++count;
}
std::time_t
now()
{
return std::time(0);
}
}
class http_connection : public std::enable_shared_from_this<http_connection>
{
public:
http_connection(tcp::socket socket)
: socket_(std::move(socket))
{
}
// Initiate the asynchronous operations associated with the connection.
void
start()
{
read_request();
check_deadline();
}
private:
// The socket for the currently connected client.
tcp::socket socket_;
// The buffer for performing reads.
beast::flat_buffer buffer_{8192};
// The request message.
http::request<http::dynamic_body> request_;
// The response message.
http::response<http::dynamic_body> response_;
// The timer for putting a deadline on connection processing.
net::basic_waitable_timer<std::chrono::steady_clock> deadline_{
socket_.get_executor(), std::chrono::seconds(60)};
// Asynchronously receive a complete request message.
void
read_request()
{
auto self = shared_from_this();
http::async_read(
socket_,
buffer_,
request_,
[self](beast::error_code ec,
std::size_t bytes_transferred)
{
boost::ignore_unused(bytes_transferred);
if(!ec)
self->process_request();
});
}
// Determine what needs to be done with the request message.
void
process_request()
{
response_.version(request_.version());
response_.keep_alive(false);
switch(request_.method())
{
case http::verb::get:
response_.result(http::status::ok);
response_.set(http::field::server, "Beast");
create_response();
break;
default:
// We return responses indicating an error if
// we do not recognize the request method.
response_.result(http::status::bad_request);
response_.set(http::field::content_type, "text/plain");
beast::ostream(response_.body())
<< "Invalid request-method '"
<< std::string(request_.method_string())
<< "'";
break;
}
write_response();
}
// Construct a response message based on the program state.
void
create_response()
{
if(request_.target() == "/count")
{
response_.set(http::field::content_type, "text/html");
beast::ostream(response_.body())
<< "<html>\n"
<< "<head><title>Request count</title></head>\n"
<< "<body>\n"
<< "<h1>Request count</h1>\n"
<< "<p>There have been "
<< my_program_state::request_count()
<< " requests so far.</p>\n"
<< "</body>\n"
<< "</html>\n";
}
else if(request_.target() == "/time")
{
response_.set(http::field::content_type, "text/html");
beast::ostream(response_.body())
<< "<html>\n"
<< "<head><title>Current time</title></head>\n"
<< "<body>\n"
<< "<h1>Current time</h1>\n"
<< "<p>The current time is "
<< my_program_state::now()
<< " seconds since the epoch.</p>\n"
<< "</body>\n"
<< "</html>\n";
}
else
{
response_.result(http::status::not_found);
response_.set(http::field::content_type, "text/plain");
beast::ostream(response_.body()) << "File not found\r\n";
}
}
// Asynchronously transmit the response message.
void
write_response()
{
auto self = shared_from_this();
response_.set(http::field::content_length, response_.body().size());
http::async_write(
socket_,
response_,
[self](beast::error_code ec, std::size_t)
{
self->socket_.shutdown(tcp::socket::shutdown_send, ec);
self->deadline_.cancel();
});
}
// Check whether we have spent enough time on this connection.
void
check_deadline()
{
auto self = shared_from_this();
deadline_.async_wait(
[self](beast::error_code ec)
{
if(!ec)
{
// Close socket to cancel any outstanding operation.
self->socket_.close(ec);
}
});
}
};
// "Loop" forever accepting new connections.
void
http_server(tcp::acceptor& acceptor, tcp::socket& socket)
{
acceptor.async_accept(socket,
[&](beast::error_code ec)
{
if(!ec)
std::make_shared<http_connection>(std::move(socket))->start();
http_server(acceptor, socket);
});
}
int
main(int argc, char* argv[])
{
try
{
// Check command line arguments.
if(argc != 3)
{
std::cerr << "Usage: " << argv[0] << " <address> <port>\n";
std::cerr << " For IPv4, try:\n";
std::cerr << " receiver 0.0.0.0 80\n";
std::cerr << " For IPv6, try:\n";
std::cerr << " receiver 0::0 80\n";
return EXIT_FAILURE;
}
auto const address = net::ip::make_address(argv[1]);
unsigned short port = static_cast<unsigned short>(std::atoi(argv[2]));
net::io_context ioc{1};
tcp::acceptor acceptor{ioc, {address, port}};
tcp::socket socket{ioc};
http_server(acceptor, socket);
ioc.run();
}
catch(std::exception const& e)
{
std::cerr << "Error: " << e.what() << std::endl;
return EXIT_FAILURE;
}
}
Thanks for any help you can provide!