src/​examples/​cpp03/​http/​server/​server.​cppsrc/​examples/​cpp11/​http/​server/​server.​cpp
1 /​/​1 /​/​
2 /​/​·​server.​cpp2 /​/​·​server.​cpp
3 /​/​·​~~~~~~~~~~3 /​/​·​~~~~~~~~~~
4 /​/​4 /​/​
5 /​/​·​Copyright·​(c)​·​2003-​2020·​Christopher·​M.​·​Kohlhoff·​(chris·​at·​kohlhoff·​dot·​com)​5 /​/​·​Copyright·​(c)​·​2003-​2020·​Christopher·​M.​·​Kohlhoff·​(chris·​at·​kohlhoff·​dot·​com)​
6 /​/​6 /​/​
7 /​/​·​Distributed·​under·​the·​Boost·​Software·​License,​·​Version·​1.​0.​·​(See·​accompanying7 /​/​·​Distributed·​under·​the·​Boost·​Software·​License,​·​Version·​1.​0.​·​(See·​accompanying
8 /​/​·​file·​LICENSE_1_0.​txt·​or·​copy·​at·​http:​/​/​www.​boost.​org/​LICENSE_1_0.​txt)​8 /​/​·​file·​LICENSE_1_0.​txt·​or·​copy·​at·​http:​/​/​www.​boost.​org/​LICENSE_1_0.​txt)​
9 /​/​9 /​/​
10 10
11 #include·​"server.​hpp"11 #include·​"server.​hpp"
12 #include·​<boost/​bind/​bind.​hpp>
13 #include·​<signal.​h>12 #include·​<signal.​h>
13 #include·​<utility>
14 14
15 namespace·​http·​{15 namespace·​http·​{
16 namespace·​server·​{16 namespace·​server·​{
17 17
18 server:​:​server(const·​std:​:​string&·​address,​·​const·​std:​:​string&·​port,​18 server:​:​server(const·​std:​:​string&·​address,​·​const·​std:​:​string&·​port,​
19 ····​const·​std:​:​string&·​doc_root)​19 ····​const·​std:​:​string&·​doc_root)​
20 ··​:​·​io_context_()​,​20 ··​:​·​io_context_(1)​,​
21 ····​signals_(io_context_)​,​21 ····​signals_(io_context_)​,​
22 ····​acceptor_(io_context_​)​,​22 ····​acceptor_(io_context_​)​,​
23 ····​connection_manager_()​,​23 ····​connection_manager_()​,​
24 ····​new_connection_()​,​
25 ····​request_handler_(doc_​root)​24 ····​request_handler_(doc_​root)​
26 {25 {
27 ··​/​/​·​Register·​to·​handle·​the·​signals·​that·​indicate·​when·​the·​server·​should·​exit.​26 ··​/​/​·​Register·​to·​handle·​the·​signals·​that·​indicate·​when·​the·​server·​should·​exit.​
28 ··​/​/​·​It·​is·​safe·​to·​register·​for·​the·​same·​signal·​multiple·​times·​in·​a·​program,​27 ··​/​/​·​It·​is·​safe·​to·​register·​for·​the·​same·​signal·​multiple·​times·​in·​a·​program,​
29 ··​/​/​·​provided·​all·​registration·​for·​the·​specified·​signal·​is·​made·​through·​Asio.​28 ··​/​/​·​provided·​all·​registration·​for·​the·​specified·​signal·​is·​made·​through·​Asio.​
30 ··​signals_.​add(SIGINT)​;​29 ··​signals_.​add(SIGINT)​;​
31 ··​signals_.​add(SIGTERM)​;​30 ··​signals_.​add(SIGTERM)​;​
32 #if·​defined(SIGQUIT)​31 #if·​defined(SIGQUIT)​
33 ··​signals_.​add(SIGQUIT)​;​32 ··​signals_.​add(SIGQUIT)​;​
34 #endif·​/​/​·​defined(SIGQUIT)​33 #endif·​/​/​·​defined(SIGQUIT)​
35 ··signals_.​async_wait(boost:​:​bind(&server:​:​handle_stop,​·this)​)​;​34
35 ··​do_await_stop()​;​
36 36
37 ··​/​/​·​Open·​the·​acceptor·​with·​the·​option·​to·​reuse·​the·​address·​(i.​e.​·​SO_REUSEADDR)​.​37 ··​/​/​·​Open·​the·​acceptor·​with·​the·​option·​to·​reuse·​the·​address·​(i.​e.​·​SO_REUSEADDR)​.​
38 ··​asio:​:​ip:​:​tcp:​:​resolver·​resolver(io_context_)​;​38 ··​asio:​:​ip:​:​tcp:​:​resolver·​resolver(io_context_)​;​
39 ··​asio:​:​ip:​:​tcp:​:​endpoint·​endpoint·​=39 ··​asio:​:​ip:​:​tcp:​:​endpoint·​endpoint·​=
40 ····​*resolver.​resolve(address,​·​port)​.​begin()​;​40 ····​*resolver.​resolve(address,​·​port)​.​begin()​;​
41 ··​acceptor_.​open(endpoint.​protocol()​)​;​41 ··​acceptor_.​open(endpoint.​protocol()​)​;​
42 ··​acceptor_.​set_option(asio:​:​ip:​:​tcp:​:​acceptor:​:​reuse_address(true)​)​;​42 ··​acceptor_.​set_option(asio:​:​ip:​:​tcp:​:​acceptor:​:​reuse_address(true)​)​;​
43 ··​acceptor_.​bind(endpoint)​;​43 ··​acceptor_.​bind(endpoint)​;​
44 ··​acceptor_.​listen()​;​44 ··​acceptor_.​listen()​;​
45 45
46 ··start_accept()​;​46 ··do_accept()​;​
47 }47 }
48 48
49 void·​server:​:​run()​49 void·​server:​:​run()​
50 {50 {
51 ··​/​/​·​The·​io_context:​:​run()​·​call·​will·​block·​until·​all·​asynchronous·​operations51 ··​/​/​·​The·​io_context:​:​run()​·​call·​will·​block·​until·​all·​asynchronous·​operations
52 ··​/​/​·​have·​finished.​·​While·​the·​server·​is·​running,​·​there·​is·​always·​at·​least·​one52 ··​/​/​·​have·​finished.​·​While·​the·​server·​is·​running,​·​there·​is·​always·​at·​least·​one
53 ··​/​/​·​asynchronous·​operation·​outstanding:​·​the·​asynchronous·​accept·​call·​waiting53 ··​/​/​·​asynchronous·​operation·​outstanding:​·​the·​asynchronous·​accept·​call·​waiting
54 ··​/​/​·​for·​new·​incoming·​connections.​54 ··​/​/​·​for·​new·​incoming·​connections.​
55 ··​io_context_.​run()​;​55 ··​io_context_.​run()​;​
56 }56 }
57 57
58 void·​server:​:​start_accept()​58 void·​server:​:​do_accept()​
59 {
60 ··new_connection_.​reset(new·connection(io_context​_,​
61 ········connection_manager_,​·request_handler_)​)​;​
62 ··acceptor_.​async_accept(new_conn​ection_-​>socket()​,​
63 ······boost:​:​bind(&server:​:​handle_accept,​·this,​
64 ········asio:​:​placeholders:​:​error)​)​;​
65 }
66
67 void·server:​:​handle_accept(const·asio:​:​error_code&·e)​
68 {59 {
69 ··/​/​·Check·whether·the·server·was·stopped·by·a·signal·before·this·completion60 ··acceptor_.​async_accept(
70 ··/​/​·​handler·had·​a·chance·to·run.​61 ······[this](std:​:​error_code·ec,​·​asio:​:​ip:​:​tcp:​:​socket·socket)​
71 ··if·(!acceptor_.​is_open()​)​62 ······{
72 ··{63 ········/​/​·Check·whether·the·server·was·stopped·by·a·signal·before·this
73 ····​return;​64 ········/​/​·completion·handler·had·a·chance·to·run.​
74 ··}65 ········if·(!acceptor_.​is_open()​)​
75 66 ········{
76 ··if·(!e)​67 ··········return;​
77 ··{68 ········}
78 ····connection_manager_.​start(new_connection_​)​;​69
79 ··}70 ········if·(!ec)​
71 ········​{
72 ··········​connection_manager_.​start(std:​:​make_shared<connectio​n>(
73 ··············​std:​:​move(socket)​,​·​connection_manager_,​·​request_handler_)​)​;​
74 ········​}
80 75
81 ··start_accept()​;​76 ········do_accept()​;​
77 ······​})​;​
82 }78 }
83 79
84 void·​server:​:​handle_stop()​80 void·​server:​:​do_await_stop()​
85 {81 {
86 ··/​/​·The·server·is·​stopped·by·cancelling·all·outstanding·asynchronous82 ··​signals_.​async_wait(
87 ··/​/​·operations.​·Once·all·operations·have·finished·the·​io_context:​:​run()​·call83 ······[this](std:​:​error_code·/​*ec*/​,​·​int·/​*signo*/​)​
88 ··/​/​·will·exit.​84 ······{
89 ··acceptor_.​close()​;​85 ········/​/​·The·server·is·stopped·by·cancelling·all·outstanding·asynchronous
90 ··connection_manager_.​stop_all()​;​86 ········/​/​·operations.​·Once·all·operations·have·finished·the·io_context:​:​run()​
87 ········​/​/​·​call·​will·​exit.​
88 ········​acceptor_.​close()​;​
89 ········​connection_manager_.​stop_all()​;​
90 ······​})​;​
91 }91 }
92 92
93 }·​/​/​·​namespace·​server93 }·​/​/​·​namespace·​server
94 }·​/​/​·​namespace·​http94 }·​/​/​·​namespace·​http