Stroika Library 3.0d23
 
Loading...
Searching...
No Matches
CacheControl.cpp
1/*
2 * Copyright(c) Sophist Solutions, Inc. 1990-2026. 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
A generalization of a vector: a container whose elements are keyed by the natural numbers.
static constexpr DiscreteRange FullRange()
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)