100.00% Lines (9/9) 100.00% Functions (1/1)
TLA Baseline Branch
Line Hits Code Line Hits Code
1   // 1   //
2   // Copyright (c) 2026 Vinnie Falco (vinnie.falco@gmail.com) 2   // Copyright (c) 2026 Vinnie Falco (vinnie.falco@gmail.com)
3   // 3   //
4   // Distributed under the Boost Software License, Version 1.0. (See accompanying 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) 5   // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
6   // 6   //
7   // Official repository: https://github.com/cppalliance/http 7   // Official repository: https://github.com/cppalliance/http
8   // 8   //
9   9  
10   #ifndef BOOST_HTTP_SERVER_WORKER_HPP 10   #ifndef BOOST_HTTP_SERVER_WORKER_HPP
11   #define BOOST_HTTP_SERVER_WORKER_HPP 11   #define BOOST_HTTP_SERVER_WORKER_HPP
12   12  
13   #include <boost/http/detail/config.hpp> 13   #include <boost/http/detail/config.hpp>
14   #include <boost/capy/io/any_read_stream.hpp> 14   #include <boost/capy/io/any_read_stream.hpp>
15   #include <boost/capy/task.hpp> 15   #include <boost/capy/task.hpp>
16   #include <boost/http/config.hpp> 16   #include <boost/http/config.hpp>
17   #include <boost/http/request_parser.hpp> 17   #include <boost/http/request_parser.hpp>
18   #include <boost/http/serializer.hpp> 18   #include <boost/http/serializer.hpp>
19   #include <boost/http/server/router.hpp> 19   #include <boost/http/server/router.hpp>
20   20  
21   namespace boost { 21   namespace boost {
22   namespace http { 22   namespace http {
23   23  
24   /** Reusable HTTP request/response processing logic. 24   /** Reusable HTTP request/response processing logic.
25   25  
26   This class provides the core HTTP processing loop: reading 26   This class provides the core HTTP processing loop: reading
27   requests, dispatching them through a router, and sending 27   requests, dispatching them through a router, and sending
28   responses. It is designed as a mix-in base class for use 28   responses. It is designed as a mix-in base class for use
29   with @ref corosio::tcp_server. 29   with @ref corosio::tcp_server.
30   30  
31   @par Usage with tcp_server 31   @par Usage with tcp_server
32   32  
33   To use this class, derive a custom worker from both 33   To use this class, derive a custom worker from both
34   @ref corosio::tcp_server::worker_base and `http_worker`. 34   @ref corosio::tcp_server::worker_base and `http_worker`.
35   The derived class must: 35   The derived class must:
36   36  
37   @li Construct `http_worker` with a router and configurations 37   @li Construct `http_worker` with a router and configurations
38   @li Initialize the @ref stream member before calling 38   @li Initialize the @ref stream member before calling
39   @ref do_http_session 39   @ref do_http_session
40   @li Wire the parser and serializer to the socket by setting 40   @li Wire the parser and serializer to the socket by setting
41   `rp.req_body` and `rp.res_body` 41   `rp.req_body` and `rp.res_body`
42   42  
43   @par Example 43   @par Example
44   @code 44   @code
45   struct my_worker 45   struct my_worker
46   : tcp_server::worker_base 46   : tcp_server::worker_base
47   , http_worker 47   , http_worker
48   { 48   {
49   corosio::tcp_socket sock; 49   corosio::tcp_socket sock;
50   50  
51   my_worker( 51   my_worker(
52   corosio::io_context& ctx, 52   corosio::io_context& ctx,
53   http::router<route_params> const& router, 53   http::router<route_params> const& router,
54   http::shared_parser_config parser_cfg, 54   http::shared_parser_config parser_cfg,
55   http::shared_serializer_config serializer_cfg) 55   http::shared_serializer_config serializer_cfg)
56   : http_worker(router, parser_cfg, serializer_cfg) 56   : http_worker(router, parser_cfg, serializer_cfg)
57   , sock(ctx) 57   , sock(ctx)
58   { 58   {
59   sock.open(); 59   sock.open();
60   rp.req_body = capy::any_buffer_source(parser.source_for(sock)); 60   rp.req_body = capy::any_buffer_source(parser.source_for(sock));
61   rp.res_body = capy::any_buffer_sink(serializer.sink_for(sock)); 61   rp.res_body = capy::any_buffer_sink(serializer.sink_for(sock));
62   stream = capy::any_read_stream(&sock); 62   stream = capy::any_read_stream(&sock);
63   } 63   }
64   64  
65   corosio::tcp_socket& socket() override { return sock; } 65   corosio::tcp_socket& socket() override { return sock; }
66   66  
67   void run(launcher launch) override 67   void run(launcher launch) override
68   { 68   {
69   launch(sock.get_executor(), do_http_session()); 69   launch(sock.get_executor(), do_http_session());
70   } 70   }
71   }; 71   };
72   @endcode 72   @endcode
73   73  
74   @par Thread Safety 74   @par Thread Safety
75   Distinct objects: Safe. 75   Distinct objects: Safe.
76   Shared objects: Unsafe. 76   Shared objects: Unsafe.
77   77  
78   @see corosio::tcp_server, http_server 78   @see corosio::tcp_server, http_server
79   */ 79   */
80   class BOOST_HTTP_DECL http_worker 80   class BOOST_HTTP_DECL http_worker
81   { 81   {
82   public: 82   public:
83   http::router<route_params> fr; 83   http::router<route_params> fr;
84   http::route_params rp; 84   http::route_params rp;
85   capy::any_read_stream stream; 85   capy::any_read_stream stream;
86   http::request_parser parser; 86   http::request_parser parser;
87   http::serializer serializer; 87   http::serializer serializer;
88   88  
89   /** Construct an HTTP worker. 89   /** Construct an HTTP worker.
90   90  
91   @param fr_ The router for dispatching requests to handlers. 91   @param fr_ The router for dispatching requests to handlers.
92   @param parser_cfg Shared configuration for the request parser. 92   @param parser_cfg Shared configuration for the request parser.
93   @param serializer_cfg Shared configuration for the response 93   @param serializer_cfg Shared configuration for the response
94   serializer. 94   serializer.
95   */ 95   */
96   template<capy::WriteStream Stream> 96   template<capy::WriteStream Stream>
HITCBC 97   1 http_worker( 97   1 http_worker(
98   Stream& stream_, 98   Stream& stream_,
99   http::router<route_params> fr_, 99   http::router<route_params> fr_,
100   http::shared_parser_config parser_cfg, 100   http::shared_parser_config parser_cfg,
101   http::shared_serializer_config serializer_cfg) 101   http::shared_serializer_config serializer_cfg)
HITCBC 102   1 : fr(std::move(fr_)) 102   1 : fr(std::move(fr_))
HITCBC 103   1 , stream(&stream_) 103   1 , stream(&stream_)
HITCBC 104   1 , parser(parser_cfg) 104   1 , parser(parser_cfg)
HITCBC 105   2 , serializer(serializer_cfg) 105   2 , serializer(serializer_cfg)
106   { 106   {
HITCBC 107   1 serializer.set_message(rp.res); 107   1 serializer.set_message(rp.res);
HITCBC 108   1 rp.req_body = capy::any_buffer_source(parser.source_for(stream_)); 108   1 rp.req_body = capy::any_buffer_source(parser.source_for(stream_));
HITCBC 109   1 rp.res_body = capy::any_buffer_sink(serializer.sink_for(stream_)); 109   1 rp.res_body = capy::any_buffer_sink(serializer.sink_for(stream_));
HITCBC 110   1 } 110   1 }
111   111  
112   /** Handle an HTTP session. 112   /** Handle an HTTP session.
113   113  
114   This coroutine reads HTTP requests, dispatches them through 114   This coroutine reads HTTP requests, dispatches them through
115   the router, and sends responses until the connection is 115   the router, and sends responses until the connection is
116   closed or an error occurs. The stream data member must be 116   closed or an error occurs. The stream data member must be
117   initialized before calling this function. 117   initialized before calling this function.
118   118  
119   @return An awaitable that completes when the session ends. 119   @return An awaitable that completes when the session ends.
120   */ 120   */
121   capy::task<void> 121   capy::task<void>
122   do_http_session(); 122   do_http_session();
123   }; 123   };
124   124  
125   } // http 125   } // http
126   } // boost 126   } // boost
127   127  
128   #endif 128   #endif