src/​examples/​cpp03/​http/​server/​request_handler.​cppsrc/​examples/​cpp11/​http/​server/​request_handler.​cpp
⋮⋮
1 /​/​1 /​/​
2 /​/​·​request_handler.​cpp2 /​/​·​request_handler.​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·​"request_handler.​hpp"11 #include·​"request_handler.​hpp"
12 #include·​<fstream>12 #include·​<fstream>
13 #include·​<sstream>13 #include·​<sstream>
14 #include·​<string>14 #include·​<string>
15 #include·​<boost/​lexical_cast.​hpp>
16 #include·​"mime_types.​hpp"15 #include·​"mime_types.​hpp"
17 #include·​"reply.​hpp"16 #include·​"reply.​hpp"
18 #include·​"request.​hpp"17 #include·​"request.​hpp"
19 18
20 namespace·​http·​{19 namespace·​http·​{
21 namespace·​server·​{20 namespace·​server·​{
22 21
23 request_handler:​:​request_handler(const​·​std:​:​string&·​doc_root)​22 request_handler:​:​request_handler(const​·​std:​:​string&·​doc_root)​
24 ·​·​:​·​doc_root_(doc_root)​23 ·​·​:​·​doc_root_(doc_root)​
25 {24 {
26 }25 }
27 26
28 void·​request_handler:​:​handle_request(const·​request&·​req,​·​reply&·​rep)​27 void·​request_handler:​:​handle_request(const·​request&·​req,​·​reply&·​rep)​
29 {28 {
30 ·​·​/​/​·​Decode·​url·​to·​path.​29 ·​·​/​/​·​Decode·​url·​to·​path.​
31 ·​·​std:​:​string·​request_path;​30 ·​·​std:​:​string·​request_path;​
32 ·​·​if·​(!url_decode(req.​uri,​·​request_path)​)​31 ·​·​if·​(!url_decode(req.​uri,​·​request_path)​)​
33 ·​·​{32 ·​·​{
34 ·​·​·​·​rep·​=·​reply:​:​stock_reply(reply:​:​bad_request)​;​33 ·​·​·​·​rep·​=·​reply:​:​stock_reply(reply:​:​bad_request)​;​
35 ·​·​·​·​return;​34 ·​·​·​·​return;​
36 ·​·​}35 ·​·​}
37 36
38 ·​·​/​/​·​Request·​path·​must·​be·​absolute·​and·​not·​contain·​".​.​".​37 ·​·​/​/​·​Request·​path·​must·​be·​absolute·​and·​not·​contain·​".​.​".​
39 ·​·​if·​(request_path.​empty()​·​||·​request_path[0]·​!=·​'/​'38 ·​·​if·​(request_path.​empty()​·​||·​request_path[0]·​!=·​'/​'
40 ·​·​·​·​·​·​||·​request_path.​find(".​.​")​·​!=·​std:​:​string:​:​npos)​39 ·​·​·​·​·​·​||·​request_path.​find(".​.​")​·​!=·​std:​:​string:​:​npos)​
41 ·​·​{40 ·​·​{
42 ·​·​·​·​rep·​=·​reply:​:​stock_reply(reply:​:​bad_request)​;​41 ·​·​·​·​rep·​=·​reply:​:​stock_reply(reply:​:​bad_request)​;​
43 ·​·​·​·​return;​42 ·​·​·​·​return;​
44 ·​·​}43 ·​·​}
45 44
46 ·​·​/​/​·​If·​path·​ends·​in·​slash·​(i.​e.​·​is·​a·​directory)​·​then·​add·​"index.​html".​45 ·​·​/​/​·​If·​path·​ends·​in·​slash·​(i.​e.​·​is·​a·​directory)​·​then·​add·​"index.​html".​
47 ·​·​if·​(request_path[request​_path.​size()​·​-​·​1]·​==·​'/​')​46 ·​·​if·​(request_path[request​_path.​size()​·​-​·​1]·​==·​'/​')​
48 ·​·​{47 ·​·​{
49 ·​·​·​·​request_path·​+=·​"index.​html";​48 ·​·​·​·​request_path·​+=·​"index.​html";​
50 ·​·​}49 ·​·​}
51 50
52 ·​·​/​/​·​Determine·​the·​file·​extension.​51 ·​·​/​/​·​Determine·​the·​file·​extension.​
53 ·​·​std:​:​size_t·​last_slash_pos·​=·​request_path.​find_last_of("/​")​;​52 ·​·​std:​:​size_t·​last_slash_pos·​=·​request_path.​find_last_of("/​")​;​
54 ·​·​std:​:​size_t·​last_dot_pos·​=·​request_path.​find_last_of(".​")​;​53 ·​·​std:​:​size_t·​last_dot_pos·​=·​request_path.​find_last_of(".​")​;​
55 ·​·​std:​:​string·​extension;​54 ·​·​std:​:​string·​extension;​
56 ·​·​if·​(last_dot_pos·​!=·​std:​:​string:​:​npos·​&&·​last_dot_pos·​>·​last_slash_pos)​55 ·​·​if·​(last_dot_pos·​!=·​std:​:​string:​:​npos·​&&·​last_dot_pos·​>·​last_slash_pos)​
57 ·​·​{56 ·​·​{
58 ·​·​·​·​extension·​=·​request_path.​substr(last_dot_pos·​+·​1)​;​57 ·​·​·​·​extension·​=·​request_path.​substr(last_dot_pos·​+·​1)​;​
59 ·​·​}58 ·​·​}
60 59
61 ·​·​/​/​·​Open·​the·​file·​to·​send·​back.​60 ·​·​/​/​·​Open·​the·​file·​to·​send·​back.​
62 ·​·​std:​:​string·​full_path·​=·​doc_root_·​+·​request_path;​61 ·​·​std:​:​string·​full_path·​=·​doc_root_·​+·​request_path;​
63 ·​·​std:​:​ifstream·​is(full_path.​c_str()​,​·​std:​:​ios:​:​in·​|·​std:​:​ios:​:​binary)​;​62 ·​·​std:​:​ifstream·​is(full_path.​c_str()​,​·​std:​:​ios:​:​in·​|·​std:​:​ios:​:​binary)​;​
64 ·​·​if·​(!is)​63 ·​·​if·​(!is)​
65 ·​·​{64 ·​·​{
66 ·​·​·​·​rep·​=·​reply:​:​stock_reply(reply:​:​not_found)​;​65 ·​·​·​·​rep·​=·​reply:​:​stock_reply(reply:​:​not_found)​;​
67 ·​·​·​·​return;​66 ·​·​·​·​return;​
68 ·​·​}67 ·​·​}
69 68
70 ·​·​/​/​·​Fill·​out·​the·​reply·​to·​be·​sent·​to·​the·​client.​69 ·​·​/​/​·​Fill·​out·​the·​reply·​to·​be·​sent·​to·​the·​client.​
71 ·​·​rep.​status·​=·​reply:​:​ok;​70 ·​·​rep.​status·​=·​reply:​:​ok;​
72 ·​·​char·​buf[512];​71 ·​·​char·​buf[512];​
73 ·​·​while·​(is.​read(buf,​·​sizeof(buf)​)​.​gcount()​·​>·​0)​72 ·​·​while·​(is.​read(buf,​·​sizeof(buf)​)​.​gcount()​·​>·​0)​
74 ·​·​·​·​rep.​content.​append(buf,​·​is.​gcount()​)​;​73 ·​·​·​·​rep.​content.​append(buf,​·​is.​gcount()​)​;​
75 ·​·​rep.​headers.​resize(2)​;​74 ·​·​rep.​headers.​resize(2)​;​
76 ·​·​rep.​headers[0].​name·​=·​"Content-​Length";​75 ·​·​rep.​headers[0].​name·​=·​"Content-​Length";​
77 ·​·​rep.​headers[0].​value·​=·​boost:​:​lexical_cast<std:​:​string>(rep.​content.​size()​)​;​76 ·​·​rep.​headers[0].​value·​=·​std:​:​to_string(rep.​content.​size()​)​;​
78 ·​·​rep.​headers[1].​name·​=·​"Content-​Type";​77 ·​·​rep.​headers[1].​name·​=·​"Content-​Type";​
79 ·​·​rep.​headers[1].​value·​=·​mime_types:​:​extension_to_type(ext​ension)​;​78 ·​·​rep.​headers[1].​value·​=·​mime_types:​:​extension_to_type(ext​ension)​;​
80 }79 }
81 80
82 bool·​request_handler:​:​url_decode(const·​std:​:​string&·​in,​·​std:​:​string&·​out)​81 bool·​request_handler:​:​url_decode(const·​std:​:​string&·​in,​·​std:​:​string&·​out)​
83 {82 {
84 ·​·​out.​clear()​;​83 ·​·​out.​clear()​;​
85 ·​·​out.​reserve(in.​size()​)​;​84 ·​·​out.​reserve(in.​size()​)​;​
86 ·​·​for·​(std:​:​size_t·​i·​=·​0;​·​i·​<·​in.​size()​;​·​++i)​85 ·​·​for·​(std:​:​size_t·​i·​=·​0;​·​i·​<·​in.​size()​;​·​++i)​
87 ·​·​{86 ·​·​{
88 ·​·​·​·​if·​(in[i]·​==·​'%')​87 ·​·​·​·​if·​(in[i]·​==·​'%')​
89 ·​·​·​·​{88 ·​·​·​·​{
90 ·​·​·​·​·​·​if·​(i·​+·​3·​<=·​in.​size()​)​89 ·​·​·​·​·​·​if·​(i·​+·​3·​<=·​in.​size()​)​
91 ·​·​·​·​·​·​{90 ·​·​·​·​·​·​{
92 ·​·​·​·​·​·​·​·​int·​value·​=·​0;​91 ·​·​·​·​·​·​·​·​int·​value·​=·​0;​
93 ·​·​·​·​·​·​·​·​std:​:​istringstream·​is(in.​substr(i·​+·​1,​·​2)​)​;​92 ·​·​·​·​·​·​·​·​std:​:​istringstream·​is(in.​substr(i·​+·​1,​·​2)​)​;​
94 ·​·​·​·​·​·​·​·​if·​(is·​>>·​std:​:​hex·​>>·​value)​93 ·​·​·​·​·​·​·​·​if·​(is·​>>·​std:​:​hex·​>>·​value)​
95 ·​·​·​·​·​·​·​·​{94 ·​·​·​·​·​·​·​·​{
96 ·​·​·​·​·​·​·​·​·​·​out·​+=·​static_cast<char>(val​ue)​;​95 ·​·​·​·​·​·​·​·​·​·​out·​+=·​static_cast<char>(val​ue)​;​
97 ·​·​·​·​·​·​·​·​·​·​i·​+=·​2;​96 ·​·​·​·​·​·​·​·​·​·​i·​+=·​2;​
98 ·​·​·​·​·​·​·​·​}97 ·​·​·​·​·​·​·​·​}
99 ·​·​·​·​·​·​·​·​else98 ·​·​·​·​·​·​·​·​else
100 ·​·​·​·​·​·​·​·​{99 ·​·​·​·​·​·​·​·​{
101 ·​·​·​·​·​·​·​·​·​·​return·​false;​100 ·​·​·​·​·​·​·​·​·​·​return·​false;​
102 ·​·​·​·​·​·​·​·​}101 ·​·​·​·​·​·​·​·​}
103 ·​·​·​·​·​·​}102 ·​·​·​·​·​·​}
104 ·​·​·​·​·​·​else103 ·​·​·​·​·​·​else
105 ·​·​·​·​·​·​{104 ·​·​·​·​·​·​{
106 ·​·​·​·​·​·​·​·​return·​false;​105 ·​·​·​·​·​·​·​·​return·​false;​
107 ·​·​·​·​·​·​}106 ·​·​·​·​·​·​}
108 ·​·​·​·​}107 ·​·​·​·​}
109 ·​·​·​·​else·​if·​(in[i]·​==·​'+')​108 ·​·​·​·​else·​if·​(in[i]·​==·​'+')​
110 ·​·​·​·​{109 ·​·​·​·​{
111 ·​·​·​·​·​·​out·​+=·​'·​';​110 ·​·​·​·​·​·​out·​+=·​'·​';​
112 ·​·​·​·​}111 ·​·​·​·​}
113 ·​·​·​·​else112 ·​·​·​·​else
114 ·​·​·​·​{113 ·​·​·​·​{
115 ·​·​·​·​·​·​out·​+=·​in[i];​114 ·​·​·​·​·​·​out·​+=·​in[i];​
116 ·​·​·​·​}115 ·​·​·​·​}
117 ·​·​}116 ·​·​}
118 ·​·​return·​true;​117 ·​·​return·​true;​
119 }118 }
120 119
121 }·​/​/​·​namespace·​server120 }·​/​/​·​namespace·​server
122 }·​/​/​·​namespace·​http121 }·​/​/​·​namespace·​http