line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
1
|
|
|
|
|
|
|
#pragma once |
2
|
|
|
|
|
|
|
#include "Message.h" |
3
|
|
|
|
|
|
|
#include |
4
|
|
|
|
|
|
|
#include |
5
|
|
|
|
|
|
|
#include |
6
|
|
|
|
|
|
|
|
7
|
|
|
|
|
|
|
|
8
|
|
|
|
|
|
|
namespace panda { namespace protocol { namespace http { |
9
|
|
|
|
|
|
|
|
10
|
|
|
|
|
|
|
struct Request; |
11
|
|
|
|
|
|
|
|
12
|
|
|
|
|
|
|
extern const panda::time::Timezone* gmtz; |
13
|
|
|
|
|
|
|
|
14
|
|
|
|
|
|
|
struct Response : Message, AllocatedObject { |
15
|
|
|
|
|
|
|
using Date = panda::date::Date; |
16
|
|
|
|
|
|
|
struct Builder; template struct BuilderImpl; |
17
|
|
|
|
|
|
|
|
18
|
|
|
|
|
|
|
struct Cookie { |
19
|
|
|
|
|
|
|
enum class SameSite { disabled = 0, Strict, Lax, None }; |
20
|
|
|
|
|
|
|
|
21
|
|
|
|
|
|
|
Cookie (const string& value = "", const string& domain = "", const string& path = "", uint64_t max_age = 0, bool secure = false, |
22
|
|
|
|
|
|
|
bool http_only = false, SameSite same_site = SameSite::disabled) : |
23
|
|
|
|
|
|
|
_value(value), _domain(domain), _path(path), _max_age(max_age), _secure(secure), _http_only(http_only), _same_site(same_site) |
24
|
|
|
|
|
|
|
{} |
25
|
|
|
|
|
|
|
|
26
|
|
|
|
|
|
|
const string& value () const { return _value; } |
27
|
|
|
|
|
|
|
const string& domain () const { return _domain; } |
28
|
|
|
|
|
|
|
const string& path () const { return _path; } |
29
|
|
|
|
|
|
|
uint64_t max_age () const { return _max_age; } |
30
|
|
|
|
|
|
|
optional expires () const { if (!_expires) return {}; return Date(_expires); } |
31
|
|
|
|
|
|
|
bool secure () const { return _secure; } |
32
|
|
|
|
|
|
|
bool http_only () const { return _http_only; } |
33
|
|
|
|
|
|
|
bool session () const { return !(_max_age || _expires); } |
34
|
|
|
|
|
|
|
SameSite same_site () const { return _same_site; } |
35
|
|
|
|
|
|
|
int64_t max_age_any () const; |
36
|
|
|
|
|
|
|
optional expires_any () const; |
37
|
|
|
|
|
|
|
|
38
|
|
|
|
|
|
|
Cookie& value (const string& v) { _value = v; return *this; } |
39
|
|
|
|
|
|
|
Cookie& domain (const string& v) { _domain = v; return *this; } |
40
|
|
|
|
|
|
|
Cookie& path (const string& v) { _path = v; return *this; } |
41
|
|
|
|
|
|
|
Cookie& max_age (uint64_t v) { _max_age = v; _expires.clear(); return *this; } |
42
|
|
|
|
|
|
|
Cookie& secure (bool v) { _secure = v; return *this; } |
43
|
|
|
|
|
|
|
Cookie& http_only (bool v) { _http_only = v; return *this; } |
44
|
|
|
|
|
|
|
Cookie& same_site (SameSite v) { _same_site = v; return *this; } |
45
|
|
|
|
|
|
|
|
46
|
|
|
|
|
|
|
Cookie& expires (const Date& _d) { |
47
|
|
|
|
|
|
|
auto d = _d; |
48
|
|
|
|
|
|
|
d.to_timezone(gmtz); |
49
|
|
|
|
|
|
|
_expires = d.to_string(Date::Format::rfc1123); |
50
|
|
|
|
|
|
|
_max_age = 0; |
51
|
|
|
|
|
|
|
return *this; |
52
|
|
|
|
|
|
|
} |
53
|
|
|
|
|
|
|
|
54
|
|
|
|
|
|
|
string to_string (const string& cookie_name, const Request* context = nullptr) const; |
55
|
|
|
|
|
|
|
void serialize_to (string& acc, const string& name, const Request* req = nullptr) const; |
56
|
|
|
|
|
|
|
|
57
|
|
|
|
|
|
|
private: |
58
|
|
|
|
|
|
|
friend struct ResponseParser; friend struct RequestParser; |
59
|
|
|
|
|
|
|
|
60
|
|
|
|
|
|
|
string _value; |
61
|
|
|
|
|
|
|
string _domain; |
62
|
|
|
|
|
|
|
string _path; |
63
|
|
|
|
|
|
|
uint64_t _max_age = 0; |
64
|
|
|
|
|
|
|
string _expires; |
65
|
|
|
|
|
|
|
bool _secure = false; |
66
|
|
|
|
|
|
|
bool _http_only = false; |
67
|
|
|
|
|
|
|
SameSite _same_site = SameSite::disabled; |
68
|
|
|
|
|
|
|
}; |
69
|
|
|
|
|
|
|
|
70
|
0
|
|
|
|
|
|
struct Cookies : Fields { |
71
|
|
|
|
|
|
|
optional get (const string& key) { |
72
|
|
|
|
|
|
|
auto it = find(key); |
73
|
|
|
|
|
|
|
if (it == fields.cend()) return {}; |
74
|
|
|
|
|
|
|
return it->value; |
75
|
|
|
|
|
|
|
} |
76
|
|
|
|
|
|
|
}; |
77
|
|
|
|
|
|
|
|
78
|
|
|
|
|
|
|
int code = 0; |
79
|
|
|
|
|
|
|
string message; |
80
|
|
|
|
|
|
|
Cookies cookies; |
81
|
|
|
|
|
|
|
|
82
|
0
|
0
|
|
|
|
|
Response () : code() {} |
|
|
0
|
|
|
|
|
|
83
|
|
|
|
|
|
|
|
84
|
|
|
|
|
|
|
Response (int code, Headers&& header = Headers(), Body&& body = Body(), bool chunked = false, int http_version = 0, const string& message = {}) : |
85
|
|
|
|
|
|
|
Message(std::move(header), std::move(body), chunked, http_version), code(code), message(message) |
86
|
|
|
|
|
|
|
{} |
87
|
|
|
|
|
|
|
|
88
|
|
|
|
|
|
|
string full_message () const { return panda::to_string(code) + " " + (message ? message : message_for_code(code)); } |
89
|
|
|
|
|
|
|
|
90
|
|
|
|
|
|
|
std::vector to_vector (const Request* req = nullptr) const; |
91
|
|
|
|
|
|
|
string to_string (const Request* req = nullptr) const { return Message::to_string(to_vector(req)); } |
92
|
|
|
|
|
|
|
|
93
|
|
|
|
|
|
|
static string message_for_code (int code); |
94
|
|
|
|
|
|
|
|
95
|
|
|
|
|
|
|
void parse_set_cookie (const string& buffer); |
96
|
|
|
|
|
|
|
|
97
|
|
|
|
|
|
|
protected: |
98
|
|
|
|
|
|
|
~Response () {} |
99
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
private: |
101
|
|
|
|
|
|
|
friend struct ResponseParser; |
102
|
|
|
|
|
|
|
|
103
|
|
|
|
|
|
|
string _http_header (SerializationContext& ctx) const; |
104
|
|
|
|
|
|
|
}; |
105
|
|
|
|
|
|
|
using ResponseSP = iptr; |
106
|
|
|
|
|
|
|
|
107
|
|
|
|
|
|
|
template |
108
|
|
|
|
|
|
|
struct Response::BuilderImpl : Message::Builder { |
109
|
|
|
|
|
|
|
using Message::Builder::Builder; |
110
|
|
|
|
|
|
|
|
111
|
|
|
|
|
|
|
T& code (int code) { |
112
|
|
|
|
|
|
|
this->_message->code = code; |
113
|
|
|
|
|
|
|
return this->self(); |
114
|
|
|
|
|
|
|
} |
115
|
|
|
|
|
|
|
|
116
|
|
|
|
|
|
|
T& message (const string& message) { |
117
|
|
|
|
|
|
|
this->_message->message = message; |
118
|
|
|
|
|
|
|
return this->self(); |
119
|
|
|
|
|
|
|
} |
120
|
|
|
|
|
|
|
|
121
|
|
|
|
|
|
|
T& cookie (const string& name, const Response::Cookie& coo) { |
122
|
|
|
|
|
|
|
this->_message->cookies.add(name, coo); |
123
|
|
|
|
|
|
|
return this->self(); |
124
|
|
|
|
|
|
|
} |
125
|
|
|
|
|
|
|
}; |
126
|
|
|
|
|
|
|
|
127
|
|
|
|
|
|
|
struct Response::Builder : Response::BuilderImpl { |
128
|
|
|
|
|
|
|
Builder () : BuilderImpl(new Response()) {} |
129
|
|
|
|
|
|
|
}; |
130
|
|
|
|
|
|
|
|
131
|
|
|
|
|
|
|
}}} |