Sourcemeta Core 0.0.0
Loading...
Searching...
No Matches
http_syntax.h
1#ifndef SOURCEMETA_CORE_HTTP_SYNTAX_H_
2#define SOURCEMETA_CORE_HTTP_SYNTAX_H_
3
4#ifndef SOURCEMETA_CORE_HTTP_EXPORT
5#include <sourcemeta/core/http_export.h>
6#endif
7
8#include <sourcemeta/core/text.h>
9
10#include <cstddef> // std::size_t
11#include <optional> // std::optional
12#include <string> // std::string
13#include <string_view> // std::string_view
14
15namespace sourcemeta::core {
16
28inline auto http_is_ows(const char character) noexcept -> bool {
29 return character == ' ' || character == '\t';
30}
31
43inline auto http_is_tchar(const char character) noexcept -> bool {
44 switch (character) {
45 case '!':
46 case '#':
47 case '$':
48 case '%':
49 case '&':
50 case '\'':
51 case '*':
52 case '+':
53 case '-':
54 case '.':
55 case '^':
56 case '_':
57 case '`':
58 case '|':
59 case '~':
60 return true;
61 default:
62 return is_alphanum(character);
63 }
64}
65
78inline auto http_is_b64token_char(const char character) noexcept -> bool {
79 return is_alphanum(character) || character == '-' || character == '.' ||
80 character == '_' || character == '~' || character == '+' ||
81 character == '/';
82}
83
96inline auto http_is_b64token(const std::string_view value) noexcept -> bool {
97 std::size_t position{0};
98 while (position < value.size() && http_is_b64token_char(value[position])) {
99 position += 1;
100 }
101
102 if (position == 0) {
103 return false;
104 }
105
106 while (position < value.size()) {
107 if (value[position] != '=') {
108 return false;
109 }
110
111 position += 1;
112 }
113
114 return true;
115}
116
128inline auto http_is_token(const std::string_view value) noexcept -> bool {
129 if (value.empty()) {
130 return false;
131 }
132
133 for (const auto character : value) {
134 if (!http_is_tchar(character)) {
135 return false;
136 }
137 }
138
139 return true;
140}
141
158inline auto http_encode_quoted_string(const std::string_view value,
159 std::string &sink) -> bool {
160 for (const auto character : value) {
161 const auto byte{static_cast<unsigned char>(character)};
162 // RFC 9110 Section 5.6.4: qdtext and quoted-pair admit HTAB, SP through
163 // VCHAR, and obs-text, so every other control character (CR and LF among
164 // them) makes the value unencodable
165 if (byte != 0x09 && (byte < 0x20 || byte == 0x7F)) {
166 return false;
167 }
168 }
169
170 sink.push_back('"');
171 for (const auto character : value) {
172 if (character == '"' || character == '\\') {
173 sink.push_back('\\');
174 }
175
176 sink.push_back(character);
177 }
178
179 sink.push_back('"');
180 return true;
181}
182
195inline auto
196http_field_line_has_forbidden_byte(const std::string_view value) noexcept
197 -> bool {
198 // RFC 9110 Section 5.5: "a recipient of CR, LF, or NUL within a field value
199 // MUST either reject the message or replace each of those characters with SP
200 // before further processing or forwarding of that message", so a field
201 // carrying one is refused as a header-injection defense
202 for (const auto character : value) {
203 if (character == '\r' || character == '\n' || character == '\0') {
204 return true;
205 }
206 }
207
208 return false;
209}
210
221inline auto http_trim_leading_ows(std::string_view value) noexcept
222 -> std::string_view {
223 while (!value.empty() && http_is_ows(value.front())) {
224 value.remove_prefix(1);
225 }
226
227 return value;
228}
229
240inline auto http_trim_trailing_ows(std::string_view value) noexcept
241 -> std::string_view {
242 while (!value.empty() && http_is_ows(value.back())) {
243 value.remove_suffix(1);
244 }
245
246 return value;
247}
248
271SOURCEMETA_CORE_HTTP_EXPORT
272auto http_scan_quoted_string(const std::string_view input,
273 const std::size_t position, std::string &storage,
274 std::string_view &value)
275 -> std::optional<std::size_t>;
276
277} // namespace sourcemeta::core
278
279#endif
auto http_trim_leading_ows(std::string_view value) noexcept -> std::string_view
Definition http_syntax.h:221
auto http_trim_trailing_ows(std::string_view value) noexcept -> std::string_view
Definition http_syntax.h:240
auto http_is_ows(const char character) noexcept -> bool
Definition http_syntax.h:28
auto http_is_token(const std::string_view value) noexcept -> bool
Definition http_syntax.h:128
auto http_is_b64token(const std::string_view value) noexcept -> bool
Definition http_syntax.h:96
auto http_field_line_has_forbidden_byte(const std::string_view value) noexcept -> bool
Definition http_syntax.h:196
auto http_is_b64token_char(const char character) noexcept -> bool
Definition http_syntax.h:78
SOURCEMETA_CORE_HTTP_EXPORT auto http_scan_quoted_string(const std::string_view input, const std::size_t position, std::string &storage, std::string_view &value) -> std::optional< std::size_t >
auto http_is_tchar(const char character) noexcept -> bool
Definition http_syntax.h:43
auto http_encode_quoted_string(const std::string_view value, std::string &sink) -> bool
Definition http_syntax.h:158
constexpr auto is_alphanum(const Character character) noexcept -> bool
Definition text.h:289