Changeset 182059 in webkit
- Timestamp:
- Mar 27, 2015, 8:13:02 AM (11 years ago)
- Location:
- trunk
- Files:
-
- 2 added
- 11 edited
-
LayoutTests/ChangeLog (modified) (1 diff)
-
LayoutTests/http/tests/cache/disk-cache/disk-cache-request-headers-expected.txt (added)
-
LayoutTests/http/tests/cache/disk-cache/disk-cache-request-headers.html (added)
-
Source/WebCore/ChangeLog (modified) (1 diff)
-
Source/WebCore/loader/cache/CacheValidation.cpp (modified) (2 diffs)
-
Source/WebCore/loader/cache/CacheValidation.h (modified) (2 diffs)
-
Source/WebCore/platform/network/ResourceRequestBase.h (modified) (1 diff)
-
Source/WebCore/platform/network/ResourceResponseBase.cpp (modified) (12 diffs)
-
Source/WebCore/platform/network/ResourceResponseBase.h (modified) (3 diffs)
-
Source/WebKit2/ChangeLog (modified) (1 diff)
-
Source/WebKit2/NetworkProcess/cache/NetworkCache.cpp (modified) (6 diffs)
-
Source/WebKit2/NetworkProcess/cache/NetworkCache.h (modified) (1 diff)
-
Source/WebKit2/NetworkProcess/cache/NetworkCacheStatisticsCocoa.mm (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
-
trunk/LayoutTests/ChangeLog
r182058 r182059 1 2015-03-26 Antti Koivisto <antti@apple.com> 2 3 Respect cache-control directives in request 4 https://bugs.webkit.org/show_bug.cgi?id=143121 5 6 Reviewed by Chris Dumez. 7 8 * http/tests/cache/disk-cache/disk-cache-request-headers-expected.txt: Added. 9 * http/tests/cache/disk-cache/disk-cache-request-headers.html: Added. 10 1 11 2015-03-27 Michael Saboff <msaboff@apple.com> 2 12 -
trunk/Source/WebCore/ChangeLog
r182056 r182059 1 2015-03-26 Antti Koivisto <antti@apple.com> 2 3 Respect cache-control directives in request 4 https://bugs.webkit.org/show_bug.cgi?id=143121 5 rdar://problem/19714040 6 7 Reviewed by Chris Dumez. 8 9 Test: http/tests/cache/disk-cache/disk-cache-request-headers.html 10 11 * loader/cache/CacheValidation.cpp: 12 (WebCore::isCacheHeaderSeparator): 13 (WebCore::isControlCharacter): 14 (WebCore::trimToNextSeparator): 15 (WebCore::parseCacheHeader): 16 (WebCore::parseCacheControlDirectives): 17 18 Factor Cache-control parsing here so it can be used for both requests and responses. 19 20 * loader/cache/CacheValidation.h: 21 * platform/network/ResourceRequestBase.h: 22 * platform/network/ResourceResponseBase.cpp: 23 (WebCore::ResourceResponseBase::ResourceResponseBase): 24 (WebCore::ResourceResponseBase::parseCacheControlDirectives): 25 (WebCore::ResourceResponseBase::cacheControlContainsNoCache): 26 (WebCore::ResourceResponseBase::cacheControlContainsNoStore): 27 (WebCore::ResourceResponseBase::cacheControlContainsMustRevalidate): 28 (WebCore::ResourceResponseBase::cacheControlMaxAge): 29 (WebCore::isCacheHeaderSeparator): Deleted. 30 (WebCore::isControlCharacter): Deleted. 31 (WebCore::trimToNextSeparator): Deleted. 32 (WebCore::parseCacheHeader): Deleted. 33 * platform/network/ResourceResponseBase.h: 34 1 35 2015-03-27 Víctor Manuel Jáquez Leal <vjaquez@igalia.com> 2 36 -
trunk/Source/WebCore/loader/cache/CacheValidation.cpp
r178012 r182059 27 27 #include "CacheValidation.h" 28 28 29 #include "HTTPHeaderMap.h" 29 30 #include "ResourceResponse.h" 30 31 #include <wtf/CurrentTime.h> … … 150 151 } 151 152 152 } 153 inline bool isCacheHeaderSeparator(UChar c) 154 { 155 // See RFC 2616, Section 2.2 156 switch (c) { 157 case '(': 158 case ')': 159 case '<': 160 case '>': 161 case '@': 162 case ',': 163 case ';': 164 case ':': 165 case '\\': 166 case '"': 167 case '/': 168 case '[': 169 case ']': 170 case '?': 171 case '=': 172 case '{': 173 case '}': 174 case ' ': 175 case '\t': 176 return true; 177 default: 178 return false; 179 } 180 } 181 182 inline bool isControlCharacter(UChar c) 183 { 184 return c < ' ' || c == 127; 185 } 186 187 inline String trimToNextSeparator(const String& str) 188 { 189 return str.substring(0, str.find(isCacheHeaderSeparator)); 190 } 191 192 static Vector<std::pair<String, String>> parseCacheHeader(const String& header) 193 { 194 Vector<std::pair<String, String>> result; 195 196 const String safeHeader = header.removeCharacters(isControlCharacter); 197 unsigned max = safeHeader.length(); 198 unsigned pos = 0; 199 while (pos < max) { 200 size_t nextCommaPosition = safeHeader.find(',', pos); 201 size_t nextEqualSignPosition = safeHeader.find('=', pos); 202 if (nextEqualSignPosition == notFound && nextCommaPosition == notFound) { 203 // Add last directive to map with empty string as value 204 result.append(std::make_pair(trimToNextSeparator(safeHeader.substring(pos, max - pos).stripWhiteSpace()), "")); 205 return result; 206 } 207 if (nextCommaPosition != notFound && (nextCommaPosition < nextEqualSignPosition || nextEqualSignPosition == notFound)) { 208 // Add directive to map with empty string as value 209 result.append(std::make_pair(trimToNextSeparator(safeHeader.substring(pos, nextCommaPosition - pos).stripWhiteSpace()), "")); 210 pos += nextCommaPosition - pos + 1; 211 continue; 212 } 213 // Get directive name, parse right hand side of equal sign, then add to map 214 String directive = trimToNextSeparator(safeHeader.substring(pos, nextEqualSignPosition - pos).stripWhiteSpace()); 215 pos += nextEqualSignPosition - pos + 1; 216 217 String value = safeHeader.substring(pos, max - pos).stripWhiteSpace(); 218 if (value[0] == '"') { 219 // The value is a quoted string 220 size_t nextDoubleQuotePosition = value.find('"', 1); 221 if (nextDoubleQuotePosition == notFound) { 222 // Parse error; just use the rest as the value 223 result.append(std::make_pair(directive, trimToNextSeparator(value.substring(1, value.length() - 1).stripWhiteSpace()))); 224 return result; 225 } 226 // Store the value as a quoted string without quotes 227 result.append(std::make_pair(directive, value.substring(1, nextDoubleQuotePosition - 1).stripWhiteSpace())); 228 pos += (safeHeader.find('"', pos) - pos) + nextDoubleQuotePosition + 1; 229 // Move past next comma, if there is one 230 size_t nextCommaPosition2 = safeHeader.find(',', pos); 231 if (nextCommaPosition2 == notFound) 232 return result; // Parse error if there is anything left with no comma 233 pos += nextCommaPosition2 - pos + 1; 234 continue; 235 } 236 // The value is a token until the next comma 237 size_t nextCommaPosition2 = value.find(','); 238 if (nextCommaPosition2 == notFound) { 239 // The rest is the value; no change to value needed 240 result.append(std::make_pair(directive, trimToNextSeparator(value))); 241 return result; 242 } 243 // The value is delimited by the next comma 244 result.append(std::make_pair(directive, trimToNextSeparator(value.substring(0, nextCommaPosition2).stripWhiteSpace()))); 245 pos += (safeHeader.find(',', pos) - pos) + 1; 246 } 247 return result; 248 } 249 250 CacheControlDirectives parseCacheControlDirectives(const HTTPHeaderMap& headers) 251 { 252 CacheControlDirectives result; 253 254 String cacheControlValue = headers.get(HTTPHeaderName::CacheControl); 255 if (!cacheControlValue.isEmpty()) { 256 auto directives = parseCacheHeader(cacheControlValue); 257 258 size_t directivesSize = directives.size(); 259 for (size_t i = 0; i < directivesSize; ++i) { 260 // RFC2616 14.9.1: A no-cache directive with a value is only meaningful for proxy caches. 261 // It should be ignored by a browser level cache. 262 if (equalIgnoringCase(directives[i].first, "no-cache") && directives[i].second.isEmpty()) 263 result.noCache = true; 264 else if (equalIgnoringCase(directives[i].first, "no-store")) 265 result.noStore = true; 266 else if (equalIgnoringCase(directives[i].first, "must-revalidate")) 267 result.mustRevalidate = true; 268 else if (equalIgnoringCase(directives[i].first, "max-age")) { 269 if (!std::isnan(result.maxAge)) { 270 // First max-age directive wins if there are multiple ones. 271 continue; 272 } 273 bool ok; 274 double maxAge = directives[i].second.toDouble(&ok); 275 if (ok) 276 result.maxAge = maxAge; 277 } 278 } 279 } 280 281 if (!result.noCache) { 282 // Handle Pragma: no-cache 283 // This is deprecated and equivalent to Cache-control: no-cache 284 // Don't bother tokenizing the value, it is not important 285 String pragmaValue = headers.get(HTTPHeaderName::Pragma); 286 287 result.noCache = pragmaValue.contains("no-cache", false); 288 } 289 290 return result; 291 } 292 293 } -
trunk/Source/WebCore/loader/cache/CacheValidation.h
r179861 r182059 29 29 namespace WebCore { 30 30 31 class HTTPHeaderMap; 31 32 class ResourceResponse; 32 33 … … 53 54 WEBCORE_EXPORT bool redirectChainAllowsReuse(RedirectChainCacheStatus, ReuseExpiredRedirectionOrNot); 54 55 56 struct CacheControlDirectives { 57 double maxAge { std::numeric_limits<double>::quiet_NaN() }; 58 bool noCache { false }; 59 bool noStore { false }; 60 bool mustRevalidate { false }; 61 }; 62 WEBCORE_EXPORT CacheControlDirectives parseCacheControlDirectives(const HTTPHeaderMap&); 63 55 64 } 56 65 -
trunk/Source/WebCore/platform/network/ResourceRequestBase.h
r181136 r182059 80 80 WEBCORE_EXPORT void setHTTPMethod(const String& httpMethod); 81 81 82 const HTTPHeaderMap& httpHeaderFields() const;82 WEBCORE_EXPORT const HTTPHeaderMap& httpHeaderFields() const; 83 83 WEBCORE_EXPORT void setHTTPHeaderFields(HTTPHeaderMap); 84 84 -
trunk/Source/WebCore/platform/network/ResourceResponseBase.cpp
r178019 r182059 28 28 #include "ResourceResponseBase.h" 29 29 30 #include "CacheValidation.h" 30 31 #include "HTTPHeaderNames.h" 31 32 #include "HTTPParsers.h" … … 38 39 namespace WebCore { 39 40 40 static void parseCacheHeader(const String& header, Vector<std::pair<String, String>>& result);41 42 41 inline const ResourceResponse& ResourceResponseBase::asResourceResponse() const 43 42 { … … 49 48 , m_includesCertificateInfo(false) 50 49 , m_httpStatusCode(0) 51 , m_cacheControlMaxAge(0)52 50 , m_age(0) 53 51 , m_date(0) … … 60 58 , m_haveParsedExpiresHeader(false) 61 59 , m_haveParsedLastModifiedHeader(false) 62 , m_cacheControlContainsNoCache(false)63 , m_cacheControlContainsNoStore(false)64 , m_cacheControlContainsMustRevalidate(false)65 60 , m_source(Source::Unknown) 66 61 { … … 74 69 , m_includesCertificateInfo(true) // Empty but valid for synthetic responses. 75 70 , m_httpStatusCode(0) 76 , m_cacheControlMaxAge(0)77 71 , m_age(0) 78 72 , m_date(0) … … 85 79 , m_haveParsedExpiresHeader(false) 86 80 , m_haveParsedLastModifiedHeader(false) 87 , m_cacheControlContainsNoCache(false)88 , m_cacheControlContainsNoStore(false)89 , m_cacheControlContainsMustRevalidate(false)90 81 , m_source(Source::Unknown) 91 82 { … … 359 350 lazyInit(CommonFieldsOnly); 360 351 352 m_cacheControlDirectives = WebCore::parseCacheControlDirectives(m_httpHeaderFields); 361 353 m_haveParsedCacheControlHeader = true; 362 363 m_cacheControlContainsMustRevalidate = false;364 m_cacheControlContainsNoCache = false;365 m_cacheControlMaxAge = std::numeric_limits<double>::quiet_NaN();366 367 String cacheControlValue = m_httpHeaderFields.get(HTTPHeaderName::CacheControl);368 if (!cacheControlValue.isEmpty()) {369 Vector<std::pair<String, String>> directives;370 parseCacheHeader(cacheControlValue, directives);371 372 size_t directivesSize = directives.size();373 for (size_t i = 0; i < directivesSize; ++i) {374 // RFC2616 14.9.1: A no-cache directive with a value is only meaningful for proxy caches.375 // It should be ignored by a browser level cache.376 if (equalIgnoringCase(directives[i].first, "no-cache") && directives[i].second.isEmpty())377 m_cacheControlContainsNoCache = true;378 else if (equalIgnoringCase(directives[i].first, "no-store"))379 m_cacheControlContainsNoStore = true;380 else if (equalIgnoringCase(directives[i].first, "must-revalidate"))381 m_cacheControlContainsMustRevalidate = true;382 else if (equalIgnoringCase(directives[i].first, "max-age")) {383 if (!std::isnan(m_cacheControlMaxAge)) {384 // First max-age directive wins if there are multiple ones.385 continue;386 }387 bool ok;388 double maxAge = directives[i].second.toDouble(&ok);389 if (ok)390 m_cacheControlMaxAge = maxAge;391 }392 }393 }394 395 if (!m_cacheControlContainsNoCache) {396 // Handle Pragma: no-cache397 // This is deprecated and equivalent to Cache-control: no-cache398 // Don't bother tokenizing the value, it is not important399 String pragmaValue = m_httpHeaderFields.get(HTTPHeaderName::Pragma);400 401 m_cacheControlContainsNoCache = pragmaValue.contains("no-cache", false);402 }403 354 } 404 355 … … 407 358 if (!m_haveParsedCacheControlHeader) 408 359 parseCacheControlDirectives(); 409 return m_cacheControl ContainsNoCache;360 return m_cacheControlDirectives.noCache; 410 361 } 411 362 … … 414 365 if (!m_haveParsedCacheControlHeader) 415 366 parseCacheControlDirectives(); 416 return m_cacheControl ContainsNoStore;367 return m_cacheControlDirectives.noStore; 417 368 } 418 369 … … 421 372 if (!m_haveParsedCacheControlHeader) 422 373 parseCacheControlDirectives(); 423 return m_cacheControl ContainsMustRevalidate;374 return m_cacheControlDirectives.mustRevalidate; 424 375 } 425 376 … … 435 386 if (!m_haveParsedCacheControlHeader) 436 387 parseCacheControlDirectives(); 437 return m_cacheControl MaxAge;388 return m_cacheControlDirectives.maxAge; 438 389 } 439 390 … … 556 507 } 557 508 558 static bool isCacheHeaderSeparator(UChar c) 559 { 560 // See RFC 2616, Section 2.2 561 switch (c) { 562 case '(': 563 case ')': 564 case '<': 565 case '>': 566 case '@': 567 case ',': 568 case ';': 569 case ':': 570 case '\\': 571 case '"': 572 case '/': 573 case '[': 574 case ']': 575 case '?': 576 case '=': 577 case '{': 578 case '}': 579 case ' ': 580 case '\t': 581 return true; 582 default: 583 return false; 584 } 585 } 586 587 static bool isControlCharacter(UChar c) 588 { 589 return c < ' ' || c == 127; 590 } 591 592 static inline String trimToNextSeparator(const String& str) 593 { 594 return str.substring(0, str.find(isCacheHeaderSeparator)); 595 } 596 597 static void parseCacheHeader(const String& header, Vector<std::pair<String, String>>& result) 598 { 599 const String safeHeader = header.removeCharacters(isControlCharacter); 600 unsigned max = safeHeader.length(); 601 for (unsigned pos = 0; pos < max; /* pos incremented in loop */) { 602 size_t nextCommaPosition = safeHeader.find(',', pos); 603 size_t nextEqualSignPosition = safeHeader.find('=', pos); 604 if (nextEqualSignPosition != notFound && (nextEqualSignPosition < nextCommaPosition || nextCommaPosition == notFound)) { 605 // Get directive name, parse right hand side of equal sign, then add to map 606 String directive = trimToNextSeparator(safeHeader.substring(pos, nextEqualSignPosition - pos).stripWhiteSpace()); 607 pos += nextEqualSignPosition - pos + 1; 608 609 String value = safeHeader.substring(pos, max - pos).stripWhiteSpace(); 610 if (value[0] == '"') { 611 // The value is a quoted string 612 size_t nextDoubleQuotePosition = value.find('"', 1); 613 if (nextDoubleQuotePosition != notFound) { 614 // Store the value as a quoted string without quotes 615 result.append(std::pair<String, String>(directive, value.substring(1, nextDoubleQuotePosition - 1).stripWhiteSpace())); 616 pos += (safeHeader.find('"', pos) - pos) + nextDoubleQuotePosition + 1; 617 // Move past next comma, if there is one 618 size_t nextCommaPosition2 = safeHeader.find(',', pos); 619 if (nextCommaPosition2 != notFound) 620 pos += nextCommaPosition2 - pos + 1; 621 else 622 return; // Parse error if there is anything left with no comma 623 } else { 624 // Parse error; just use the rest as the value 625 result.append(std::pair<String, String>(directive, trimToNextSeparator(value.substring(1, value.length() - 1).stripWhiteSpace()))); 626 return; 627 } 628 } else { 629 // The value is a token until the next comma 630 size_t nextCommaPosition2 = value.find(','); 631 if (nextCommaPosition2 != notFound) { 632 // The value is delimited by the next comma 633 result.append(std::pair<String, String>(directive, trimToNextSeparator(value.substring(0, nextCommaPosition2).stripWhiteSpace()))); 634 pos += (safeHeader.find(',', pos) - pos) + 1; 635 } else { 636 // The rest is the value; no change to value needed 637 result.append(std::pair<String, String>(directive, trimToNextSeparator(value))); 638 return; 639 } 640 } 641 } else if (nextCommaPosition != notFound && (nextCommaPosition < nextEqualSignPosition || nextEqualSignPosition == notFound)) { 642 // Add directive to map with empty string as value 643 result.append(std::pair<String, String>(trimToNextSeparator(safeHeader.substring(pos, nextCommaPosition - pos).stripWhiteSpace()), "")); 644 pos += nextCommaPosition - pos + 1; 645 } else { 646 // Add last directive to map with empty string as value 647 result.append(std::pair<String, String>(trimToNextSeparator(safeHeader.substring(pos, max - pos).stripWhiteSpace()), "")); 648 return; 649 } 650 } 651 } 652 653 } 509 } -
trunk/Source/WebCore/platform/network/ResourceResponseBase.h
r179861 r182059 28 28 #define ResourceResponseBase_h 29 29 30 #include "CacheValidation.h" 30 31 #include "CertificateInfo.h" 31 32 #include "HTTPHeaderMap.h" … … 161 162 162 163 private: 163 mutable double m_cacheControlMaxAge;164 164 mutable double m_age; 165 165 mutable double m_date; 166 166 mutable double m_expires; 167 167 mutable double m_lastModified; 168 mutable CacheControlDirectives m_cacheControlDirectives; 168 169 169 170 public: … … 180 181 mutable bool m_haveParsedExpiresHeader : 1; 181 182 mutable bool m_haveParsedLastModifiedHeader : 1; 182 183 mutable bool m_cacheControlContainsNoCache : 1;184 mutable bool m_cacheControlContainsNoStore : 1;185 mutable bool m_cacheControlContainsMustRevalidate : 1;186 183 187 184 Source m_source; -
trunk/Source/WebKit2/ChangeLog
r182049 r182059 1 2015-03-26 Antti Koivisto <antti@apple.com> 2 3 Respect cache-control directives in request 4 https://bugs.webkit.org/show_bug.cgi?id=143121 5 rdar://problem/19714040 6 7 Reviewed by Chris Dumez. 8 9 Better support for https://tools.ietf.org/html/rfc7234#section-5.2.1 10 11 * NetworkProcess/cache/NetworkCache.cpp: 12 (WebKit::NetworkCache::canUse): 13 14 Consider requests with Cache-control: no-cache and max-age=0 expired. 15 16 (WebKit::NetworkCache::canStore): 17 18 Don't store requests with Cache-control: no-store. 19 20 (WebKit::NetworkCache::Cache::store): 21 * NetworkProcess/cache/NetworkCache.h: 22 * NetworkProcess/cache/NetworkCacheStatisticsCocoa.mm: 23 (WebKit::NetworkCache::storeDecisionToDiagnosticKey): 24 1 25 2015-03-25 Jon Honeycutt <jhoneycutt@apple.com> 2 26 -
trunk/Source/WebKit2/NetworkProcess/cache/NetworkCache.cpp
r182019 r182059 151 151 } 152 152 153 static inlinebool responseHasExpired(const WebCore::ResourceResponse& response, std::chrono::milliseconds timestamp)153 static bool responseHasExpired(const WebCore::ResourceResponse& response, std::chrono::milliseconds timestamp) 154 154 { 155 155 if (response.cacheControlContainsNoCache()) … … 170 170 } 171 171 172 static bool requestNeedsRevalidation(const WebCore::ResourceRequest& request) 173 { 174 auto requestDirectives = WebCore::parseCacheControlDirectives(request.httpHeaderFields()); 175 if (requestDirectives.noCache) 176 return true; 177 // For requests we ignore max-age values other than zero. 178 if (requestDirectives.maxAge == 0) 179 return true; 180 181 return false; 182 } 183 172 184 static UseDecision canUse(const Entry& entry, const WebCore::ResourceRequest& request) 173 185 { … … 177 189 } 178 190 179 // We never revalidate in the case of a history navigation (i.e. cachePolicyAllowsExpired() returns true). 180 bool needsRevalidation = !cachePolicyAllowsExpired(request.cachePolicy()) && responseHasExpired(entry.response(), entry.timeStamp()); 191 // We never revalidate in the case of a history navigation. 192 if (cachePolicyAllowsExpired(request.cachePolicy())) 193 return UseDecision::Use; 194 195 bool needsRevalidation = requestNeedsRevalidation(request) || responseHasExpired(entry.response(), entry.timeStamp()); 181 196 if (!needsRevalidation) 182 197 return UseDecision::Use; … … 267 282 static StoreDecision canStore(const WebCore::ResourceRequest& originalRequest, const WebCore::ResourceResponse& response) 268 283 { 269 if (!originalRequest.url().protocolIsInHTTPFamily() || !response.isHTTP()) { 270 LOG(NetworkCache, "(NetworkProcess) not HTTP"); 284 if (!originalRequest.url().protocolIsInHTTPFamily() || !response.isHTTP()) 271 285 return StoreDecision::NoDueToProtocol; 272 } 273 if (originalRequest.httpMethod() != "GET") { 274 LOG(NetworkCache, "(NetworkProcess) method %s", originalRequest.httpMethod().utf8().data()); 286 287 if (originalRequest.httpMethod() != "GET") 275 288 return StoreDecision::NoDueToHTTPMethod; 276 } 289 290 auto requestDirectives = WebCore::parseCacheControlDirectives(originalRequest.httpHeaderFields()); 291 if (requestDirectives.noStore) 292 return StoreDecision::NoDueToNoStoreRequest; 293 294 if (response.cacheControlContainsNoStore()) 295 return StoreDecision::NoDueToNoStoreResponse; 277 296 278 297 switch (response.httpStatusCode()) { … … 285 304 case 404: // Not Found 286 305 case 410: // Gone 287 if (response.cacheControlContainsNoStore()) {288 LOG(NetworkCache, "(NetworkProcess) Cache-control:no-store");289 return StoreDecision::NoDueToNoStoreResponse;290 }291 306 return StoreDecision::Yes; 292 307 default: … … 306 321 StoreDecision storeDecision = canStore(originalRequest, response); 307 322 if (storeDecision != StoreDecision::Yes) { 308 LOG(NetworkCache, "(NetworkProcess) didn't store ");323 LOG(NetworkCache, "(NetworkProcess) didn't store, storeDecision=%d", storeDecision); 309 324 if (m_statistics) { 310 325 auto key = makeCacheKey(originalRequest); -
trunk/Source/WebKit2/NetworkProcess/cache/NetworkCache.h
r181970 r182059 69 69 NoDueToAttachmentResponse, 70 70 NoDueToNoStoreResponse, 71 NoDueToHTTPStatusCode 71 NoDueToHTTPStatusCode, 72 NoDueToNoStoreRequest 72 73 }; 73 74 -
trunk/Source/WebKit2/NetworkProcess/cache/NetworkCacheStatisticsCocoa.mm
r181970 r182059 237 237 return WebCore::DiagnosticLoggingKeys::isAttachmentKey(); 238 238 case StoreDecision::NoDueToNoStoreResponse: 239 case StoreDecision::NoDueToNoStoreRequest: 239 240 return WebCore::DiagnosticLoggingKeys::cacheControlNoStoreKey(); 240 241 case StoreDecision::NoDueToHTTPStatusCode:
Note:
See TracChangeset
for help on using the changeset viewer.