1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* vim: set sw=2 ts=8 et tw=80 : */
3 /* This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this
5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6
7 #include "CacheControlParser.h"
8
9 namespace mozilla {
10 namespace net {
11
CacheControlParser(nsACString const & aHeader)12 CacheControlParser::CacheControlParser(nsACString const& aHeader)
13 : Tokenizer(aHeader, nullptr, "-_"),
14 mMaxAgeSet(false),
15 mMaxAge(0),
16 mMaxStaleSet(false),
17 mMaxStale(0),
18 mMinFreshSet(false),
19 mMinFresh(0),
20 mStaleWhileRevalidateSet(false),
21 mStaleWhileRevalidate(0),
22 mNoCache(false),
23 mNoStore(false),
24 mPublic(false),
25 mPrivate(false),
26 mImmutable(false) {
27 SkipWhites();
28 if (!CheckEOF()) {
29 Directive();
30 }
31 }
32
Directive()33 void CacheControlParser::Directive() {
34 if (CheckWord("no-cache")) {
35 mNoCache = true;
36 IgnoreDirective(); // ignore any optionally added values
37 } else if (CheckWord("no-store")) {
38 mNoStore = true;
39 } else if (CheckWord("max-age")) {
40 mMaxAgeSet = SecondsValue(&mMaxAge);
41 } else if (CheckWord("max-stale")) {
42 mMaxStaleSet = SecondsValue(&mMaxStale, PR_UINT32_MAX);
43 } else if (CheckWord("min-fresh")) {
44 mMinFreshSet = SecondsValue(&mMinFresh);
45 } else if (CheckWord("stale-while-revalidate")) {
46 mStaleWhileRevalidateSet = SecondsValue(&mStaleWhileRevalidate);
47 } else if (CheckWord("public")) {
48 mPublic = true;
49 } else if (CheckWord("private")) {
50 mPrivate = true;
51 } else if (CheckWord("immutable")) {
52 mImmutable = true;
53 } else {
54 IgnoreDirective();
55 }
56
57 SkipWhites();
58 if (CheckEOF()) {
59 return;
60 }
61 if (CheckChar(',')) {
62 SkipWhites();
63 Directive();
64 return;
65 }
66
67 NS_WARNING("Unexpected input in Cache-control header value");
68 }
69
SecondsValue(uint32_t * seconds,uint32_t defaultVal)70 bool CacheControlParser::SecondsValue(uint32_t* seconds, uint32_t defaultVal) {
71 SkipWhites();
72 if (!CheckChar('=')) {
73 *seconds = defaultVal;
74 return !!defaultVal;
75 }
76
77 SkipWhites();
78 if (!ReadInteger(seconds)) {
79 NS_WARNING("Unexpected value in Cache-control header value");
80 return false;
81 }
82
83 return true;
84 }
85
IgnoreDirective()86 void CacheControlParser::IgnoreDirective() {
87 Token t;
88 while (Next(t)) {
89 if (t.Equals(Token::Char(',')) || t.Equals(Token::EndOfFile())) {
90 Rollback();
91 break;
92 }
93 if (t.Equals(Token::Char('"'))) {
94 SkipUntil(Token::Char('"'));
95 if (!CheckChar('"')) {
96 NS_WARNING(
97 "Missing quoted string expansion in Cache-control header value");
98 break;
99 }
100 }
101 }
102 }
103
MaxAge(uint32_t * seconds)104 bool CacheControlParser::MaxAge(uint32_t* seconds) {
105 *seconds = mMaxAge;
106 return mMaxAgeSet;
107 }
108
MaxStale(uint32_t * seconds)109 bool CacheControlParser::MaxStale(uint32_t* seconds) {
110 *seconds = mMaxStale;
111 return mMaxStaleSet;
112 }
113
MinFresh(uint32_t * seconds)114 bool CacheControlParser::MinFresh(uint32_t* seconds) {
115 *seconds = mMinFresh;
116 return mMinFreshSet;
117 }
118
StaleWhileRevalidate(uint32_t * seconds)119 bool CacheControlParser::StaleWhileRevalidate(uint32_t* seconds) {
120 *seconds = mStaleWhileRevalidate;
121 return mStaleWhileRevalidateSet;
122 }
123
NoCache()124 bool CacheControlParser::NoCache() { return mNoCache; }
125
NoStore()126 bool CacheControlParser::NoStore() { return mNoStore; }
127
Public()128 bool CacheControlParser::Public() { return mPublic; }
129
Private()130 bool CacheControlParser::Private() { return mPrivate; }
131
Immutable()132 bool CacheControlParser::Immutable() { return mImmutable; }
133
134 } // namespace net
135 } // namespace mozilla
136