Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 /* | 1 /* |
| 2 * Copyright (C) 2013 Google Inc. All rights reserved. | 2 * Copyright (C) 2013 Google Inc. All rights reserved. |
| 3 * | 3 * |
| 4 * Redistribution and use in source and binary forms, with or without | 4 * Redistribution and use in source and binary forms, with or without |
| 5 * modification, are permitted provided that the following conditions are | 5 * modification, are permitted provided that the following conditions are |
| 6 * met: | 6 * met: |
| 7 * | 7 * |
| 8 * * Redistributions of source code must retain the above copyright | 8 * * Redistributions of source code must retain the above copyright |
| 9 * notice, this list of conditions and the following disclaimer. | 9 * notice, this list of conditions and the following disclaimer. |
| 10 * * Redistributions in binary form must reproduce the above | 10 * * Redistributions in binary form must reproduce the above |
| (...skipping 197 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 208 return document.settings() | 208 return document.settings() |
| 209 ->getDisallowFetchForDocWrittenScriptsInMainFrame() || | 209 ->getDisallowFetchForDocWrittenScriptsInMainFrame() || |
| 210 (document.settings() | 210 (document.settings() |
| 211 ->getDisallowFetchForDocWrittenScriptsInMainFrameOnSlowConnections () && | 211 ->getDisallowFetchForDocWrittenScriptsInMainFrameOnSlowConnections () && |
| 212 is2G) || | 212 is2G) || |
| 213 (document.settings() | 213 (document.settings() |
| 214 ->getDisallowFetchForDocWrittenScriptsInMainFrameIfEffectively2G() && | 214 ->getDisallowFetchForDocWrittenScriptsInMainFrameIfEffectively2G() && |
| 215 isConnectionEffectively2G(effectiveConnection)); | 215 isConnectionEffectively2G(effectiveConnection)); |
| 216 } | 216 } |
| 217 | 217 |
| 218 enum class RequestMethod { kIsPost, kIsNotPost }; | |
| 219 enum class RequestType { kIsConditional, kIsNotConditional }; | |
| 220 enum class ResourceType { kIsMainResource, kIsNotMainResource }; | |
| 221 | |
| 222 WebCachePolicy determineWebCachePolicy(RequestMethod method, | |
| 223 RequestType requestType, | |
| 224 ResourceType resourceType, | |
| 225 FrameLoadType loadType) { | |
| 226 switch (loadType) { | |
| 227 case FrameLoadTypeStandard: | |
| 228 case FrameLoadTypeReplaceCurrentItem: | |
| 229 case FrameLoadTypeInitialInChildFrame: | |
| 230 return (requestType == RequestType::kIsConditional || | |
| 231 method == RequestMethod::kIsPost) | |
| 232 ? WebCachePolicy::ValidatingCacheData | |
| 233 : WebCachePolicy::UseProtocolCachePolicy; | |
| 234 case FrameLoadTypeInitialHistoryLoad: | |
|
yhirano
2017/03/14 08:34:35
Where is this clause from?
Takashi Toyoshima
2017/03/15 03:13:51
This wasn't handled in the original, and used UseP
yhirano
2017/03/15 05:26:20
Yeah, splitting the CL helps me understand the cha
Takashi Toyoshima
2017/03/15 08:27:22
Done.
| |
| 235 case FrameLoadTypeBackForward: | |
| 236 // Mutates the policy for POST requests to avoid form resubmission. | |
| 237 return method == RequestMethod::kIsPost | |
| 238 ? WebCachePolicy::ReturnCacheDataDontLoad | |
| 239 : WebCachePolicy::ReturnCacheDataElseLoad; | |
| 240 case FrameLoadTypeReload: | |
| 241 return WebCachePolicy::ValidatingCacheData; | |
| 242 case FrameLoadTypeReloadMainResource: | |
| 243 return resourceType == ResourceType::kIsMainResource | |
| 244 ? WebCachePolicy::ValidatingCacheData | |
| 245 : WebCachePolicy::UseProtocolCachePolicy; | |
| 246 case FrameLoadTypeReloadBypassingCache: | |
| 247 return WebCachePolicy::BypassingCache; | |
| 248 } | |
| 249 NOTREACHED(); | |
| 250 return WebCachePolicy::UseProtocolCachePolicy; | |
| 251 } | |
| 252 | |
| 253 // TODO(toyoshim): Remove |type|. See comments in resourceRequestCachePolicy(). | |
|
yhirano
2017/03/14 08:34:35
|resourceType|?
Takashi Toyoshima
2017/03/15 03:13:51
Done.
| |
| 254 WebCachePolicy determineFrameWebCachePolicy(Frame* frame, | |
| 255 ResourceType resourceType) { | |
| 256 if (!frame) | |
| 257 return WebCachePolicy::UseProtocolCachePolicy; | |
| 258 if (!frame->isLocalFrame()) | |
| 259 return determineFrameWebCachePolicy(frame->tree().parent(), resourceType); | |
| 260 | |
| 261 // Does not propagate cache policy for subresources after the load event. | |
| 262 // TODO(toyoshim): We should be able to remove following parents' policy check | |
| 263 // if each frame has a relevant FrameLoadType for reload and history | |
| 264 // navigations. | |
| 265 if (resourceType == ResourceType::kIsNotMainResource && | |
| 266 toLocalFrame(frame)->document()->loadEventFinished()) { | |
| 267 return WebCachePolicy::UseProtocolCachePolicy; | |
| 268 } | |
| 269 | |
| 270 // Respects BypassingCache rather than parent's policy. | |
| 271 // TODO(toyoshim): Adopt BypassingCache even for MainResource. | |
| 272 FrameLoadType loadType = | |
| 273 toLocalFrame(frame)->loader().documentLoader()->loadType(); | |
| 274 if (resourceType == ResourceType::kIsNotMainResource && | |
| 275 loadType == FrameLoadTypeReloadBypassingCache) { | |
| 276 return WebCachePolicy::BypassingCache; | |
| 277 } | |
| 278 | |
| 279 // Respects parent's policy if it has a special one. | |
| 280 WebCachePolicy parentPolicy = | |
| 281 determineFrameWebCachePolicy(frame->tree().parent(), resourceType); | |
| 282 if (parentPolicy != WebCachePolicy::UseProtocolCachePolicy) | |
| 283 return parentPolicy; | |
| 284 | |
| 285 // Otherwise, follows FrameLoadType. Use kIsNotPost, kIsNotConditional, and | |
| 286 // kIsNotMainResource to obtain a representative policy for the frame. | |
| 287 return determineWebCachePolicy(RequestMethod::kIsNotPost, | |
| 288 RequestType::kIsNotConditional, | |
| 289 ResourceType::kIsNotMainResource, loadType); | |
| 290 } | |
| 291 | |
| 218 } // namespace | 292 } // namespace |
| 219 | 293 |
| 220 FrameFetchContext::FrameFetchContext(DocumentLoader* loader, Document* document) | 294 FrameFetchContext::FrameFetchContext(DocumentLoader* loader, Document* document) |
| 221 : m_document(document), m_documentLoader(loader) { | 295 : m_document(document), m_documentLoader(loader) { |
| 222 DCHECK(frame()); | 296 DCHECK(frame()); |
| 223 } | 297 } |
| 224 | 298 |
| 225 FrameFetchContext::~FrameFetchContext() { | 299 FrameFetchContext::~FrameFetchContext() { |
| 226 m_document = nullptr; | 300 m_document = nullptr; |
| 227 m_documentLoader = nullptr; | 301 m_documentLoader = nullptr; |
| (...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 278 if (!request.url().isEmpty() && !request.url().protocolIsInHTTPFamily()) | 352 if (!request.url().isEmpty() && !request.url().protocolIsInHTTPFamily()) |
| 279 return; | 353 return; |
| 280 | 354 |
| 281 if (masterDocumentLoader()->loadType() == FrameLoadTypeReload) | 355 if (masterDocumentLoader()->loadType() == FrameLoadTypeReload) |
| 282 request.clearHTTPHeaderField("Save-Data"); | 356 request.clearHTTPHeaderField("Save-Data"); |
| 283 | 357 |
| 284 if (frame()->settings() && frame()->settings()->getDataSaverEnabled()) | 358 if (frame()->settings() && frame()->settings()->getDataSaverEnabled()) |
| 285 request.setHTTPHeaderField("Save-Data", "on"); | 359 request.setHTTPHeaderField("Save-Data", "on"); |
| 286 } | 360 } |
| 287 | 361 |
| 288 CachePolicy FrameFetchContext::getCachePolicy() const { | |
| 289 if (m_document && m_document->loadEventFinished()) | |
| 290 return CachePolicyVerify; | |
| 291 | |
| 292 FrameLoadType loadType = masterDocumentLoader()->loadType(); | |
| 293 if (loadType == FrameLoadTypeReloadBypassingCache) | |
| 294 return CachePolicyReload; | |
| 295 | |
| 296 Frame* parentFrame = frame()->tree().parent(); | |
| 297 if (parentFrame && parentFrame->isLocalFrame()) { | |
| 298 CachePolicy parentCachePolicy = toLocalFrame(parentFrame) | |
| 299 ->document() | |
| 300 ->fetcher() | |
| 301 ->context() | |
| 302 .getCachePolicy(); | |
| 303 if (parentCachePolicy != CachePolicyVerify) | |
| 304 return parentCachePolicy; | |
| 305 } | |
| 306 | |
| 307 if (loadType == FrameLoadTypeReload) | |
| 308 return CachePolicyRevalidate; | |
| 309 | |
| 310 if (m_documentLoader && | |
| 311 m_documentLoader->getRequest().getCachePolicy() == | |
| 312 WebCachePolicy::ReturnCacheDataElseLoad) | |
| 313 return CachePolicyHistoryBuffer; | |
| 314 | |
| 315 // Returns CachePolicyVerify for other cases, mainly FrameLoadTypeStandard and | |
| 316 // FrameLoadTypeReloadMainResource. See public/web/WebFrameLoadType.h to know | |
| 317 // how these load types work. | |
| 318 return CachePolicyVerify; | |
| 319 } | |
| 320 | |
| 321 static WebCachePolicy memoryCachePolicyToResourceRequestCachePolicy( | |
| 322 const CachePolicy policy) { | |
| 323 if (policy == CachePolicyVerify) | |
| 324 return WebCachePolicy::UseProtocolCachePolicy; | |
| 325 if (policy == CachePolicyRevalidate) | |
| 326 return WebCachePolicy::ValidatingCacheData; | |
| 327 if (policy == CachePolicyReload) | |
| 328 return WebCachePolicy::BypassingCache; | |
| 329 if (policy == CachePolicyHistoryBuffer) | |
| 330 return WebCachePolicy::ReturnCacheDataElseLoad; | |
| 331 return WebCachePolicy::UseProtocolCachePolicy; | |
| 332 } | |
| 333 | |
| 334 static WebCachePolicy frameLoadTypeToWebCachePolicy(FrameLoadType type) { | |
| 335 if (type == FrameLoadTypeBackForward) | |
| 336 return WebCachePolicy::ReturnCacheDataElseLoad; | |
| 337 if (type == FrameLoadTypeReloadBypassingCache) | |
| 338 return WebCachePolicy::BypassingCache; | |
| 339 if (type == FrameLoadTypeReload) | |
| 340 return WebCachePolicy::ValidatingCacheData; | |
| 341 return WebCachePolicy::UseProtocolCachePolicy; | |
| 342 } | |
| 343 | |
| 344 WebCachePolicy FrameFetchContext::resourceRequestCachePolicy( | 362 WebCachePolicy FrameFetchContext::resourceRequestCachePolicy( |
| 345 ResourceRequest& request, | 363 ResourceRequest& request, |
| 346 Resource::Type type, | 364 Resource::Type type, |
| 347 FetchRequest::DeferOption defer) const { | 365 FetchRequest::DeferOption defer) const { |
| 348 DCHECK(frame()); | 366 DCHECK(frame()); |
| 349 if (type == Resource::MainResource) { | 367 if (type == Resource::MainResource) { |
| 350 FrameLoadType frameLoadType = masterDocumentLoader()->loadType(); | 368 const WebCachePolicy cachePolicy = determineWebCachePolicy( |
| 351 if (request.httpMethod() == "POST" && | 369 request.httpMethod() == "POST" ? RequestMethod::kIsPost |
| 352 frameLoadType == FrameLoadTypeBackForward) | 370 : RequestMethod::kIsNotPost, |
| 353 return WebCachePolicy::ReturnCacheDataDontLoad; | 371 request.isConditional() ? RequestType::kIsConditional |
| 354 if (frameLoadType == FrameLoadTypeReloadMainResource || | 372 : RequestType::kIsNotConditional, |
| 355 request.isConditional() || request.httpMethod() == "POST") | 373 ResourceType::kIsMainResource, masterDocumentLoader()->loadType()); |
| 356 return WebCachePolicy::ValidatingCacheData; | 374 // Follows the parent frame's policy. |
| 357 | 375 // TODO(toyoshim): Probably, FrameLoadType for each frame should have a |
| 358 WebCachePolicy policy = frameLoadTypeToWebCachePolicy(frameLoadType); | 376 // right type for reload or history navigations, and should not need to |
| 359 if (policy != WebCachePolicy::UseProtocolCachePolicy) | 377 // check parent's frame policy here. Once it has a right FrameLoadType, |
| 360 return policy; | 378 // we can remove Resource::Type argument from determineFrameWebCachePolicy. |
| 361 | 379 // See also crbug.com/332602. |
| 362 for (Frame* f = frame()->tree().parent(); f; f = f->tree().parent()) { | 380 if (cachePolicy != WebCachePolicy::UseProtocolCachePolicy) |
| 363 if (!f->isLocalFrame()) | 381 return cachePolicy; |
| 364 continue; | 382 return determineFrameWebCachePolicy(frame()->tree().parent(), |
| 365 policy = frameLoadTypeToWebCachePolicy( | 383 ResourceType::kIsMainResource); |
| 366 toLocalFrame(f)->loader().documentLoader()->loadType()); | |
| 367 if (policy != WebCachePolicy::UseProtocolCachePolicy) | |
| 368 return policy; | |
| 369 } | |
| 370 // Returns UseProtocolCachePolicy for other cases, parent frames not having | |
| 371 // special kinds of FrameLoadType as they are checked inside the for loop | |
| 372 // above, or |frameLoadType| being FrameLoadTypeStandard. See | |
| 373 // public/web/WebFrameLoadType.h to know how these load types work. | |
| 374 return WebCachePolicy::UseProtocolCachePolicy; | |
| 375 } | 384 } |
| 376 | 385 |
| 377 // For users on slow connections, we want to avoid blocking the parser in | 386 // For users on slow connections, we want to avoid blocking the parser in |
| 378 // the main frame on script loads inserted via document.write, since it can | 387 // the main frame on script loads inserted via document.write, since it can |
| 379 // add significant delays before page content is displayed on the screen. | 388 // add significant delays before page content is displayed on the screen. |
| 389 // TODO(toyoshim): Move following logic that rewrites ResourceRequest to | |
| 390 // somewhere that should be relevant to the script resource handling. | |
| 380 if (type == Resource::Script && isMainFrame() && m_document && | 391 if (type == Resource::Script && isMainFrame() && m_document && |
| 381 shouldDisallowFetchForMainFrameScript(request, defer, *m_document)) | 392 shouldDisallowFetchForMainFrameScript(request, defer, *m_document)) |
| 382 return WebCachePolicy::ReturnCacheDataDontLoad; | 393 return WebCachePolicy::ReturnCacheDataDontLoad; |
| 383 | 394 |
| 395 // TODO(toyoshim): We should check isConditional() and use ValidatingCacheData | |
| 396 // only when |cachePolicy| below is UseProtocolCachePolicy. | |
| 384 if (request.isConditional()) | 397 if (request.isConditional()) |
| 385 return WebCachePolicy::ValidatingCacheData; | 398 return WebCachePolicy::ValidatingCacheData; |
| 386 | 399 |
| 387 if (m_documentLoader && m_document && !m_document->loadEventFinished()) { | 400 return determineFrameWebCachePolicy(frame(), |
| 388 // For POST requests, we mutate the main resource's cache policy to avoid | 401 ResourceType::kIsNotMainResource); |
| 389 // form resubmission. This policy should not be inherited by subresources. | |
| 390 WebCachePolicy mainResourceCachePolicy = | |
| 391 m_documentLoader->getRequest().getCachePolicy(); | |
| 392 if (m_documentLoader->getRequest().httpMethod() == "POST") { | |
|
yhirano
2017/03/14 08:34:35
This part is missing in the new implementation.
Takashi Toyoshima
2017/03/15 03:13:51
We do not need this in the new code.
The old logi
| |
| 393 if (mainResourceCachePolicy == WebCachePolicy::ReturnCacheDataDontLoad) | |
| 394 return WebCachePolicy::ReturnCacheDataElseLoad; | |
| 395 return WebCachePolicy::UseProtocolCachePolicy; | |
| 396 } | |
| 397 return memoryCachePolicyToResourceRequestCachePolicy(getCachePolicy()); | |
| 398 } | |
| 399 return WebCachePolicy::UseProtocolCachePolicy; | |
| 400 } | 402 } |
| 401 | 403 |
| 402 // The |m_documentLoader| is null in the FrameFetchContext of an imported | 404 // The |m_documentLoader| is null in the FrameFetchContext of an imported |
| 403 // document. | 405 // document. |
| 404 // FIXME(http://crbug.com/274173): This means Inspector, which uses | 406 // FIXME(http://crbug.com/274173): This means Inspector, which uses |
| 405 // DocumentLoader as a grouping entity, cannot see imported documents. | 407 // DocumentLoader as a grouping entity, cannot see imported documents. |
| 406 inline DocumentLoader* FrameFetchContext::masterDocumentLoader() const { | 408 inline DocumentLoader* FrameFetchContext::masterDocumentLoader() const { |
| 407 if (m_documentLoader) | 409 if (m_documentLoader) |
| 408 return m_documentLoader.get(); | 410 return m_documentLoader.get(); |
| 409 | 411 |
| (...skipping 672 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1082 response); | 1084 response); |
| 1083 } | 1085 } |
| 1084 | 1086 |
| 1085 DEFINE_TRACE(FrameFetchContext) { | 1087 DEFINE_TRACE(FrameFetchContext) { |
| 1086 visitor->trace(m_document); | 1088 visitor->trace(m_document); |
| 1087 visitor->trace(m_documentLoader); | 1089 visitor->trace(m_documentLoader); |
| 1088 FetchContext::trace(visitor); | 1090 FetchContext::trace(visitor); |
| 1089 } | 1091 } |
| 1090 | 1092 |
| 1091 } // namespace blink | 1093 } // namespace blink |
| OLD | NEW |