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 mNoCache(false),
21 mNoStore(false) {
22 SkipWhites();
23 if (!CheckEOF()) {
24 Directive();
25 }
26 }
27
Directive()28 void CacheControlParser::Directive() {
29 if (CheckWord("no-cache")) {
30 mNoCache = true;
31 IgnoreDirective(); // ignore any optionally added values
32 } else if (CheckWord("no-store")) {
33 mNoStore = true;
34 } else if (CheckWord("max-age")) {
35 mMaxAgeSet = SecondsValue(&mMaxAge);
36 } else if (CheckWord("max-stale")) {
37 mMaxStaleSet = SecondsValue(&mMaxStale, PR_UINT32_MAX);
38 } else if (CheckWord("min-fresh")) {
39 mMinFreshSet = SecondsValue(&mMinFresh);
40 } else {
41 IgnoreDirective();
42 }
43
44 SkipWhites();
45 if (CheckEOF()) {
46 return;
47 }
48 if (CheckChar(',')) {
49 SkipWhites();
50 Directive();
51 return;
52 }
53
54 NS_WARNING("Unexpected input in Cache-control header value");
55 }
56
SecondsValue(uint32_t * seconds,uint32_t defaultVal)57 bool CacheControlParser::SecondsValue(uint32_t *seconds, uint32_t defaultVal) {
58 SkipWhites();
59 if (!CheckChar('=')) {
60 *seconds = defaultVal;
61 return !!defaultVal;
62 }
63
64 SkipWhites();
65 if (!ReadInteger(seconds)) {
66 NS_WARNING("Unexpected value in Cache-control header value");
67 return false;
68 }
69
70 return true;
71 }
72
IgnoreDirective()73 void CacheControlParser::IgnoreDirective() {
74 Token t;
75 while (Next(t)) {
76 if (t.Equals(Token::Char(',')) || t.Equals(Token::EndOfFile())) {
77 Rollback();
78 break;
79 }
80 if (t.Equals(Token::Char('"'))) {
81 SkipUntil(Token::Char('"'));
82 if (!CheckChar('"')) {
83 NS_WARNING(
84 "Missing quoted string expansion in Cache-control header value");
85 break;
86 }
87 }
88 }
89 }
90
MaxAge(uint32_t * seconds)91 bool CacheControlParser::MaxAge(uint32_t *seconds) {
92 *seconds = mMaxAge;
93 return mMaxAgeSet;
94 }
95
MaxStale(uint32_t * seconds)96 bool CacheControlParser::MaxStale(uint32_t *seconds) {
97 *seconds = mMaxStale;
98 return mMaxStaleSet;
99 }
100
MinFresh(uint32_t * seconds)101 bool CacheControlParser::MinFresh(uint32_t *seconds) {
102 *seconds = mMinFresh;
103 return mMinFreshSet;
104 }
105
NoCache()106 bool CacheControlParser::NoCache() { return mNoCache; }
107
NoStore()108 bool CacheControlParser::NoStore() { return mNoStore; }
109
110 } // namespace net
111 } // namespace mozilla
112