1  
//
1  
//
2  
// Copyright (c) 2025 Vinnie Falco (vinnie.falco@gmail.com)
2  
// Copyright (c) 2025 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_ROUTE_ABNF_HPP
10  
#ifndef BOOST_HTTP_SERVER_ROUTE_ABNF_HPP
11  
#define BOOST_HTTP_SERVER_ROUTE_ABNF_HPP
11  
#define BOOST_HTTP_SERVER_ROUTE_ABNF_HPP
12  

12  

13  
#include <boost/http/detail/config.hpp>
13  
#include <boost/http/detail/config.hpp>
14  
#include <boost/core/detail/string_view.hpp>
14  
#include <boost/core/detail/string_view.hpp>
15  
#include <boost/system/result.hpp>
15  
#include <boost/system/result.hpp>
16  
#include <string>
16  
#include <string>
17  
#include <vector>
17  
#include <vector>
18  

18  

19  
namespace boost {
19  
namespace boost {
20  
namespace http {
20  
namespace http {
21  
namespace detail {
21  
namespace detail {
22  

22  

23  
//------------------------------------------------
23  
//------------------------------------------------
24  

24  

25  
/** Type of route pattern token
25  
/** Type of route pattern token
26  
*/
26  
*/
27  
enum class route_token_type
27  
enum class route_token_type
28  
{
28  
{
29  
    text,       // literal text
29  
    text,       // literal text
30  
    param,      // :name parameter
30  
    param,      // :name parameter
31  
    wildcard,   // *name wildcard
31  
    wildcard,   // *name wildcard
32  
    group       // {...} optional group
32  
    group       // {...} optional group
33  
};
33  
};
34  

34  

35  
//------------------------------------------------
35  
//------------------------------------------------
36  

36  

37  
/** A token in a parsed route pattern
37  
/** A token in a parsed route pattern
38  
*/
38  
*/
39  
struct route_token
39  
struct route_token
40  
{
40  
{
41  
    route_token_type type;
41  
    route_token_type type;
42  
    std::string value;              // text content or param name
42  
    std::string value;              // text content or param name
43  
    std::vector<route_token> children;  // group contents
43  
    std::vector<route_token> children;  // group contents
44  

44  

45  
    route_token() = default;
45  
    route_token() = default;
46  

46  

47  
    route_token(
47  
    route_token(
48  
        route_token_type t,
48  
        route_token_type t,
49  
        std::string v)
49  
        std::string v)
50  
        : type(t)
50  
        : type(t)
51  
        , value(std::move(v))
51  
        , value(std::move(v))
52  
    {
52  
    {
53  
    }
53  
    }
54  
};
54  
};
55  

55  

56  
//------------------------------------------------
56  
//------------------------------------------------
57  

57  

58  
/** Result of parsing a route pattern
58  
/** Result of parsing a route pattern
59  
*/
59  
*/
60  
struct route_pattern
60  
struct route_pattern
61  
{
61  
{
62  
    std::vector<route_token> tokens;
62  
    std::vector<route_token> tokens;
63  
    std::string original;
63  
    std::string original;
64  
};
64  
};
65  

65  

66  
//------------------------------------------------
66  
//------------------------------------------------
67  

67  

68  
/** Parse a route pattern string
68  
/** Parse a route pattern string
69  

69  

70  
    Parses a path-to-regexp style route pattern into tokens.
70  
    Parses a path-to-regexp style route pattern into tokens.
71  

71  

72  
    @par Grammar
72  
    @par Grammar
73  
    @code
73  
    @code
74  
    path      = *token
74  
    path      = *token
75  
    token     = text / param / wildcard / group
75  
    token     = text / param / wildcard / group
76  
    text      = 1*(char / escaped-char)
76  
    text      = 1*(char / escaped-char)
77  
    param     = ":" name
77  
    param     = ":" name
78  
    wildcard  = "*" name
78  
    wildcard  = "*" name
79  
    group     = "{" *token "}"
79  
    group     = "{" *token "}"
80  
    name      = identifier / quoted-name
80  
    name      = identifier / quoted-name
81  
    @endcode
81  
    @endcode
82  

82  

83  
    @param pattern The route pattern string to parse
83  
    @param pattern The route pattern string to parse
84  

84  

85  
    @return A result containing the parsed route pattern, or
85  
    @return A result containing the parsed route pattern, or
86  
    an error if parsing failed
86  
    an error if parsing failed
87  
*/
87  
*/
88  
system::result<route_pattern>
88  
system::result<route_pattern>
89  
parse_route_pattern(core::string_view pattern);
89  
parse_route_pattern(core::string_view pattern);
90  

90  

91  
//------------------------------------------------
91  
//------------------------------------------------
92  

92  

93  
/** Options for route matching
93  
/** Options for route matching
94  
*/
94  
*/
95  
struct match_options
95  
struct match_options
96  
{
96  
{
97  
    bool case_sensitive;  ///< Text comparison mode
97  
    bool case_sensitive;  ///< Text comparison mode
98  
    bool strict;          ///< Trailing slash matters
98  
    bool strict;          ///< Trailing slash matters
99  
    bool end;             ///< true = full match, false = prefix match
99  
    bool end;             ///< true = full match, false = prefix match
100  
};
100  
};
101  

101  

102  
//------------------------------------------------
102  
//------------------------------------------------
103  

103  

104  
/** Result of matching a path against a pattern
104  
/** Result of matching a path against a pattern
105  
*/
105  
*/
106  
struct match_params
106  
struct match_params
107  
{
107  
{
108  
    std::vector<std::pair<std::string, std::string>> params;  ///< Captured parameters
108  
    std::vector<std::pair<std::string, std::string>> params;  ///< Captured parameters
109  
    std::size_t matched_length;  ///< Characters consumed from path
109  
    std::size_t matched_length;  ///< Characters consumed from path
110  
};
110  
};
111  

111  

112  
//------------------------------------------------
112  
//------------------------------------------------
113  

113  

114  
/** Match a decoded path against a route pattern
114  
/** Match a decoded path against a route pattern
115  

115  

116  
    Attempts to match the given path against the pattern,
116  
    Attempts to match the given path against the pattern,
117  
    extracting any captured parameters.
117  
    extracting any captured parameters.
118  

118  

119  
    @param path The decoded path to match (not URL-encoded)
119  
    @param path The decoded path to match (not URL-encoded)
120  
    @param pattern The parsed route pattern
120  
    @param pattern The parsed route pattern
121  
    @param opts Matching options
121  
    @param opts Matching options
122  

122  

123  
    @return The captured parameters and match length if successful,
123  
    @return The captured parameters and match length if successful,
124  
    or an error if the path doesn't match
124  
    or an error if the path doesn't match
125  
*/
125  
*/
126  
system::result<match_params>
126  
system::result<match_params>
127  
match_route(
127  
match_route(
128  
    core::string_view path,
128  
    core::string_view path,
129  
    route_pattern const& pattern,
129  
    route_pattern const& pattern,
130  
    match_options const& opts);
130  
    match_options const& opts);
131  

131  

132  
} // detail
132  
} // detail
133  
} // http
133  
} // http
134  
} // boost
134  
} // boost
135  

135  

136  
#endif
136  
#endif