LCOV - code coverage report
Current view: top level - boost/http/server - router_types.hpp (source / functions) Coverage Total Hit
Test: coverage_filtered.info Lines: 100.0 % 15 15
Test Date: 2026-01-20 00:11:34 Functions: 100.0 % 3 3

            Line data    Source code
       1              : //
       2              : // Copyright (c) 2025 Vinnie Falco (vinnie dot falco at gmail dot 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              : #ifndef BOOST_HTTP_SERVER_ROUTER_TYPES_HPP
      11              : #define BOOST_HTTP_SERVER_ROUTER_TYPES_HPP
      12              : 
      13              : #include <boost/http/detail/config.hpp>
      14              : #include <boost/http/method.hpp>
      15              : #include <boost/http/detail/except.hpp>
      16              : #include <boost/core/detail/string_view.hpp>
      17              : #include <boost/system/error_code.hpp>
      18              : #include <exception>
      19              : #include <string>
      20              : #include <type_traits>
      21              : 
      22              : namespace boost {
      23              : namespace http {
      24              : 
      25              : /** The result type returned by a route handler.
      26              : 
      27              :     Route handlers use this type to report errors that prevent
      28              :     normal processing. A handler must never return a non-failing
      29              :     (i.e. `ec.failed() == false`) value. Returning a default-constructed
      30              :     `system::error_code` is disallowed; handlers that complete
      31              :     successfully must instead return a valid @ref route result.
      32              : */
      33              : using route_result = system::error_code;
      34              : 
      35              : /** Route handler return values
      36              : 
      37              :     These values determine how the caller proceeds after invoking
      38              :     a route handler. Each enumerator represents a distinct control
      39              :     action�whether the request was handled, should continue to the
      40              :     next route, transfers ownership of the session, or signals that
      41              :     the connection should be closed.
      42              : */
      43              : enum class route
      44              : {
      45              :     /** The handler declined to process the request.
      46              : 
      47              :         The handler chose not to generate a response. The caller
      48              :         continues invoking the remaining handlers in the same route
      49              :         until one returns @ref send. If none do, the caller proceeds
      50              :         to evaluate the next matching route.
      51              : 
      52              :         This value is returned by @ref router::dispatch if no
      53              :         handlers in any route handle the request.
      54              :     */
      55              :     next,
      56              : 
      57              :     /** The handler declined the current route.
      58              : 
      59              :         The handler wishes to skip any remaining handlers in the
      60              :         current route and move on to the next matching route. The
      61              :         caller stops invoking handlers in this route and resumes
      62              :         evaluation with the next candidate route.
      63              :     */
      64              :     next_route
      65              : };
      66              : 
      67              : //------------------------------------------------
      68              : 
      69              : } // http
      70              : namespace system {
      71              : template<>
      72              : struct is_error_code_enum<
      73              :     ::boost::http::route>
      74              : {
      75              :     static bool const value = true;
      76              : };
      77              : } // system
      78              : namespace http {
      79              : 
      80              : namespace detail {
      81              : struct BOOST_HTTP_SYMBOL_VISIBLE route_cat_type
      82              :     : system::error_category
      83              : {
      84              :     BOOST_HTTP_DECL const char* name() const noexcept override;
      85              :     BOOST_HTTP_DECL std::string message(int) const override;
      86              :     BOOST_HTTP_DECL char const* message(
      87              :         int, char*, std::size_t) const noexcept override;
      88              :     BOOST_SYSTEM_CONSTEXPR route_cat_type()
      89              :         : error_category(0x51c90d393754ecdf )
      90              :     {
      91              :     }
      92              : };
      93              : BOOST_HTTP_DECL extern route_cat_type route_cat;
      94              : } // detail
      95              : 
      96              : inline
      97              : BOOST_SYSTEM_CONSTEXPR
      98              : system::error_code
      99          155 : make_error_code(route ev) noexcept
     100              : {
     101              :     return system::error_code{static_cast<
     102              :         std::underlying_type<route>::type>(ev),
     103          155 :         detail::route_cat};
     104              : }
     105              : 
     106              : /** Return true if `rv` is a route result.
     107              : 
     108              :     A @ref route_result can hold any error code,
     109              :     and this function returns `true` only if `rv`
     110              :     holds a value from the @ref route enumeration.
     111              : */
     112              : inline bool is_route_result(
     113              :     route_result rv) noexcept
     114              : {
     115              :     return &rv.category() == &detail::route_cat;
     116              : }
     117              : 
     118              : //------------------------------------------------
     119              : 
     120              : namespace detail {
     121              : class router_base;
     122              : } // detail
     123              : template<class> class router;
     124              : 
     125              : struct route_params_base_privates
     126              : {
     127              :     struct match_result;
     128              : 
     129              :     std::string verb_str_;
     130              :     std::string decoded_path_;
     131              :     system::error_code ec_;
     132              :     std::exception_ptr ep_;
     133              :     std::size_t pos_ = 0;
     134              :     std::size_t resume_ = 0;
     135              :     http::method verb_ =
     136              :         http::method::unknown;
     137              :     bool addedSlash_ = false;
     138              :     bool case_sensitive = false;
     139              :     bool strict = false;
     140              :     char kind_ = 0;  // dispatch mode, initialized by flat_router::dispatch()
     141              : };
     142              : 
     143              : /** Base class for request objects
     144              : 
     145              :     This is a required public base for any `Request`
     146              :     type used with @ref router.
     147              : */
     148              : class route_params_base : public route_params_base_privates
     149              : {
     150              : public:
     151              :     /** Return true if the request method matches `m`
     152              :     */
     153              :     bool is_method(
     154              :         http::method m) const noexcept
     155              :     {
     156              :         return verb_ == m;
     157              :     }
     158              : 
     159              :     /** Return true if the request method matches `s`
     160              :     */
     161              :     BOOST_HTTP_DECL
     162              :     bool is_method(
     163              :         core::string_view s) const noexcept;
     164              : 
     165              :     /** The mount path of the current router
     166              : 
     167              :         This is the portion of the request path
     168              :         which was matched to select the handler.
     169              :         The remaining portion is available in
     170              :         @ref path.
     171              :     */
     172              :     core::string_view base_path;
     173              : 
     174              :     /** The current pathname, relative to the base path
     175              :     */
     176              :     core::string_view path;
     177              : 
     178              :    struct match_result;
     179              : 
     180              : private:
     181              :     template<class>
     182              :     friend class router;
     183              :     friend struct route_params_access;
     184              : 
     185              :     route_params_base& operator=(
     186              :         route_params_base const&) = delete;
     187              : };
     188              : 
     189              : struct route_params_base::
     190              :     match_result
     191              : {
     192           73 :     void adjust_path(
     193              :         route_params_base& p,
     194              :         std::size_t n)
     195              :     {
     196           73 :         n_ = n;
     197           73 :         if(n_ == 0)
     198           39 :             return;
     199           34 :         p.base_path = {
     200              :             p.base_path.data(),
     201           34 :             p.base_path.size() + n_ };
     202           34 :         if(n_ < p.path.size())
     203              :         {
     204           13 :             p.path.remove_prefix(n_);
     205              :         }
     206              :         else
     207              :         {
     208              :             // append a soft slash
     209           21 :             p.path = { p.decoded_path_.data() +
     210           21 :                 p.decoded_path_.size() - 1, 1};
     211           21 :             BOOST_ASSERT(p.path == "/");
     212              :         }
     213              :     }
     214              : 
     215              :     void restore_path(
     216              :         route_params_base& p)
     217              :     {
     218              :         if( n_ > 0 &&
     219              :             p.addedSlash_ &&
     220              :             p.path.data() ==
     221              :                 p.decoded_path_.data() +
     222              :                 p.decoded_path_.size() - 1)
     223              :         {
     224              :             // remove soft slash
     225              :             p.path = {
     226              :                 p.base_path.data() +
     227              :                 p.base_path.size(), 0 };
     228              :         }
     229              :         p.base_path.remove_suffix(n_);
     230              :         p.path = {
     231              :             p.path.data() - n_,
     232              :             p.path.size() + n_ };
     233              :     }
     234              : 
     235              : private:
     236              :     std::size_t n_ = 0; // chars moved from path to base_path
     237              : };
     238              : 
     239              : 
     240              : namespace detail {
     241              : 
     242              : struct route_params_access
     243              : {
     244              :     route_params_base& rp;
     245              : 
     246           24 :     route_params_base_privates* operator->() const noexcept
     247              :     {
     248           24 :         return &rp;
     249              :     }
     250              : };
     251              : 
     252              : } // detail
     253              : 
     254              : } // http
     255              : } // boost
     256              : 
     257              : #endif
        

Generated by: LCOV version 2.3