4#include "Stroika/Foundation/StroikaPreComp.h"
6#include "Stroika/Foundation/Characters/String2Int.h"
8#include "Stroika/Foundation/Containers/Set.h"
16using namespace Stroika::Foundation::IO;
19using namespace Stroika::Foundation::Streams;
31 for (
const auto& i : attributes) {
32 AddAttribute (i.fKey, i.fValue);
40 result.
Add (kExpiresAttributeLabel, fExpires->Format (Time::DateTime::kISO8601Format));
43 result.
Add (kMaxAgeAttributeLabel,
"{}"_f(*fMaxAge));
46 result.
Add (kDomainAttributeLabel, *fDomain);
49 result.
Add (kPathAttributeLabel, *fPath);
52 result.
Add (kSecureAttributeLabel,
String{});
55 result.
Add (kHttpOnlyAttributeLabel,
String{});
57 if (fOtherAttributes) {
58 result += *fOtherAttributes;
63void Cookie::AddAttribute (
const String& aEqualsBAttributePair)
65 if (
auto i = aEqualsBAttributePair.
Find (
'=')) {
66 AddAttribute (aEqualsBAttributePair.
SubString (0, *i), aEqualsBAttributePair.
SubString (0, *i + 1));
69 AddAttribute (aEqualsBAttributePair);
73void Cookie::AddAttribute (
const String& key,
const String& value)
77 if (key == kPathAttributeLabel) {
80 else if (key == kDomainAttributeLabel) {
83 else if (key == kExpiresAttributeLabel) {
84 fExpires = DateTime::Parse (value, DateTime::kRFC1123Format);
86 else if (key == kMaxAgeAttributeLabel) {
87 fMaxAge = String2Int<int> (value);
89 else if (key == kSecureAttributeLabel) {
92 else if (key == kHttpOnlyAttributeLabel) {
96 if (fOtherAttributes) {
97 fOtherAttributes->Add (key, value);
106String Cookie::As<String> ()
const
110 sb << fKey <<
"="sv << fValue;
112 sb <<
"; "sv << kvp.fKey;
113 static const Set<String> kNoValueAttributes_{kSecureAttributeLabel, kHttpOnlyAttributeLabel};
114 if (not kNoValueAttributes_.Contains (kvp.fKey)) {
115 sb <<
"="sv << kvp.fValue;
124 auto skipWS = [&] () {
126 if (not c->IsWhitespace ()) {
127 src.
Seek (eFromCurrent, -1);
136 if (*c == targetChar) {
149 if (*c == targetChar or *c == targetChar2) {
158 auto prevChar = [&] () {
159 src.
Seek (eFromCurrent, -1);
161 Assert (c.has_value ());
166 skipUpTo (
'=', &key);
168 skipUpTo (
';', &value);
174 skipUpTo2 (
'=',
';', &k2);
175 if (prevChar () ==
'=') {
176 skipUpTo (
';', &val2);
178 if (not key.empty ()) {
179 attributes.
Add (k2, val2);
182 return Cookie{key, value, attributes};
196 : cookies{[qStroika_Foundation_Common_Property_ExtraCaptureStuff] ([[maybe_unused]] const auto* property) ->
Mapping<
String,
String> {
200 [qStroika_Foundation_Common_Property_ExtraCaptureStuff] ([[maybe_unused]]
auto* property,
const Mapping<String, String>& basicCookies) {
202 thisObj->fCookieDetails_ = basicCookies.Map<
Iterable<Cookie>> ([] (
const auto& i) {
return Cookie{i.fKey, i.fValue}; });
204 , cookieDetails{[qStroika_Foundation_Common_Property_ExtraCaptureStuff] ([[maybe_unused]]
const auto* property) ->
Collection<Cookie> {
206 return thisObj->fCookieDetails_;
208 [qStroika_Foundation_Common_Property_ExtraCaptureStuff] ([[maybe_unused]]
auto* property,
const Collection<Cookie>& cookies) {
210 thisObj->fCookieDetails_ = cookies;
223 for (
const auto& keyValuePair : cookieValueArg.
Tokenize ({
';'})) {
Similar to String, but intended to more efficiently construct a String. Mutable type (String is large...
nonvirtual void Append(span< const CHAR_T > s)
nonvirtual String str() const
String is like std::u32string, except it is much easier to use, often much more space efficient,...
static String Join(const Iterable< String > &list, const String &separator=", "sv)
nonvirtual String SubString(SZ from) const
nonvirtual Containers::Sequence< String > Tokenize() const
nonvirtual optional< size_t > Find(Character c, CompareOptions co=eWithCase) const
A Collection<T> is a container to manage an un-ordered collection of items, without equality defined ...
nonvirtual bool Add(ArgByValueType< key_type > key, ArgByValueType< mapped_type > newElt, AddReplaceMode addReplaceMode=AddReplaceMode::eAddReplaces)
Set<T> is a container of T, where once an item is added, additionally adds () do nothing.
nonvirtual String EncodeForCookieHeader() const
render as a string suitable for a cookie header
static CookieList Parse(const String &cookieValueArg)
Common::Property< Collection< Cookie > > cookieDetails
Common::Property< Mapping< String, String > > cookies
nonvirtual bool IsSeekable() const
Returns true iff this object was constructed with a seekable input stream rep.
Iterable<T> is a base class for containers which easily produce an Iterator<T> to traverse them.
Ptr New(const InputStream::Ptr< byte > &src, optional< AutomaticCodeCvtFlags > codeCvtFlags={}, optional< SeekableFlag > seekable={}, ReadAhead readAhead=eReadAheadAllowed)
Create an InputStream::Ptr<Character> from the arguments (usually binary source) - which can be used ...
object representing an HTTP cookie - from https://tools.ietf.org/html/rfc6265
static Cookie Parse(Streams::InputStream::Ptr< Character > src)
nonvirtual Mapping< String, String > GetAttributes() const