1 | // |
2 | // HTTPCookie.cpp |
3 | // |
4 | // Library: Net |
5 | // Package: HTTP |
6 | // Module: HTTPCookie |
7 | // |
8 | // Copyright (c) 2005-2006, Applied Informatics Software Engineering GmbH. |
9 | // and Contributors. |
10 | // |
11 | // SPDX-License-Identifier: BSL-1.0 |
12 | // |
13 | |
14 | |
15 | #include "Poco/Net/HTTPCookie.h" |
16 | #include "Poco/Net/NameValueCollection.h" |
17 | #include "Poco/Timestamp.h" |
18 | #include "Poco/DateTime.h" |
19 | #include "Poco/DateTimeFormatter.h" |
20 | #include "Poco/DateTimeFormat.h" |
21 | #include "Poco/DateTimeParser.h" |
22 | #include "Poco/NumberFormatter.h" |
23 | #include "Poco/NumberParser.h" |
24 | #include "Poco/String.h" |
25 | #include "Poco/URI.h" |
26 | |
27 | |
28 | using Poco::Timestamp; |
29 | using Poco::DateTime; |
30 | using Poco::DateTimeFormatter; |
31 | using Poco::DateTimeFormat; |
32 | using Poco::DateTimeParser; |
33 | using Poco::NumberFormatter; |
34 | using Poco::NumberParser; |
35 | using Poco::icompare; |
36 | |
37 | |
38 | namespace Poco { |
39 | namespace Net { |
40 | |
41 | |
42 | HTTPCookie::HTTPCookie(): |
43 | _version(0), |
44 | _secure(false), |
45 | _maxAge(-1), |
46 | _httpOnly(false) |
47 | { |
48 | } |
49 | |
50 | |
51 | HTTPCookie::HTTPCookie(const std::string& name): |
52 | _version(0), |
53 | _name(name), |
54 | _secure(false), |
55 | _maxAge(-1), |
56 | _httpOnly(false) |
57 | { |
58 | } |
59 | |
60 | |
61 | HTTPCookie::HTTPCookie(const NameValueCollection& nvc): |
62 | _version(0), |
63 | _secure(false), |
64 | _maxAge(-1), |
65 | _httpOnly(false) |
66 | { |
67 | for (NameValueCollection::ConstIterator it = nvc.begin(); it != nvc.end(); ++it) |
68 | { |
69 | const std::string& name = it->first; |
70 | const std::string& value = it->second; |
71 | if (icompare(name, "comment" ) == 0) |
72 | { |
73 | setComment(value); |
74 | } |
75 | else if (icompare(name, "domain" ) == 0) |
76 | { |
77 | setDomain(value); |
78 | } |
79 | else if (icompare(name, "path" ) == 0) |
80 | { |
81 | setPath(value); |
82 | } |
83 | else if (icompare(name, "priority" ) == 0) |
84 | { |
85 | setPriority(value); |
86 | } |
87 | else if (icompare(name, "max-age" ) == 0) |
88 | { |
89 | setMaxAge(NumberParser::parse(value)); |
90 | } |
91 | else if (icompare(name, "secure" ) == 0) |
92 | { |
93 | setSecure(true); |
94 | } |
95 | else if (icompare(name, "expires" ) == 0) |
96 | { |
97 | int tzd; |
98 | DateTime exp = DateTimeParser::parse(value, tzd); |
99 | Timestamp now; |
100 | setMaxAge((int) ((exp.timestamp() - now) / Timestamp::resolution())); |
101 | } |
102 | else if (icompare(name, "version" ) == 0) |
103 | { |
104 | setVersion(NumberParser::parse(value)); |
105 | } |
106 | else if (icompare(name, "HttpOnly" ) == 0) |
107 | { |
108 | setHttpOnly(true); |
109 | } |
110 | else |
111 | { |
112 | setName(name); |
113 | setValue(value); |
114 | } |
115 | } |
116 | } |
117 | |
118 | |
119 | HTTPCookie::HTTPCookie(const std::string& name, const std::string& value): |
120 | _version(0), |
121 | _name(name), |
122 | _value(value), |
123 | _secure(false), |
124 | _maxAge(-1), |
125 | _httpOnly(false) |
126 | { |
127 | } |
128 | |
129 | |
130 | HTTPCookie::HTTPCookie(const HTTPCookie& cookie): |
131 | _version(cookie._version), |
132 | _name(cookie._name), |
133 | _value(cookie._value), |
134 | _comment(cookie._comment), |
135 | _domain(cookie._domain), |
136 | _path(cookie._path), |
137 | _priority(cookie._priority), |
138 | _secure(cookie._secure), |
139 | _maxAge(cookie._maxAge), |
140 | _httpOnly(cookie._httpOnly) |
141 | { |
142 | } |
143 | |
144 | |
145 | HTTPCookie::~HTTPCookie() |
146 | { |
147 | } |
148 | |
149 | |
150 | HTTPCookie& HTTPCookie::operator = (const HTTPCookie& cookie) |
151 | { |
152 | if (&cookie != this) |
153 | { |
154 | _version = cookie._version; |
155 | _name = cookie._name; |
156 | _value = cookie._value; |
157 | _comment = cookie._comment; |
158 | _domain = cookie._domain; |
159 | _path = cookie._path; |
160 | _priority = cookie._priority; |
161 | _secure = cookie._secure; |
162 | _maxAge = cookie._maxAge; |
163 | _httpOnly = cookie._httpOnly; |
164 | } |
165 | return *this; |
166 | } |
167 | |
168 | |
169 | void HTTPCookie::setVersion(int version) |
170 | { |
171 | _version = version; |
172 | } |
173 | |
174 | |
175 | void HTTPCookie::setName(const std::string& name) |
176 | { |
177 | _name = name; |
178 | } |
179 | |
180 | |
181 | void HTTPCookie::setValue(const std::string& value) |
182 | { |
183 | _value = value; |
184 | } |
185 | |
186 | |
187 | void HTTPCookie::(const std::string& ) |
188 | { |
189 | _comment = comment; |
190 | } |
191 | |
192 | |
193 | void HTTPCookie::setDomain(const std::string& domain) |
194 | { |
195 | _domain = domain; |
196 | } |
197 | |
198 | |
199 | void HTTPCookie::setPath(const std::string& path) |
200 | { |
201 | _path = path; |
202 | } |
203 | |
204 | |
205 | void HTTPCookie::setPriority(const std::string& priority) |
206 | { |
207 | _priority = priority; |
208 | } |
209 | |
210 | |
211 | void HTTPCookie::setSecure(bool secure) |
212 | { |
213 | _secure = secure; |
214 | } |
215 | |
216 | |
217 | void HTTPCookie::setMaxAge(int maxAge) |
218 | { |
219 | _maxAge = maxAge; |
220 | } |
221 | |
222 | |
223 | void HTTPCookie::setHttpOnly(bool flag) |
224 | { |
225 | _httpOnly = flag; |
226 | } |
227 | |
228 | |
229 | std::string HTTPCookie::toString() const |
230 | { |
231 | std::string result; |
232 | result.reserve(256); |
233 | result.append(_name); |
234 | result.append("=" ); |
235 | if (_version == 0) |
236 | { |
237 | // Netscape cookie |
238 | result.append(_value); |
239 | if (!_domain.empty()) |
240 | { |
241 | result.append("; domain=" ); |
242 | result.append(_domain); |
243 | } |
244 | if (!_path.empty()) |
245 | { |
246 | result.append("; path=" ); |
247 | result.append(_path); |
248 | } |
249 | if (!_priority.empty()) |
250 | { |
251 | result.append("; Priority=" ); |
252 | result.append(_priority); |
253 | } |
254 | if (_maxAge != -1) |
255 | { |
256 | Timestamp ts; |
257 | ts += _maxAge * Timestamp::resolution(); |
258 | result.append("; expires=" ); |
259 | DateTimeFormatter::append(result, ts, DateTimeFormat::HTTP_FORMAT); |
260 | } |
261 | if (_secure) |
262 | { |
263 | result.append("; secure" ); |
264 | } |
265 | if (_httpOnly) |
266 | { |
267 | result.append("; HttpOnly" ); |
268 | } |
269 | } |
270 | else |
271 | { |
272 | // RFC 2109 cookie |
273 | result.append("\"" ); |
274 | result.append(_value); |
275 | result.append("\"" ); |
276 | if (!_comment.empty()) |
277 | { |
278 | result.append("; Comment=\"" ); |
279 | result.append(_comment); |
280 | result.append("\"" ); |
281 | } |
282 | if (!_domain.empty()) |
283 | { |
284 | result.append("; Domain=\"" ); |
285 | result.append(_domain); |
286 | result.append("\"" ); |
287 | } |
288 | if (!_path.empty()) |
289 | { |
290 | result.append("; Path=\"" ); |
291 | result.append(_path); |
292 | result.append("\"" ); |
293 | } |
294 | if (!_priority.empty()) |
295 | { |
296 | result.append("; Priority=\"" ); |
297 | result.append(_priority); |
298 | result.append("\"" ); |
299 | } |
300 | |
301 | if (_maxAge != -1) |
302 | { |
303 | result.append("; Max-Age=\"" ); |
304 | NumberFormatter::append(result, _maxAge); |
305 | result.append("\"" ); |
306 | } |
307 | if (_secure) |
308 | { |
309 | result.append("; secure" ); |
310 | } |
311 | if (_httpOnly) |
312 | { |
313 | result.append("; HttpOnly" ); |
314 | } |
315 | result.append("; Version=\"1\"" ); |
316 | } |
317 | return result; |
318 | } |
319 | |
320 | |
321 | namespace |
322 | { |
323 | static const std::string ILLEGAL_CHARS("()[]/|\\',;" ); |
324 | } |
325 | |
326 | |
327 | std::string HTTPCookie::escape(const std::string& str) |
328 | { |
329 | std::string result; |
330 | Poco::URI::encode(str, ILLEGAL_CHARS, result); |
331 | return result; |
332 | } |
333 | |
334 | |
335 | std::string HTTPCookie::unescape(const std::string& str) |
336 | { |
337 | std::string result; |
338 | Poco::URI::decode(str, result); |
339 | return result; |
340 | } |
341 | |
342 | |
343 | } } // namespace Poco::Net |
344 | |