void ResourceResponseBase::parseCacheControlDirectives() const { ASSERT(!m_haveParsedCacheControlHeader); lazyInit(CommonFieldsOnly); m_haveParsedCacheControlHeader = true; m_cacheControlContainsMustRevalidate = false; m_cacheControlContainsNoCache = false; m_cacheControlMaxAge = std::numeric_limits<double>::quiet_NaN(); DEPRECATED_DEFINE_STATIC_LOCAL(const AtomicString, cacheControlString, ("cache-control", AtomicString::ConstructFromLiteral)); DEPRECATED_DEFINE_STATIC_LOCAL(const AtomicString, noCacheDirective, ("no-cache", AtomicString::ConstructFromLiteral)); DEPRECATED_DEFINE_STATIC_LOCAL(const AtomicString, noStoreDirective, ("no-store", AtomicString::ConstructFromLiteral)); DEPRECATED_DEFINE_STATIC_LOCAL(const AtomicString, mustRevalidateDirective, ("must-revalidate", AtomicString::ConstructFromLiteral)); DEPRECATED_DEFINE_STATIC_LOCAL(const AtomicString, maxAgeDirective, ("max-age", AtomicString::ConstructFromLiteral)); String cacheControlValue = m_httpHeaderFields.get(cacheControlString); if (!cacheControlValue.isEmpty()) { Vector<std::pair<String, String>> directives; parseCacheHeader(cacheControlValue, directives); size_t directivesSize = directives.size(); for (size_t i = 0; i < directivesSize; ++i) { // RFC2616 14.9.1: A no-cache directive with a value is only meaningful for proxy caches. // It should be ignored by a browser level cache. if (equalIgnoringCase(directives[i].first, noCacheDirective) && directives[i].second.isEmpty()) m_cacheControlContainsNoCache = true; else if (equalIgnoringCase(directives[i].first, noStoreDirective)) m_cacheControlContainsNoStore = true; else if (equalIgnoringCase(directives[i].first, mustRevalidateDirective)) m_cacheControlContainsMustRevalidate = true; else if (equalIgnoringCase(directives[i].first, maxAgeDirective)) { if (!std::isnan(m_cacheControlMaxAge)) { // First max-age directive wins if there are multiple ones. continue; } bool ok; double maxAge = directives[i].second.toDouble(&ok); if (ok) m_cacheControlMaxAge = maxAge; } } } if (!m_cacheControlContainsNoCache) { // Handle Pragma: no-cache // This is deprecated and equivalent to Cache-control: no-cache // Don't bother tokenizing the value, it is not important DEPRECATED_DEFINE_STATIC_LOCAL(const AtomicString, pragmaHeader, ("pragma", AtomicString::ConstructFromLiteral)); String pragmaValue = m_httpHeaderFields.get(pragmaHeader); m_cacheControlContainsNoCache = pragmaValue.lower().contains(noCacheDirective); }
const CacheControlDirectiveMap& ResourceResponseBase::parseCacheControlDirectives() const { lazyInit(); if (m_haveParsedCacheControlHeader) return m_cacheControlDirectiveMap; m_cacheControlDirectiveMap.clear(); m_haveParsedCacheControlHeader = true; const String cacheControlHeader = httpHeaderField("Cache-Control"); if (cacheControlHeader.isEmpty()) return m_cacheControlDirectiveMap; Vector<pair<String, String> > directives; parseCacheHeader(cacheControlHeader, directives); unsigned iMax = directives.size(); for (unsigned i = 0; i < iMax; ++i) { Vector<String> directiveValues; if ((equalIgnoringCase(directives[i].first, "private") || equalIgnoringCase(directives[i].first, "no-cache")) && !directives[i].second.isEmpty()) parseCacheControlDirectiveValues(directives[i].second, directiveValues); else directiveValues.append(directives[i].second); if (m_cacheControlDirectiveMap.contains(directives[i].first)) { CacheControlDirectiveMap::iterator entry = m_cacheControlDirectiveMap.find(directives[i].first); unsigned jMax = directiveValues.size(); for (unsigned j = 0; j < jMax; ++j) entry->second.add(directiveValues[j]); } else { HashSet<String> values; unsigned jMax = directiveValues.size(); for (unsigned j = 0; j < jMax; ++j) values.add(directiveValues[j]); m_cacheControlDirectiveMap.set(directives[i].first, values); } } return m_cacheControlDirectiveMap; }
const PragmaDirectiveMap& ResourceResponseBase::parsePragmaDirectives() const { lazyInit(); if (m_haveParsedPragmaHeader) return m_pragmaDirectiveMap; m_pragmaDirectiveMap.clear(); m_haveParsedPragmaHeader = true; const String pragmaHeader = httpHeaderField("Pragma"); if (pragmaHeader.isEmpty()) return m_pragmaDirectiveMap; Vector<pair<String, String> > directives; parseCacheHeader(pragmaHeader, directives); unsigned max = directives.size(); for (unsigned i = 0; i < max; ++i) m_pragmaDirectiveMap.set(directives[i].first, directives[i].second); return m_pragmaDirectiveMap; }