Coverage Report

Created: 2024-09-11 06:19

/src/crow/include/crow/common.h
Line
Count
Source (jump to first uncovered line)
1
#pragma once
2
3
#include <vector>
4
#include <string>
5
#include <stdexcept>
6
#include <iostream>
7
#include "crow/utility.h"
8
9
namespace crow
10
{
11
    const char cr = '\r';
12
    const char lf = '\n';
13
    const std::string crlf("\r\n");
14
15
    enum class HTTPMethod : char
16
    {
17
#ifndef DELETE
18
        DELETE = 0,
19
        GET,
20
        HEAD,
21
        POST,
22
        PUT,
23
24
        CONNECT,
25
        OPTIONS,
26
        TRACE,
27
28
        PATCH,
29
        PURGE,
30
31
        COPY,
32
        LOCK,
33
        MKCOL,
34
        MOVE,
35
        PROPFIND,
36
        PROPPATCH,
37
        SEARCH,
38
        UNLOCK,
39
        BIND,
40
        REBIND,
41
        UNBIND,
42
        ACL,
43
44
        REPORT,
45
        MKACTIVITY,
46
        CHECKOUT,
47
        MERGE,
48
49
        MSEARCH,
50
        NOTIFY,
51
        SUBSCRIBE,
52
        UNSUBSCRIBE,
53
54
        MKCALENDAR,
55
56
        LINK,
57
        UNLINK,
58
59
        SOURCE,
60
#endif
61
62
        Delete = 0,
63
        Get,
64
        Head,
65
        Post,
66
        Put,
67
68
        Connect,
69
        Options,
70
        Trace,
71
72
        Patch,
73
        Purge,
74
75
        Copy,
76
        Lock,
77
        MkCol,
78
        Move,
79
        Propfind,
80
        Proppatch,
81
        Search,
82
        Unlock,
83
        Bind,
84
        Rebind,
85
        Unbind,
86
        Acl,
87
88
        Report,
89
        MkActivity,
90
        Checkout,
91
        Merge,
92
93
        MSearch,
94
        Notify,
95
        Subscribe,
96
        Unsubscribe,
97
98
        MkCalendar,
99
100
        Link,
101
        Unlink,
102
103
        Source,
104
105
106
        InternalMethodCount,
107
        // should not add an item below this line: used for array count
108
    };
109
110
    constexpr const char* method_strings[] =
111
      {
112
        "DELETE",
113
        "GET",
114
        "HEAD",
115
        "POST",
116
        "PUT",
117
118
        "CONNECT",
119
        "OPTIONS",
120
        "TRACE",
121
122
        "PATCH",
123
        "PURGE",
124
125
        "COPY",
126
        "LOCK",
127
        "MKCOL",
128
        "MOVE",
129
        "PROPFIND",
130
        "PROPPATCH",
131
        "SEARCH",
132
        "UNLOCK",
133
        "BIND",
134
        "REBIND",
135
        "UNBIND",
136
        "ACL",
137
138
        "REPORT",
139
        "MKACTIVITY",
140
        "CHECKOUT",
141
        "MERGE",
142
143
        "M-SEARCH",
144
        "NOTIFY",
145
        "SUBSCRIBE",
146
        "UNSUBSCRIBE",
147
148
        "MKCALENDAR",
149
150
        "LINK",
151
        "UNLINK",
152
153
        "SOURCE"};
154
155
156
    inline std::string method_name(HTTPMethod method)
157
0
    {
158
0
        if (CROW_LIKELY(method < HTTPMethod::InternalMethodCount))
159
0
        {
160
0
            return method_strings[(unsigned char)method];
161
0
        }
162
0
        return "invalid";
163
0
    }
164
165
    // clang-format off
166
167
    enum status
168
    {
169
        CONTINUE                      = 100,
170
        SWITCHING_PROTOCOLS           = 101,
171
172
        OK                            = 200,
173
        CREATED                       = 201,
174
        ACCEPTED                      = 202,
175
        NON_AUTHORITATIVE_INFORMATION = 203,
176
        NO_CONTENT                    = 204,
177
        RESET_CONTENT                 = 205,
178
        PARTIAL_CONTENT               = 206,
179
180
        MULTIPLE_CHOICES              = 300,
181
        MOVED_PERMANENTLY             = 301,
182
        FOUND                         = 302,
183
        SEE_OTHER                     = 303,
184
        NOT_MODIFIED                  = 304,
185
        TEMPORARY_REDIRECT            = 307,
186
        PERMANENT_REDIRECT            = 308,
187
188
        BAD_REQUEST                   = 400,
189
        UNAUTHORIZED                  = 401,
190
        FORBIDDEN                     = 403,
191
        NOT_FOUND                     = 404,
192
        METHOD_NOT_ALLOWED            = 405,
193
        NOT_ACCEPTABLE                = 406,
194
        PROXY_AUTHENTICATION_REQUIRED = 407,
195
        CONFLICT                      = 409,
196
        GONE                          = 410,
197
        PAYLOAD_TOO_LARGE             = 413,
198
        UNSUPPORTED_MEDIA_TYPE        = 415,
199
        RANGE_NOT_SATISFIABLE         = 416,
200
        EXPECTATION_FAILED            = 417,
201
        PRECONDITION_REQUIRED         = 428,
202
        TOO_MANY_REQUESTS             = 429,
203
        UNAVAILABLE_FOR_LEGAL_REASONS = 451,
204
205
        INTERNAL_SERVER_ERROR         = 500,
206
        NOT_IMPLEMENTED               = 501,
207
        BAD_GATEWAY                   = 502,
208
        SERVICE_UNAVAILABLE           = 503,
209
        GATEWAY_TIMEOUT               = 504,
210
        VARIANT_ALSO_NEGOTIATES       = 506
211
    };
212
213
    // clang-format on
214
215
    enum class ParamType : char
216
    {
217
        INT,
218
        UINT,
219
        DOUBLE,
220
        STRING,
221
        PATH,
222
223
        MAX
224
    };
225
226
    /// @cond SKIP
227
    struct routing_params
228
    {
229
        std::vector<int64_t> int_params;
230
        std::vector<uint64_t> uint_params;
231
        std::vector<double> double_params;
232
        std::vector<std::string> string_params;
233
234
        void debug_print() const
235
0
        {
236
0
            std::cerr << "routing_params" << std::endl;
237
0
            for (auto i : int_params)
238
0
                std::cerr << i << ", ";
239
0
            std::cerr << std::endl;
240
0
            for (auto i : uint_params)
241
0
                std::cerr << i << ", ";
242
0
            std::cerr << std::endl;
243
0
            for (auto i : double_params)
244
0
                std::cerr << i << ", ";
245
0
            std::cerr << std::endl;
246
0
            for (auto& i : string_params)
247
0
                std::cerr << i << ", ";
248
0
            std::cerr << std::endl;
249
0
        }
250
251
        template<typename T>
252
        T get(unsigned) const;
253
    };
254
255
    template<>
256
    inline int64_t routing_params::get<int64_t>(unsigned index) const
257
0
    {
258
0
        return int_params[index];
259
0
    }
260
261
    template<>
262
    inline uint64_t routing_params::get<uint64_t>(unsigned index) const
263
0
    {
264
0
        return uint_params[index];
265
0
    }
266
267
    template<>
268
    inline double routing_params::get<double>(unsigned index) const
269
0
    {
270
0
        return double_params[index];
271
0
    }
272
273
    template<>
274
    inline std::string routing_params::get<std::string>(unsigned index) const
275
0
    {
276
0
        return string_params[index];
277
0
    }
278
    /// @endcond
279
280
    struct routing_handle_result
281
    {
282
        uint16_t rule_index;
283
        std::vector<uint16_t> blueprint_indices;
284
        routing_params r_params;
285
        HTTPMethod method;
286
287
0
        routing_handle_result() {}
288
289
        routing_handle_result(uint16_t rule_index_, std::vector<uint16_t> blueprint_indices_, routing_params r_params_):
290
          rule_index(rule_index_),
291
          blueprint_indices(blueprint_indices_),
292
0
          r_params(r_params_) {}
293
294
        routing_handle_result(uint16_t rule_index_, std::vector<uint16_t> blueprint_indices_, routing_params r_params_, HTTPMethod method_):
295
          rule_index(rule_index_),
296
          blueprint_indices(blueprint_indices_),
297
          r_params(r_params_),
298
0
          method(method_) {}
299
    };
300
} // namespace crow
301
302
// clang-format off
303
#ifndef CROW_MSVC_WORKAROUND
304
constexpr crow::HTTPMethod method_from_string(const char* str)
305
0
{
306
0
    return crow::black_magic::is_equ_p(str, "GET", 3)    ? crow::HTTPMethod::Get :
307
0
           crow::black_magic::is_equ_p(str, "DELETE", 6) ? crow::HTTPMethod::Delete :
308
0
           crow::black_magic::is_equ_p(str, "HEAD", 4)   ? crow::HTTPMethod::Head :
309
0
           crow::black_magic::is_equ_p(str, "POST", 4)   ? crow::HTTPMethod::Post :
310
0
           crow::black_magic::is_equ_p(str, "PUT", 3)    ? crow::HTTPMethod::Put :
311
0
312
0
           crow::black_magic::is_equ_p(str, "OPTIONS", 7) ? crow::HTTPMethod::Options :
313
0
           crow::black_magic::is_equ_p(str, "CONNECT", 7) ? crow::HTTPMethod::Connect :
314
0
           crow::black_magic::is_equ_p(str, "TRACE", 5)   ? crow::HTTPMethod::Trace :
315
0
316
0
           crow::black_magic::is_equ_p(str, "PATCH", 5)     ? crow::HTTPMethod::Patch :
317
0
           crow::black_magic::is_equ_p(str, "PURGE", 5)     ? crow::HTTPMethod::Purge :
318
0
           crow::black_magic::is_equ_p(str, "COPY", 4)      ? crow::HTTPMethod::Copy :
319
0
           crow::black_magic::is_equ_p(str, "LOCK", 4)      ? crow::HTTPMethod::Lock :
320
0
           crow::black_magic::is_equ_p(str, "MKCOL", 5)     ? crow::HTTPMethod::MkCol :
321
0
           crow::black_magic::is_equ_p(str, "MOVE", 4)      ? crow::HTTPMethod::Move :
322
0
           crow::black_magic::is_equ_p(str, "PROPFIND", 8)  ? crow::HTTPMethod::Propfind :
323
0
           crow::black_magic::is_equ_p(str, "PROPPATCH", 9) ? crow::HTTPMethod::Proppatch :
324
0
           crow::black_magic::is_equ_p(str, "SEARCH", 6)    ? crow::HTTPMethod::Search :
325
0
           crow::black_magic::is_equ_p(str, "UNLOCK", 6)    ? crow::HTTPMethod::Unlock :
326
0
           crow::black_magic::is_equ_p(str, "BIND", 4)      ? crow::HTTPMethod::Bind :
327
0
           crow::black_magic::is_equ_p(str, "REBIND", 6)    ? crow::HTTPMethod::Rebind :
328
0
           crow::black_magic::is_equ_p(str, "UNBIND", 6)    ? crow::HTTPMethod::Unbind :
329
0
           crow::black_magic::is_equ_p(str, "ACL", 3)       ? crow::HTTPMethod::Acl :
330
0
331
0
           crow::black_magic::is_equ_p(str, "REPORT", 6)      ? crow::HTTPMethod::Report :
332
0
           crow::black_magic::is_equ_p(str, "MKACTIVITY", 10) ? crow::HTTPMethod::MkActivity :
333
0
           crow::black_magic::is_equ_p(str, "CHECKOUT", 8)    ? crow::HTTPMethod::Checkout :
334
0
           crow::black_magic::is_equ_p(str, "MERGE", 5)       ? crow::HTTPMethod::Merge :
335
0
336
0
           crow::black_magic::is_equ_p(str, "MSEARCH", 7)      ? crow::HTTPMethod::MSearch :
337
0
           crow::black_magic::is_equ_p(str, "NOTIFY", 6)       ? crow::HTTPMethod::Notify :
338
0
           crow::black_magic::is_equ_p(str, "SUBSCRIBE", 9)    ? crow::HTTPMethod::Subscribe :
339
0
           crow::black_magic::is_equ_p(str, "UNSUBSCRIBE", 11) ? crow::HTTPMethod::Unsubscribe :
340
0
341
0
           crow::black_magic::is_equ_p(str, "MKCALENDAR", 10) ? crow::HTTPMethod::MkCalendar :
342
0
343
0
           crow::black_magic::is_equ_p(str, "LINK", 4)   ? crow::HTTPMethod::Link :
344
0
           crow::black_magic::is_equ_p(str, "UNLINK", 6) ? crow::HTTPMethod::Unlink :
345
0
346
0
           crow::black_magic::is_equ_p(str, "SOURCE", 6) ? crow::HTTPMethod::Source :
347
0
                                                           throw std::runtime_error("invalid http method");
348
0
}
349
350
constexpr crow::HTTPMethod operator"" _method(const char* str, size_t /*len*/)
351
0
{
352
0
    return method_from_string( str );
353
0
}
354
#endif
355
// clang-format on