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-​2016·​Christopher·​M.​·​Kohlhoff·​(chris·​at·​kohlhoff·​dot·​com)​5 /​/​·​Copyright·​(c)​·​2003-​2016·​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.​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_service_()​,​20 ·​·​:​·​io_service_()​,​
21 ·​·​·​·​signals_(io_service_)​,​21 ·​·​·​·​signals_(io_service_)​,​
22 ·​·​·​·​acceptor_(io_service_​)​,​22 ·​·​·​·​acceptor_(io_service_​)​,​
23 ·​·​·​·​connection_manager_()​,​23 ·​·​·​·​connection_manager_()​,​
24 ·​·​·​·​new_connection_()​,​24 ·​·​·​·​socket_(io_service_)​,​
25 ·​·​·​·​request_handler_(doc_​root)​25 ·​·​·​·​request_handler_(doc_​root)​
26 {26 {
27 ·​·​/​/​·​Register·​to·​handle·​the·​signals·​that·​indicate·​when·​the·​server·​should·​exit.​27 ·​·​/​/​·​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,​28 ·​·​/​/​·​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.​29 ·​·​/​/​·​provided·​all·​registration·​for·​the·​specified·​signal·​is·​made·​through·​Asio.​
30 ·​·​signals_.​add(SIGINT)​;​30 ·​·​signals_.​add(SIGINT)​;​
31 ·​·​signals_.​add(SIGTERM)​;​31 ·​·​signals_.​add(SIGTERM)​;​
32 #if·​defined(SIGQUIT)​32 #if·​defined(SIGQUIT)​
33 ·​·​signals_.​add(SIGQUIT)​;​33 ·​·​signals_.​add(SIGQUIT)​;​
34 #endif·​/​/​·​defined(SIGQUIT)​34 #endif·​/​/​·​defined(SIGQUIT)​
35 ·​·​signals_.​async_wait(boost:​:​bind(&server:​:​handle_stop,​·​this)​)​;​35
36 ·​·​do_await_stop()​;​
36 37
37 ·​·​/​/​·​Open·​the·​acceptor·​with·​the·​option·​to·​reuse·​the·​address·​(i.​e.​·​SO_REUSEADDR)​.​38 ·​·​/​/​·​Open·​the·​acceptor·​with·​the·​option·​to·​reuse·​the·​address·​(i.​e.​·​SO_REUSEADDR)​.​
38 ·​·​asio:​:​ip:​:​tcp:​:​resolver·​resolver(io_service_)​;​39 ·​·​asio:​:​ip:​:​tcp:​:​resolver·​resolver(io_service_)​;​
39 ·​·​asio:​:​ip:​:​tcp:​:​resolver:​:​query·​query(address,​·​port)​;​40 ·​·​asio:​:​ip:​:​tcp:​:​endpoint·​endpoint·​=·​*resolver.​resolve({address,​·​port})​;​
40 ·​·​asio:​:​ip:​:​tcp:​:​endpoint·​endpoint·​=·​*resolver.​resolve(query)​;​
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_service:​:​run()​·​call·​will·​block·​until·​all·​asynchronous·​operations51 ·​·​/​/​·​The·​io_service:​:​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_service_.​run()​;​55 ·​·​io_service_.​run()​;​
56 }56 }
57 57
58 void·​server:​:​start_accept()​58 void·​server:​:​do_accept()​
59 {
60 ·​·​new_connection_.​reset(new·​connection(io_service​_,​
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(socket_,​
70 ·​·​/​/​·​handler·​had·​a·​chance·​to·​run.​61 ·​·​·​·​·​·​[this](std:​:​error_code·​ec)​
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_service:​:​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_service:​:​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