Stroika Library 3.0d16
 
Loading...
Searching...
No Matches
CacheControl.cpp
1/*
2 * Copyright(c) Sophist Solutions, Inc. 1990-2025. All rights reserved
3 */
4#include "Stroika/Foundation/StroikaPreComp.h"
5
7#include "Stroika/Foundation/Characters/String2Int.h"
11
12#include "CacheControl.h"
13
14using namespace Stroika::Foundation;
17using namespace Stroika::Foundation::Common;
19using namespace Stroika::Foundation::Traversal;
20
21/*
22 ********************************************************************************
23 *************************** HTTP::CacheControl *********************************
24 ********************************************************************************
25 */
27{
29 auto parseInt = [] (const String& i) -> optional<uint32_t> {
30 // @todo validate/tweak/keep in range
31 auto v = String2Int<int32_t> (i);
32 return v < 0 ? optional<uint32_t>{} : static_cast<uint32_t> (v);
33 };
34 for (const String& v : headerValue.Tokenize ({',', ' '})) {
35 // https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Cache-Control case insensitive
36 Assert (not v.empty ());
37 Sequence<String> vv = v.Tokenize ({'='});
38 Assert (not vv.empty ()); // cuz the first tokenize will never return an empty item
39 String token = vv[0];
41 if (String::EqualsComparer{eCaseInsensitive}(token, DefaultNames<Cacheability>{}.GetName (sr))) {
42 r.fCacheability = sr;
43 goto DoneWithV;
44 }
45 }
46 if (String::EqualsComparer{eCaseInsensitive}(token, "must-revalidate"sv)) {
47 r.fMustRevalidate = true;
48 }
49 else if (String::EqualsComparer{eCaseInsensitive}(token, "no-transform"sv)) {
50 r.fNoTransform = true;
51 }
52 else if (String::EqualsComparer{eCaseInsensitive}(token, "only-if-cached"sv)) {
53 r.fOnlyIfCached = true;
54 }
55 else if (String::EqualsComparer{eCaseInsensitive}(token, "age"sv) && vv.length () >= 2) {
56 r.fAge = parseInt (vv[1]);
57 }
58 else if (String::EqualsComparer{eCaseInsensitive}(token, "max-age"sv) && vv.length () >= 2) {
59 r.fMaxAge = parseInt (vv[1]);
60 }
61 else if (String::EqualsComparer{eCaseInsensitive}(token, "s-max-age"sv) && vv.length () >= 2) {
62 r.fSharedMaxAge = parseInt (vv[1]);
63 }
64 else if (String::EqualsComparer{eCaseInsensitive}(token, "max-stale"sv)) {
65 MaxStale m;
66 if (vv.length () >= 2) {
67 m.fAmount = parseInt (vv[1]);
68 }
69 r.fMaxStale = m;
70 }
71 else if (String::EqualsComparer{eCaseInsensitive}(token, "min-fresh"sv) && vv.length () >= 2) {
72 r.fMinFresh = parseInt (vv[1]);
73 }
74 DoneWithV:;
75 }
76 return r;
77}
78
79template <>
81{
83 auto handleComma = [&] () {
84 if (not sb.empty ()) {
85 sb << ", "sv;
86 }
87 };
88 if (fCacheability) {
89 sb << DefaultNames<Cacheability>{}.GetName (*fCacheability);
90 }
91 if (fMustRevalidate) {
92 handleComma ();
93 sb << "must-revalidate"sv;
94 }
95 if (fImmutable) {
96 handleComma ();
97 sb << "immutable"sv;
98 }
99 if (fNoTransform) {
100 handleComma ();
101 sb << "no-transform"sv;
102 }
103 if (fOnlyIfCached) {
104 handleComma ();
105 sb << "only-if-cached"sv;
106 }
107 if (fAge) {
108 handleComma ();
109 sb << "age={}"_f(*fAge);
110 }
111 if (fMaxAge) {
112 handleComma ();
113 sb << "max-age={}"_f(*fMaxAge);
114 }
115 if (fSharedMaxAge) {
116 handleComma ();
117 sb << "s-max-age={}"_f(*fSharedMaxAge);
118 }
119 if (fMaxStale) {
120 handleComma ();
121 sb << "max-stale"sv;
122 if (fMaxStale->fAmount) {
123 sb << "={}"_f(*fMaxStale->fAmount);
124 }
125 }
126 if (fMinFresh) {
127 handleComma ();
128 sb << "min-fresh={}"_f(*fMinFresh);
129 }
130 return sb;
131}
Similar to String, but intended to more efficiently construct a String. Mutable type (String is large...
String is like std::u32string, except it is much easier to use, often much more space efficient,...
Definition String.h:201
nonvirtual Containers::Sequence< String > Tokenize() const
Definition String.cpp:1234
A generalization of a vector: a container whose elements are keyed by the natural numbers.
Definition Sequence.h:187
static constexpr DiscreteRange FullRange()
nonvirtual size_t length() const
STL-ish alias for size() - really in STL only used in string, I think, but still makes sense as an al...
nonvirtual bool empty() const
Returns true iff size() == 0.
Definition Iterable.inl:306
bool fMustRevalidate
Probably not useful in most cases. Just affects behavior of cached values when expired and disconnect...
static CacheControl Parse(const Characters::String &headerValue)