/src/pdns/ext/yahttp/yahttp/cookie.hpp
Line | Count | Source (jump to first uncovered line) |
1 | | namespace YaHTTP { |
2 | | /*! Implements a single cookie */ |
3 | | class Cookie { |
4 | | public: |
5 | 6.84k | Cookie() { |
6 | 6.84k | secure = false; |
7 | 6.84k | httponly = false; |
8 | 6.84k | name = value = ""; |
9 | 6.84k | expires = DateTime(); |
10 | 6.84k | }; //!< Set the cookie to empty value |
11 | | |
12 | 798k | Cookie(const Cookie &rhs) { |
13 | 798k | name = rhs.name; |
14 | 798k | value = rhs.value; |
15 | 798k | domain = rhs.domain; |
16 | 798k | path = rhs.path; |
17 | 798k | secure = rhs.secure; |
18 | 798k | httponly = rhs.httponly; |
19 | 798k | expires = rhs.expires; |
20 | 798k | }; //<! Copy cookie values |
21 | | |
22 | 263k | Cookie& operator=(const Cookie &rhs) { |
23 | 263k | name = rhs.name; |
24 | 263k | value = rhs.value; |
25 | 263k | domain = rhs.domain; |
26 | 263k | path = rhs.path; |
27 | 263k | secure = rhs.secure; |
28 | 263k | httponly = rhs.httponly; |
29 | 263k | expires = rhs.expires; |
30 | 263k | return *this; |
31 | 263k | } |
32 | | |
33 | | DateTime expires; /*!< Expiration date */ |
34 | | std::string domain; /*!< Domain where cookie is valid */ |
35 | | std::string path; /*!< Path where the cookie is valid */ |
36 | | bool httponly; /*!< Whether the cookie is for server use only */ |
37 | | bool secure; /*!< Whether the cookie is for HTTPS only */ |
38 | | |
39 | | std::string name; /*!< Cookie name */ |
40 | | std::string value; /*!< Cookie value */ |
41 | | |
42 | 0 | std::string str() const { |
43 | 0 | std::ostringstream oss; |
44 | 0 | oss << YaHTTP::Utility::encodeURL(name) << "=" << YaHTTP::Utility::encodeURL(value); |
45 | |
|
46 | 0 | if (expires.isSet) |
47 | 0 | oss << "; expires=" << expires.cookie_str(); |
48 | 0 | if (domain.size()>0) |
49 | 0 | oss << "; domain=" << domain; |
50 | 0 | if (path.size()>0) |
51 | 0 | oss << "; path=" << path; |
52 | 0 | if (secure) |
53 | 0 | oss << "; secure"; |
54 | 0 | if (httponly) |
55 | 0 | oss << "; httpOnly"; |
56 | 0 | return oss.str(); |
57 | 0 | }; //!< Stringify the cookie |
58 | | }; |
59 | | |
60 | | /*! Implements a Cookie jar for storing multiple cookies */ |
61 | | class CookieJar { |
62 | | public: |
63 | | std::map<std::string, Cookie, ASCIICINullSafeComparator> cookies; //<! cookie container |
64 | | |
65 | 4.15k | CookieJar() {}; //<! constructs empty cookie jar |
66 | 0 | CookieJar(const CookieJar & rhs) { |
67 | 0 | this->cookies = rhs.cookies; |
68 | 0 | } //<! copy cookies from another cookie jar |
69 | 0 | CookieJar& operator=(const CookieJar & rhs) = default; |
70 | | |
71 | 12.4k | void clear() { |
72 | 12.4k | this->cookies.clear(); |
73 | 12.4k | } |
74 | | |
75 | 798k | void keyValuePair(const std::string &keyvalue, std::string &key, std::string &value) { |
76 | 798k | size_t pos; |
77 | 798k | pos = keyvalue.find("="); |
78 | 798k | if (pos == std::string::npos) throw ParseError("Not a Key-Value pair (cookie)"); |
79 | 798k | key = std::string(keyvalue.begin(), keyvalue.begin()+pos); |
80 | 798k | value = std::string(keyvalue.begin()+pos+1, keyvalue.end()); |
81 | 798k | } //<! key value pair parser |
82 | | |
83 | 2.08k | void parseCookieHeader(const std::string &cookiestr) { |
84 | 2.08k | size_t pos, npos; |
85 | 2.08k | std::list<Cookie> lcookies; |
86 | 2.08k | Cookie c; |
87 | 2.08k | pos = 0; |
88 | 800k | while(pos < cookiestr.size()) { |
89 | 798k | if ((npos = cookiestr.find("; ", pos)) == std::string::npos) |
90 | 1.85k | npos = cookiestr.size(); |
91 | 798k | keyValuePair(cookiestr.substr(pos, npos-pos), c.name, c.value); |
92 | 798k | c.name = YaHTTP::Utility::decodeURL(c.name); |
93 | 798k | c.value = YaHTTP::Utility::decodeURL(c.value); |
94 | 798k | lcookies.push_back(c); |
95 | 798k | pos = npos+2; |
96 | 798k | } |
97 | 265k | for(std::list<Cookie>::iterator i = lcookies.begin(); i != lcookies.end(); i++) { |
98 | 263k | this->cookies[i->name] = *i; |
99 | 263k | } |
100 | 2.08k | } |
101 | | |
102 | 0 | void parseSetCookieHeader(const std::string &cookiestr) { |
103 | 0 | Cookie c; |
104 | 0 | size_t pos,npos; |
105 | 0 | std::string k, v; |
106 | |
|
107 | 0 | if ((pos = cookiestr.find("; ", 0)) == std::string::npos) |
108 | 0 | pos = cookiestr.size(); |
109 | 0 | keyValuePair(cookiestr.substr(0, pos), c.name, c.value); |
110 | 0 | c.name = YaHTTP::Utility::decodeURL(c.name); |
111 | 0 | c.value = YaHTTP::Utility::decodeURL(c.value); |
112 | 0 | if (pos < cookiestr.size()) pos+=2; |
113 | |
|
114 | 0 | while(pos < cookiestr.size()) { |
115 | 0 | if ((npos = cookiestr.find("; ", pos)) == std::string::npos) |
116 | 0 | npos = cookiestr.size(); |
117 | 0 | std::string s = cookiestr.substr(pos, npos-pos); |
118 | 0 | if (s.find("=") != std::string::npos) |
119 | 0 | keyValuePair(s, k, v); |
120 | 0 | else |
121 | 0 | k = std::move(s); |
122 | 0 | if (k == "expires") { |
123 | 0 | DateTime dt; |
124 | 0 | dt.parseCookie(v); |
125 | 0 | c.expires = dt; |
126 | 0 | } else if (k == "domain") { |
127 | 0 | c.domain = v; |
128 | 0 | } else if (k == "path") { |
129 | 0 | c.path = v; |
130 | 0 | } else if (k == "httpOnly") { |
131 | 0 | c.httponly = true; |
132 | 0 | } else if (k == "secure") { |
133 | 0 | c.secure = true; |
134 | 0 | } else { |
135 | | // ignore crap |
136 | 0 | break; |
137 | 0 | } |
138 | 0 | pos = npos+2; |
139 | 0 | } |
140 | | |
141 | 0 | this->cookies[c.name] = c; |
142 | 0 | }; //<! Parse multiple cookies from header |
143 | | }; |
144 | | }; |