Line data Source code
1 : //
2 : // Copyright (c) 2026 Vinnie Falco (vinnie.falco@gmail.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/cppalliance/http
8 : //
9 :
10 : #include <boost/http/server/http_worker.hpp>
11 : #include <boost/http/error.hpp>
12 : #include <boost/url/parse.hpp>
13 : #include <iostream>
14 :
15 : namespace boost {
16 : namespace http {
17 :
18 : capy::task<void>
19 67 : http_worker::
20 : do_http_session()
21 : {
22 : struct guard
23 : {
24 : http_worker& self;
25 :
26 67 : guard(http_worker& self_)
27 67 : : self(self_)
28 : {
29 67 : }
30 :
31 67 : ~guard()
32 : {
33 67 : self.parser.reset();
34 67 : self.parser.start();
35 67 : self.rp.session_data.clear();
36 67 : }
37 : };
38 :
39 : guard g(*this); // clear things when session ends
40 :
41 : // read request, send response loop
42 : for(;;)
43 : {
44 : parser.reset();
45 : parser.start();
46 : rp.session_data.clear();
47 :
48 : // Read HTTP request header
49 : auto [ec] = co_await parser.read_header(stream);
50 : if(ec)
51 : {
52 : std::cerr << "read_header error: " << ec.message() << "\n";
53 : break;
54 : }
55 :
56 : // Process headers and dispatch
57 : // Set up Request and Response objects
58 : rp.req = parser.get();
59 : rp.route_data.clear();
60 : rp.res.set_start_line(
61 : http::status::ok, rp.req.version());
62 : rp.res.set_keep_alive(rp.req.keep_alive());
63 : serializer.reset();
64 :
65 : // Parse the URL
66 : {
67 : auto rv = urls::parse_uri_reference(rp.req.target());
68 : if(rv.has_error())
69 : {
70 : rp.status(http::status::bad_request);
71 : }
72 : rp.url = rv.value();
73 : }
74 :
75 : {
76 : auto rv = co_await fr.dispatch(rp.req.method(), rp.url, rp);
77 :
78 : if(rv.what() == route_what::close)
79 : break;
80 :
81 : if(rv.what() == route_what::next)
82 : {
83 : rp.status(http::status::not_found);
84 : (void)(co_await rp.send());
85 : }
86 :
87 : if(rv.failed())
88 : {
89 : rp.status(http::status::internal_server_error);
90 : (void)(co_await rp.send());
91 : }
92 :
93 : if(! rp.res.keep_alive())
94 : break;
95 : }
96 : }
97 134 : }
98 :
99 : } // http
100 : } // boost
|