Coverage Report

Created: 2025-07-18 06:55

/src/pistache/include/pistache/http_defs.h
Line
Count
Source (jump to first uncovered line)
1
/*
2
 * SPDX-FileCopyrightText: 2015 Mathieu Stefani
3
 *
4
 * SPDX-License-Identifier: Apache-2.0
5
 */
6
7
/* http_defs.h
8
   Mathieu Stefani, 01 September 2015
9
10
   Various http definitions
11
*/
12
13
#pragma once
14
15
#include <chrono>
16
#include <functional>
17
#include <ostream>
18
#include <stdexcept>
19
#include <string>
20
21
namespace Pistache::Http
22
{
23
24
#define HTTP_METHODS                               \
25
0
    METHOD(Options, "OPTIONS")                     \
26
0
    METHOD(Get, "GET")                             \
27
0
    METHOD(Post, "POST")                           \
28
0
    METHOD(Head, "HEAD")                           \
29
0
    METHOD(Put, "PUT")                             \
30
0
    METHOD(Patch, "PATCH")                         \
31
0
    METHOD(Delete, "DELETE")                       \
32
0
    METHOD(Trace, "TRACE")                         \
33
0
    METHOD(Connect, "CONNECT")                     \
34
0
    METHOD(Acl, "ACL")                             \
35
0
    METHOD(BaselineControl, "BASELINE-CONTROL")    \
36
0
    METHOD(Bind, "BIND")                           \
37
0
    METHOD(Checkin, "CHECKIN")                     \
38
0
    METHOD(Checkout, "CHECKOUT")                   \
39
0
    METHOD(Copy, "COPY")                           \
40
0
    METHOD(Label, "LABEL")                         \
41
0
    METHOD(Link, "LINK")                           \
42
0
    METHOD(Lock, "LOCK")                           \
43
0
    METHOD(Merge, "MERGE")                         \
44
0
    METHOD(Mkactivity, "MKACTIVITY")               \
45
0
    METHOD(Mkcalendar, "MKCALENDAR")               \
46
0
    METHOD(Mkcol, "MKCOL")                         \
47
0
    METHOD(Mkredirectref, "MKREDIRECTREF")         \
48
0
    METHOD(Mkworkspace, "MKWORKSPACE")             \
49
0
    METHOD(Move, "MOVE")                           \
50
0
    METHOD(Orderpatch, "ORDERPATCH")               \
51
0
    METHOD(Pri, "PRI")                             \
52
0
    METHOD(Propfind, "PROPFIND")                   \
53
0
    METHOD(Proppatch, "PROPPATCH")                 \
54
0
    METHOD(Rebind, "REBIND")                       \
55
0
    METHOD(Report, "REPORT")                       \
56
0
    METHOD(Search, "SEARCH")                       \
57
0
    METHOD(Unbind, "UNBIND")                       \
58
0
    METHOD(Uncheckout, "UNCHECKOUT")               \
59
0
    METHOD(Unlink, "UNLINK")                       \
60
0
    METHOD(Unlock, "UNLOCK")                       \
61
0
    METHOD(Update, "UPDATE")                       \
62
0
    METHOD(Updateredirectref, "UPDATEREDIRECTREF") \
63
0
    METHOD(VersionControl, "VERSION-CONTROL")
64
65
// 10. Status Code Definitions
66
#define STATUS_CODES                                                          \
67
0
    CODE(100, Continue, "Continue")                                           \
68
0
    CODE(101, Switching_Protocols, "Switching Protocols")                     \
69
0
    CODE(102, Processing, "Processing")                                       \
70
0
    CODE(103, Early_Hints, "Early Hints")                                     \
71
0
    CODE(200, Ok, "OK")                                                       \
72
0
    CODE(201, Created, "Created")                                             \
73
0
    CODE(202, Accepted, "Accepted")                                           \
74
0
    CODE(203, NonAuthoritative_Information, "Non-Authoritative Information")  \
75
0
    CODE(204, No_Content, "No Content")                                       \
76
0
    CODE(205, Reset_Content, "Reset Content")                                 \
77
0
    CODE(206, Partial_Content, "Partial Content")                             \
78
0
    CODE(207, MultiStatus, "Multi-Status")                                    \
79
0
    CODE(208, Already_Reported, "Already Reported")                           \
80
0
    CODE(226, IM_Used, "IM Used")                                             \
81
0
    CODE(300, Multiple_Choices, "Multiple Choices")                           \
82
0
    CODE(301, Moved_Permanently, "Moved Permanently")                         \
83
0
    CODE(302, Found, "Found")                                                 \
84
0
    CODE(303, See_Other, "See Other")                                         \
85
0
    CODE(304, Not_Modified, "Not Modified")                                   \
86
0
    CODE(305, Use_Proxy, "Use Proxy")                                         \
87
0
    CODE(307, Temporary_Redirect, "Temporary Redirect")                       \
88
0
    CODE(308, Permanent_Redirect, "Permanent Redirect")                       \
89
0
    CODE(400, Bad_Request, "Bad Request")                                     \
90
0
    CODE(401, Unauthorized, "Unauthorized")                                   \
91
0
    CODE(402, Payment_Required, "Payment Required")                           \
92
0
    CODE(403, Forbidden, "Forbidden")                                         \
93
0
    CODE(404, Not_Found, "Not Found")                                         \
94
0
    CODE(405, Method_Not_Allowed, "Method Not Allowed")                       \
95
0
    CODE(406, Not_Acceptable, "Not Acceptable")                               \
96
0
    CODE(407, Proxy_Authentication_Required, "Proxy Authentication Required") \
97
0
    CODE(408, Request_Timeout, "Request Timeout")                             \
98
0
    CODE(409, Conflict, "Conflict")                                           \
99
0
    CODE(410, Gone, "Gone")                                                   \
100
0
    CODE(411, Length_Required, "Length Required")                             \
101
0
    CODE(412, Precondition_Failed, "Precondition Failed")                     \
102
0
    CODE(413, Request_Entity_Too_Large, "Request Entity Too Large")           \
103
0
    CODE(414, RequestURI_Too_Long, "Request-URI Too Long")                    \
104
0
    CODE(415, Unsupported_Media_Type, "Unsupported Media Type")               \
105
0
    CODE(416, Requested_Range_Not_Satisfiable,                                \
106
0
         "Requested Range Not Satisfiable")                                   \
107
0
    CODE(417, Expectation_Failed, "Expectation Failed")                       \
108
0
    CODE(418, I_m_a_teapot, "I'm a teapot")                                   \
109
0
    CODE(421, Misdirected_Request, "Misdirected Request")                     \
110
0
    CODE(422, Unprocessable_Entity, "Unprocessable Entity")                   \
111
0
    CODE(423, Locked, "Locked")                                               \
112
0
    CODE(424, Failed_Dependency, "Failed Dependency")                         \
113
0
    CODE(426, Upgrade_Required, "Upgrade Required")                           \
114
0
    CODE(428, Precondition_Required, "Precondition Required")                 \
115
0
    CODE(429, Too_Many_Requests, "Too Many Requests")                         \
116
0
    CODE(431, Request_Header_Fields_Too_Large,                                \
117
0
         "Request Header Fields Too Large")                                   \
118
0
    CODE(444, Connection_Closed_Without_Response,                             \
119
0
         "Connection Closed Without Response")                                \
120
0
    CODE(451, Unavailable_For_Legal_Reasons, "Unavailable For Legal Reasons") \
121
0
    CODE(499, Client_Closed_Request, "Client Closed Request")                 \
122
0
    CODE(500, Internal_Server_Error, "Internal Server Error")                 \
123
0
    CODE(501, Not_Implemented, "Not Implemented")                             \
124
0
    CODE(502, Bad_Gateway, "Bad Gateway")                                     \
125
0
    CODE(503, Service_Unavailable, "Service Unavailable")                     \
126
0
    CODE(504, Gateway_Timeout, "Gateway Timeout")                             \
127
0
    CODE(505, HTTP_Version_Not_Supported, "HTTP Version Not Supported")       \
128
0
    CODE(506, Variant_Also_Negotiates, "Variant Also Negotiates")             \
129
0
    CODE(507, Insufficient_Storage, "Insufficient Storage")                   \
130
0
    CODE(508, Loop_Detected, "Loop Detected")                                 \
131
0
    CODE(510, Not_Extended, "Not Extended")                                   \
132
0
    CODE(511, Network_Authentication_Required,                                \
133
0
         "Network Authentication Required")                                   \
134
0
    CODE(599, Network_Connect_Timeout_Error, "Network Connect Timeout Error")
135
136
// 3.4. Character Sets
137
// See http://tools.ietf.org/html/rfc2978 and
138
// http://www.iana.org/assignments/character-sets/character-sets.xhtml
139
#define CHARSETS                            \
140
    CHARSET(UsAscii, "us-ascii")            \
141
    CHARSET(Iso - 8859 - 1, "iso-8859-1")   \
142
    CHARSET(Iso - 8859 - 2, "iso-8859-2")   \
143
    CHARSET(Iso - 8859 - 3, "iso-8859-3")   \
144
    CHARSET(Iso - 8859 - 4, "iso-8859-4")   \
145
    CHARSET(Iso - 8859 - 5, "iso-8859-5")   \
146
    CHARSET(Iso - 8859 - 6, "iso-8859-6")   \
147
    CHARSET(Iso - 8859 - 7, "iso-8859-7")   \
148
    CHARSET(Iso - 8859 - 8, "iso-8859-8")   \
149
    CHARSET(Iso - 8859 - 9, "iso-8859-9")   \
150
    CHARSET(Iso - 8859 - 10, "iso-8859-10") \
151
    CHARSET(Shift - JIS, "shift_jis")       \
152
    CHARSET(Utf7, "utf-7")                  \
153
    CHARSET(Utf8, "utf-8")                  \
154
    CHARSET(Utf16, "utf-16")                \
155
    CHARSET(Utf16 - BE, "utf-16be")         \
156
    CHARSET(Utf16 - LE, "utf-16le")         \
157
    CHARSET(Utf32, "utf-32")                \
158
    CHARSET(Utf32 - BE, "utf-32be")         \
159
    CHARSET(Utf32 - LE, "utf-32le")         \
160
    CHARSET(Unicode - 11, "unicode-1-1")
161
162
    enum class Method {
163
#define METHOD(m, _) m,
164
        HTTP_METHODS
165
#undef METHOD
166
    };
167
168
    enum class Code {
169
#define CODE(value, name, _) name = value,
170
        STATUS_CODES
171
#undef CODE
172
    };
173
174
    enum class Version {
175
        Http10, // HTTP/1.0
176
        Http11 // HTTP/1.1
177
    };
178
179
    enum class ConnectionControl { Close,
180
                                   KeepAlive,
181
                                   Ext };
182
183
    enum class Expectation { Continue,
184
                             Ext };
185
186
    class CacheDirective
187
    {
188
    public:
189
        enum Directive {
190
            NoCache,
191
            NoStore,
192
            MaxAge,
193
            MaxStale,
194
            MinFresh,
195
            NoTransform,
196
            OnlyIfCached,
197
            Public,
198
            Private,
199
            MustRevalidate,
200
            ProxyRevalidate,
201
            SMaxAge,
202
            Ext
203
        };
204
205
        CacheDirective()
206
            : directive_()
207
            , data()
208
0
        { }
209
210
        explicit CacheDirective(Directive directive);
211
        CacheDirective(Directive directive, std::chrono::seconds delta);
212
213
357k
        Directive directive() const { return directive_; }
214
        std::chrono::seconds delta() const;
215
216
    private:
217
        void init(Directive directive, std::chrono::seconds delta);
218
        Directive directive_;
219
        // Poor way of representing tagged unions in C++
220
        union
221
        {
222
            uint64_t maxAge;
223
            uint64_t sMaxAge;
224
            uint64_t maxStale;
225
            uint64_t minFresh;
226
        } data;
227
    };
228
229
    // 3.3.1 Full Date
230
    class FullDate
231
    {
232
    public:
233
        using time_point = std::chrono::system_clock::time_point;
234
        FullDate()
235
9.38k
            : date_()
236
9.38k
        { }
237
238
        enum class Type { RFC1123,
239
                          RFC850,
240
                          AscTime,
241
                          RFC1123GMT };
242
243
        explicit FullDate(time_point date)
244
6.67k
            : date_(date)
245
6.67k
        { }
246
247
0
        time_point date() const { return date_; }
248
        void write(std::ostream& os, Type type = Type::RFC1123) const;
249
250
        static FullDate fromString(const std::string& str);
251
252
    private:
253
        time_point date_;
254
    };
255
256
    const char* methodString(Method method);
257
    const char* versionString(Version version);
258
    const char* codeString(Code code);
259
260
    std::ostream& operator<<(std::ostream& os, Version version);
261
    std::ostream& operator<<(std::ostream& os, Method method);
262
    std::ostream& operator<<(std::ostream& os, Code code);
263
264
    struct HttpError : public std::exception
265
    {
266
        HttpError(Code code, std::string reason);
267
        HttpError(int code, std::string reason);
268
269
9.71k
        ~HttpError() noexcept override = default;
270
271
0
        const char* what() const noexcept override { return reason_.c_str(); }
272
273
0
        int code() const { return code_; }
274
0
        std::string reason() const { return reason_; }
275
276
    private:
277
        int code_;
278
        std::string reason_;
279
    };
280
281
} // namespace Pistache::Http
282
283
namespace std
284
{
285
286
    template <>
287
    struct hash<Pistache::Http::Method>
288
    {
289
        size_t operator()(Pistache::Http::Method method) const
290
0
        {
291
0
            return std::hash<int>()(static_cast<int>(method));
292
0
        }
293
    };
294
295
} // namespace std