Audacity 3.2.0
CookiesList.cpp
Go to the documentation of this file.
1/*!********************************************************************
2
3 Audacity: A Digital Audio Editor
4
5 @file CookiesList.cpp
6 @brief Define HTTP cookies list class.
7
8 Dmitry Vedenko
9 **********************************************************************/
10
11/*!********************************************************************
12
13 @class Cookie
14 @brief A struct, representing a Cookie object.
15
16 **********************************************************************/
17
18/*!********************************************************************
19
20 @class CookiesList
21 @brief A class, representing a list of HTTP cookies.
22
23 **********************************************************************/
24
25#include "CookiesList.h"
26
27#include <sstream>
28#include <cstring>
29#include <algorithm>
30
31#include "DateTimeConversions.h"
32
33namespace audacity
34{
35namespace network_manager
36{
37
38Cookie Cookie::Parse (const std::string& cookieString)
39{
40 const size_t equalsPosition = cookieString.find ('=');
41
42 if (equalsPosition == std::string::npos)
43 return { cookieString, std::string () };
44
45 std::string name = cookieString.substr (0, equalsPosition);
46
47 const size_t firstValueIndex = equalsPosition + 1;
48
49 const size_t semicolonPosition = cookieString.find (';', firstValueIndex);
50
51 Cookie cookie;
52
53 cookie.Name = std::move (name);
54 cookie.Value = semicolonPosition == std::string::npos ?
55 cookieString.substr (firstValueIndex) :
56 cookieString.substr (firstValueIndex, semicolonPosition - firstValueIndex);
57
58 size_t expiresPosition = cookieString.find("Expires=");
59
60 if (expiresPosition != std::string::npos)
61 {
62 expiresPosition += std::strlen ("Expires=");
63
64 const size_t trailingSemicolon = cookieString.find (';', expiresPosition);
65
66 std::string expiresValue =
67 trailingSemicolon == std::string::npos ?
68 cookieString.substr (expiresPosition) :
69 cookieString.substr (expiresPosition, trailingSemicolon - expiresPosition);
70
71 // Hack around Yandex violating RFC
72 std::replace (expiresValue.begin(), expiresValue.end(), '-', ' ');
73 ParseRFC822Date (expiresValue, &cookie.Expires);
74 }
75
76 return cookie;
77}
78
79bool Cookie::isSession () const noexcept
80{
81 return Expires == ExpiresTime {};
82}
83
84std::string Cookie::toString (bool fullString) const
85{
86 std::ostringstream stream;
87
88 stream << Name << "=" << Value;
89
90 if (fullString)
91 {
92 if (!isSession())
93 stream << "; " << "Expires=" << SerializeRFC822Date(Expires);
94 }
95
96 return stream.str ();
97}
98
99bool Cookie::isExpired () const noexcept
100{
101 return !isSession() &&
102 std::chrono::system_clock::now() >= Expires;
103}
104
105void CookiesList::setCookie (const Cookie& cookie)
106{
107 setCookie (cookie.Name, cookie.Value);
108}
109
110void CookiesList::setCookie (const std::string& cookieName, std::string cookieValue)
111{
112 Cookie* item = getCookie (cookieName);
113
114 if (item != nullptr)
115 item->Value = std::move (cookieValue);
116 else
117 mCookies.push_back ({ cookieName, std::move (cookieValue) });
118}
119
121{
122 addCookie (std::move (cookie.Name), std::move (cookie.Value));
123}
124
125void CookiesList::addCookie (std::string cookieName, std::string cookieValue)
126{
127 mCookies.push_back ({ std::move (cookieName), std::move (cookieValue) });
128}
129
130bool CookiesList::hasCookie (const std::string& cookieName) const noexcept
131{
132 return getCookie (cookieName) != nullptr;
133}
134
135std::string CookiesList::getCookieValue (const std::string& cookieName) const
136{
137 const Cookie* item = getCookie (cookieName);
138
139 if (item != nullptr)
140 return item->Value;
141
142 return {};
143}
144
145const Cookie* CookiesList::getCookie (size_t idx) const noexcept
146{
147 return const_cast<CookiesList*>(this)->getCookie(idx);
148}
149
150const Cookie* CookiesList::getCookie (const std::string& name) const noexcept
151{
152 return const_cast<CookiesList*>(this)->getCookie (name);
153}
154
155size_t CookiesList::getCookiesCount () const noexcept
156{
157 return mCookies.size ();
158}
159
161{
162 std::string result;
163
164 for (const Cookie& cookie : mCookies)
165 {
166 if (!result.empty ())
167 result.push_back (';');
168
169 result += cookie.Name + "=" + cookie.Value;
170 }
171
172 return result;
173}
174
176{
177 return mCookies.begin ();
178}
179
181{
182 return mCookies.end ();
183}
184
186{
187 return mCookies.begin ();
188}
189
191{
192 return mCookies.end ();
193}
194
195Cookie* CookiesList::getCookie (size_t idx) noexcept
196{
197 if (idx < mCookies.size ())
198 return &mCookies[idx];
199
200 return nullptr;
201}
202
203Cookie* CookiesList::getCookie (const std::string& cookieName) noexcept
204{
205 for (Cookie& cookie : mCookies)
206 {
207 if (cookie.Name == cookieName)
208 return &cookie;
209 }
210
211 return nullptr;
212}
213
214}
215}
Define HTTP cookies list class.
Declare functions to work with date and time string representations.
const TranslatableString name
Definition: Distortion.cpp:76
void setCookie(const Cookie &cookie)
std::string getCookieValue(const std::string &cookieName) const
CookiesStorageType::const_iterator CookiesConstIterator
Definition: CookiesList.h:46
bool hasCookie(const std::string &cookieName) const noexcept
CookiesStorageType::iterator CookiesIterator
Definition: CookiesList.h:45
CookiesIterator begin() noexcept
CookiesIterator end() noexcept
size_t getCookiesCount() const noexcept
const Cookie * getCookie(size_t idx) const noexcept
constexpr size_t npos(-1)
std::chrono::system_clock::time_point ExpiresTime
Definition: CookiesList.h:24
bool ParseRFC822Date(const std::string &dateString, SystemTime *time)
std::string SerializeRFC822Date(SystemTime timePoint)