1#ifndef CPR_COOKIES_H
2#define CPR_COOKIES_H
3
4#include "cpr/curlholder.h"
5#include <chrono>
6#include <initializer_list>
7#include <sstream>
8#include <string>
9#include <vector>
10
11namespace cpr {
12/**
13 * EXPIRES_STRING_SIZE is an explicitly static and const variable that could be only accessed within the same namespace and is immutable.
14 * To be used for "std::array", the expression must have a constant value, so EXPIRES_STRING_SIZE must be a const value.
15 **/
16static const std::size_t EXPIRES_STRING_SIZE = 100;
17
18class Cookie {
19 public:
20 Cookie() = default;
21 /**
22 * Some notes for the default value used by expires:
23 * std::chrono::system_clock::time_point::min() won't work on Windows due to the min, max clash there.
24 * So we fall back to std::chrono::system_clock::from_time_t(0) for the minimum value here.
25 **/
26 Cookie(const std::string& name, const std::string& value, const std::string& domain = "", bool p_isIncludingSubdomains = false, const std::string& path = "/", bool p_isHttpsOnly = false, std::chrono::system_clock::time_point expires = std::chrono::system_clock::from_time_t(t: 0)) : name_{name}, value_{value}, domain_{domain}, includeSubdomains_{p_isIncludingSubdomains}, path_{path}, httpsOnly_{p_isHttpsOnly}, expires_{expires} {};
27 const std::string GetDomain() const;
28 bool IsIncludingSubdomains() const;
29 const std::string GetPath() const;
30 bool IsHttpsOnly() const;
31 const std::chrono::system_clock::time_point GetExpires() const;
32 const std::string GetExpiresString() const;
33 const std::string GetName() const;
34 const std::string GetValue() const;
35
36 private:
37 std::string name_;
38 std::string value_;
39 std::string domain_;
40 bool includeSubdomains_{};
41 std::string path_;
42 bool httpsOnly_{};
43 /**
44 * TODO: Update the implementation using `std::chrono::utc_clock` of C++20
45 **/
46 std::chrono::system_clock::time_point expires_{};
47};
48
49class Cookies {
50 public:
51 /**
52 * Should we URL-encode cookies when making a request.
53 * Based on RFC6265, it is recommended but not mandatory to encode cookies.
54 *
55 * -------
56 * To maximize compatibility with user agents, servers that wish to
57 * store arbitrary data in a cookie-value SHOULD encode that data, for
58 * example, using Base64 [RFC4648].
59 * -------
60 * Source: RFC6265 (https://www.ietf.org/rfc/rfc6265.txt)
61 **/
62 bool encode{true};
63
64 // NOLINTNEXTLINE(google-explicit-constructor, hicpp-explicit-conversions)
65 Cookies(bool p_encode = true) : encode{p_encode} {};
66 Cookies(const std::initializer_list<cpr::Cookie>& cookies, bool p_encode = true) : encode{p_encode}, cookies_{cookies} {};
67 // NOLINTNEXTLINE(google-explicit-constructor, hicpp-explicit-conversions)
68 Cookies(const cpr::Cookie& cookie, bool p_encode = true) : encode{p_encode}, cookies_{cookie} {};
69
70 cpr::Cookie& operator[](size_t pos);
71 const std::string GetEncoded(const CurlHolder& holder) const;
72
73 using iterator = std::vector<cpr::Cookie>::iterator;
74 using const_iterator = std::vector<cpr::Cookie>::const_iterator;
75
76 iterator begin();
77 iterator end();
78 const_iterator begin() const;
79 const_iterator end() const;
80 const_iterator cbegin() const;
81 const_iterator cend() const;
82 void emplace_back(const Cookie& str);
83 void push_back(const Cookie& str);
84 void pop_back();
85
86 private:
87 std::vector<cpr::Cookie> cookies_;
88};
89
90} // namespace cpr
91
92#endif
93