• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 //
2 // Copyright (c) 2016-2019 Vinnie Falco (vinnie dot falco at gmail dot com)
3 //
4 // Distributed under the Boost Software License, Version 1.0. (See accompanying
5 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
6 //
7 // Official repository: https://github.com/vinniefalco/CppCon2018
8 //
9 
10 #include "listener.hpp"
11 #include "http_session.hpp"
12 #include <iostream>
13 
14 listener::
listener(net::io_context & ioc,tcp::endpoint endpoint,boost::shared_ptr<shared_state> const & state)15 listener(
16     net::io_context& ioc,
17     tcp::endpoint endpoint,
18     boost::shared_ptr<shared_state> const& state)
19     : ioc_(ioc)
20     , acceptor_(ioc)
21     , state_(state)
22 {
23     beast::error_code ec;
24 
25     // Open the acceptor
26     acceptor_.open(endpoint.protocol(), ec);
27     if(ec)
28     {
29         fail(ec, "open");
30         return;
31     }
32 
33     // Allow address reuse
34     acceptor_.set_option(net::socket_base::reuse_address(true), ec);
35     if(ec)
36     {
37         fail(ec, "set_option");
38         return;
39     }
40 
41     // Bind to the server address
42     acceptor_.bind(endpoint, ec);
43     if(ec)
44     {
45         fail(ec, "bind");
46         return;
47     }
48 
49     // Start listening for connections
50     acceptor_.listen(
51         net::socket_base::max_listen_connections, ec);
52     if(ec)
53     {
54         fail(ec, "listen");
55         return;
56     }
57 }
58 
59 void
60 listener::
run()61 run()
62 {
63     // The new connection gets its own strand
64     acceptor_.async_accept(
65         net::make_strand(ioc_),
66         beast::bind_front_handler(
67             &listener::on_accept,
68             shared_from_this()));
69 }
70 
71 // Report a failure
72 void
73 listener::
fail(beast::error_code ec,char const * what)74 fail(beast::error_code ec, char const* what)
75 {
76     // Don't report on canceled operations
77     if(ec == net::error::operation_aborted)
78         return;
79     std::cerr << what << ": " << ec.message() << "\n";
80 }
81 
82 // Handle a connection
83 void
84 listener::
on_accept(beast::error_code ec,tcp::socket socket)85 on_accept(beast::error_code ec, tcp::socket socket)
86 {
87     if(ec)
88         return fail(ec, "accept");
89     else
90         // Launch a new session for this connection
91         boost::make_shared<http_session>(
92             std::move(socket),
93             state_)->run();
94 
95     // The new connection gets its own strand
96     acceptor_.async_accept(
97         net::make_strand(ioc_),
98         beast::bind_front_handler(
99             &listener::on_accept,
100             shared_from_this()));
101 }
102