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 199 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
210 return document.settings() | 210 return document.settings() |
211 ->getDisallowFetchForDocWrittenScriptsInMainFrame() || | 211 ->getDisallowFetchForDocWrittenScriptsInMainFrame() || |
212 (document.settings() | 212 (document.settings() |
213 ->getDisallowFetchForDocWrittenScriptsInMainFrameOnSlowConnections
() && | 213 ->getDisallowFetchForDocWrittenScriptsInMainFrameOnSlowConnections
() && |
214 is2G) || | 214 is2G) || |
215 (document.settings() | 215 (document.settings() |
216 ->getDisallowFetchForDocWrittenScriptsInMainFrameIfEffectively2G()
&& | 216 ->getDisallowFetchForDocWrittenScriptsInMainFrameIfEffectively2G()
&& |
217 isConnectionEffectively2G(effectiveConnection)); | 217 isConnectionEffectively2G(effectiveConnection)); |
218 } | 218 } |
219 | 219 |
| 220 enum class RequestMethod { kIsPost, kIsNotPost }; |
| 221 enum class RequestType { kIsConditional, kIsNotConditional }; |
| 222 enum class ResourceType { kIsMainResource, kIsNotMainResource }; |
| 223 |
| 224 WebCachePolicy determineWebCachePolicy(RequestMethod method, |
| 225 RequestType requestType, |
| 226 ResourceType resourceType, |
| 227 FrameLoadType loadType) { |
| 228 switch (loadType) { |
| 229 case FrameLoadTypeStandard: |
| 230 return (requestType == RequestType::kIsConditional || |
| 231 method == RequestMethod::kIsPost) |
| 232 ? WebCachePolicy::ValidatingCacheData |
| 233 : WebCachePolicy::UseProtocolCachePolicy; |
| 234 case FrameLoadTypeReplaceCurrentItem: |
| 235 case FrameLoadTypeInitialInChildFrame: |
| 236 // TODO(toyoshim): Should be the same with FrameLoadTypeStandard, but |
| 237 // keep legacy logic as is. To be changed in a follow-up patch soon. |
| 238 return (resourceType == ResourceType::kIsMainResource && |
| 239 (requestType == RequestType::kIsConditional || |
| 240 method == RequestMethod::kIsPost)) |
| 241 ? WebCachePolicy::ValidatingCacheData |
| 242 : WebCachePolicy::UseProtocolCachePolicy; |
| 243 case FrameLoadTypeInitialHistoryLoad: |
| 244 // TODO(toyoshim): Should be the same with FrameLoadTypeBackForward, but |
| 245 // keep legacy logic as is. To be changed in a follow-up patch soon. |
| 246 return (resourceType == ResourceType::kIsMainResource && |
| 247 (requestType == RequestType::kIsConditional || |
| 248 method == RequestMethod::kIsPost)) |
| 249 ? WebCachePolicy::ValidatingCacheData |
| 250 : WebCachePolicy::UseProtocolCachePolicy; |
| 251 case FrameLoadTypeBackForward: |
| 252 // Mutates the policy for POST requests to avoid form resubmission. |
| 253 return method == RequestMethod::kIsPost |
| 254 ? WebCachePolicy::ReturnCacheDataDontLoad |
| 255 : WebCachePolicy::ReturnCacheDataElseLoad; |
| 256 case FrameLoadTypeReload: |
| 257 return WebCachePolicy::ValidatingCacheData; |
| 258 case FrameLoadTypeReloadMainResource: |
| 259 return resourceType == ResourceType::kIsMainResource |
| 260 ? WebCachePolicy::ValidatingCacheData |
| 261 : WebCachePolicy::UseProtocolCachePolicy; |
| 262 case FrameLoadTypeReloadBypassingCache: |
| 263 // TODO(toyoshim): Should return BypassingCache always, but keep legacy |
| 264 // logic as is. To be changed in a follow-up patch soon. |
| 265 return (resourceType == ResourceType::kIsMainResource && |
| 266 (requestType == RequestType::kIsConditional || |
| 267 method == RequestMethod::kIsPost)) |
| 268 ? WebCachePolicy::ValidatingCacheData |
| 269 : WebCachePolicy::BypassingCache; |
| 270 } |
| 271 NOTREACHED(); |
| 272 return WebCachePolicy::UseProtocolCachePolicy; |
| 273 } |
| 274 |
| 275 // TODO(toyoshim): Remove |resourceType|. See comments in |
| 276 // resourceRequestCachePolicy(). |
| 277 WebCachePolicy determineFrameWebCachePolicy(Frame* frame, |
| 278 ResourceType resourceType) { |
| 279 if (!frame) |
| 280 return WebCachePolicy::UseProtocolCachePolicy; |
| 281 if (!frame->isLocalFrame()) |
| 282 return determineFrameWebCachePolicy(frame->tree().parent(), resourceType); |
| 283 |
| 284 // Does not propagate cache policy for subresources after the load event. |
| 285 // TODO(toyoshim): We should be able to remove following parents' policy check |
| 286 // if each frame has a relevant FrameLoadType for reload and history |
| 287 // navigations. |
| 288 if (resourceType == ResourceType::kIsNotMainResource && |
| 289 toLocalFrame(frame)->document()->loadEventFinished()) { |
| 290 return WebCachePolicy::UseProtocolCachePolicy; |
| 291 } |
| 292 |
| 293 // Respects BypassingCache rather than parent's policy. |
| 294 // TODO(toyoshim): Adopt BypassingCache even for MainResource. |
| 295 FrameLoadType loadType = |
| 296 toLocalFrame(frame)->loader().documentLoader()->loadType(); |
| 297 if (resourceType == ResourceType::kIsNotMainResource && |
| 298 loadType == FrameLoadTypeReloadBypassingCache) { |
| 299 return WebCachePolicy::BypassingCache; |
| 300 } |
| 301 |
| 302 // Respects parent's policy if it has a special one. |
| 303 WebCachePolicy parentPolicy = |
| 304 determineFrameWebCachePolicy(frame->tree().parent(), resourceType); |
| 305 if (parentPolicy != WebCachePolicy::UseProtocolCachePolicy) |
| 306 return parentPolicy; |
| 307 |
| 308 // Otherwise, follows FrameLoadType. Use kIsNotPost, kIsNotConditional, and |
| 309 // kIsNotMainResource to obtain a representative policy for the frame. |
| 310 return determineWebCachePolicy(RequestMethod::kIsNotPost, |
| 311 RequestType::kIsNotConditional, |
| 312 ResourceType::kIsNotMainResource, loadType); |
| 313 } |
| 314 |
220 } // namespace | 315 } // namespace |
221 | 316 |
222 FrameFetchContext::FrameFetchContext(DocumentLoader* loader, Document* document) | 317 FrameFetchContext::FrameFetchContext(DocumentLoader* loader, Document* document) |
223 : m_document(document), m_documentLoader(loader) { | 318 : m_document(document), m_documentLoader(loader) { |
224 DCHECK(frame()); | 319 DCHECK(frame()); |
225 } | 320 } |
226 | 321 |
227 FrameFetchContext::~FrameFetchContext() { | 322 FrameFetchContext::~FrameFetchContext() { |
228 m_document = nullptr; | 323 m_document = nullptr; |
229 m_documentLoader = nullptr; | 324 m_documentLoader = nullptr; |
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
280 if (!request.url().isEmpty() && !request.url().protocolIsInHTTPFamily()) | 375 if (!request.url().isEmpty() && !request.url().protocolIsInHTTPFamily()) |
281 return; | 376 return; |
282 | 377 |
283 if (masterDocumentLoader()->loadType() == FrameLoadTypeReload) | 378 if (masterDocumentLoader()->loadType() == FrameLoadTypeReload) |
284 request.clearHTTPHeaderField("Save-Data"); | 379 request.clearHTTPHeaderField("Save-Data"); |
285 | 380 |
286 if (frame()->settings() && frame()->settings()->getDataSaverEnabled()) | 381 if (frame()->settings() && frame()->settings()->getDataSaverEnabled()) |
287 request.setHTTPHeaderField("Save-Data", "on"); | 382 request.setHTTPHeaderField("Save-Data", "on"); |
288 } | 383 } |
289 | 384 |
290 CachePolicy FrameFetchContext::getCachePolicy() const { | |
291 if (m_document && m_document->loadEventFinished()) | |
292 return CachePolicyVerify; | |
293 | |
294 FrameLoadType loadType = masterDocumentLoader()->loadType(); | |
295 if (loadType == FrameLoadTypeReloadBypassingCache) | |
296 return CachePolicyReload; | |
297 | |
298 Frame* parentFrame = frame()->tree().parent(); | |
299 if (parentFrame && parentFrame->isLocalFrame()) { | |
300 CachePolicy parentCachePolicy = toLocalFrame(parentFrame) | |
301 ->document() | |
302 ->fetcher() | |
303 ->context() | |
304 .getCachePolicy(); | |
305 if (parentCachePolicy != CachePolicyVerify) | |
306 return parentCachePolicy; | |
307 } | |
308 | |
309 if (loadType == FrameLoadTypeReload) | |
310 return CachePolicyRevalidate; | |
311 | |
312 if (m_documentLoader && | |
313 m_documentLoader->getRequest().getCachePolicy() == | |
314 WebCachePolicy::ReturnCacheDataElseLoad) | |
315 return CachePolicyHistoryBuffer; | |
316 | |
317 // Returns CachePolicyVerify for other cases, mainly FrameLoadTypeStandard and | |
318 // FrameLoadTypeReloadMainResource. See public/web/WebFrameLoadType.h to know | |
319 // how these load types work. | |
320 return CachePolicyVerify; | |
321 } | |
322 | |
323 static WebCachePolicy memoryCachePolicyToResourceRequestCachePolicy( | |
324 const CachePolicy policy) { | |
325 if (policy == CachePolicyVerify) | |
326 return WebCachePolicy::UseProtocolCachePolicy; | |
327 if (policy == CachePolicyRevalidate) | |
328 return WebCachePolicy::ValidatingCacheData; | |
329 if (policy == CachePolicyReload) | |
330 return WebCachePolicy::BypassingCache; | |
331 if (policy == CachePolicyHistoryBuffer) | |
332 return WebCachePolicy::ReturnCacheDataElseLoad; | |
333 return WebCachePolicy::UseProtocolCachePolicy; | |
334 } | |
335 | |
336 static WebCachePolicy frameLoadTypeToWebCachePolicy(FrameLoadType type) { | |
337 if (type == FrameLoadTypeBackForward) | |
338 return WebCachePolicy::ReturnCacheDataElseLoad; | |
339 if (type == FrameLoadTypeReloadBypassingCache) | |
340 return WebCachePolicy::BypassingCache; | |
341 if (type == FrameLoadTypeReload) | |
342 return WebCachePolicy::ValidatingCacheData; | |
343 return WebCachePolicy::UseProtocolCachePolicy; | |
344 } | |
345 | |
346 WebCachePolicy FrameFetchContext::resourceRequestCachePolicy( | 385 WebCachePolicy FrameFetchContext::resourceRequestCachePolicy( |
347 ResourceRequest& request, | 386 ResourceRequest& request, |
348 Resource::Type type, | 387 Resource::Type type, |
349 FetchRequest::DeferOption defer) const { | 388 FetchRequest::DeferOption defer) const { |
350 DCHECK(frame()); | 389 DCHECK(frame()); |
351 if (type == Resource::MainResource) { | 390 if (type == Resource::MainResource) { |
352 FrameLoadType frameLoadType = masterDocumentLoader()->loadType(); | 391 const WebCachePolicy cachePolicy = determineWebCachePolicy( |
353 if (request.httpMethod() == "POST" && | 392 request.httpMethod() == "POST" ? RequestMethod::kIsPost |
354 frameLoadType == FrameLoadTypeBackForward) | 393 : RequestMethod::kIsNotPost, |
355 return WebCachePolicy::ReturnCacheDataDontLoad; | 394 request.isConditional() ? RequestType::kIsConditional |
356 if (frameLoadType == FrameLoadTypeReloadMainResource || | 395 : RequestType::kIsNotConditional, |
357 request.isConditional() || request.httpMethod() == "POST") | 396 ResourceType::kIsMainResource, masterDocumentLoader()->loadType()); |
358 return WebCachePolicy::ValidatingCacheData; | 397 // Follows the parent frame's policy. |
359 | 398 // TODO(toyoshim): Probably, FrameLoadType for each frame should have a |
360 WebCachePolicy policy = frameLoadTypeToWebCachePolicy(frameLoadType); | 399 // right type for reload or history navigations, and should not need to |
361 if (policy != WebCachePolicy::UseProtocolCachePolicy) | 400 // check parent's frame policy here. Once it has a right FrameLoadType, |
362 return policy; | 401 // we can remove Resource::Type argument from determineFrameWebCachePolicy. |
363 | 402 // See also crbug.com/332602. |
364 for (Frame* f = frame()->tree().parent(); f; f = f->tree().parent()) { | 403 if (cachePolicy != WebCachePolicy::UseProtocolCachePolicy) |
365 if (!f->isLocalFrame()) | 404 return cachePolicy; |
366 continue; | 405 return determineFrameWebCachePolicy(frame()->tree().parent(), |
367 policy = frameLoadTypeToWebCachePolicy( | 406 ResourceType::kIsMainResource); |
368 toLocalFrame(f)->loader().documentLoader()->loadType()); | |
369 if (policy != WebCachePolicy::UseProtocolCachePolicy) | |
370 return policy; | |
371 } | |
372 // Returns UseProtocolCachePolicy for other cases, parent frames not having | |
373 // special kinds of FrameLoadType as they are checked inside the for loop | |
374 // above, or |frameLoadType| being FrameLoadTypeStandard. See | |
375 // public/web/WebFrameLoadType.h to know how these load types work. | |
376 return WebCachePolicy::UseProtocolCachePolicy; | |
377 } | 407 } |
378 | 408 |
379 // For users on slow connections, we want to avoid blocking the parser in | 409 // For users on slow connections, we want to avoid blocking the parser in |
380 // the main frame on script loads inserted via document.write, since it can | 410 // the main frame on script loads inserted via document.write, since it can |
381 // add significant delays before page content is displayed on the screen. | 411 // add significant delays before page content is displayed on the screen. |
| 412 // TODO(toyoshim): Move following logic that rewrites ResourceRequest to |
| 413 // somewhere that should be relevant to the script resource handling. |
382 if (type == Resource::Script && isMainFrame() && m_document && | 414 if (type == Resource::Script && isMainFrame() && m_document && |
383 shouldDisallowFetchForMainFrameScript(request, defer, *m_document)) | 415 shouldDisallowFetchForMainFrameScript(request, defer, *m_document)) |
384 return WebCachePolicy::ReturnCacheDataDontLoad; | 416 return WebCachePolicy::ReturnCacheDataDontLoad; |
385 | 417 |
| 418 // TODO(toyoshim): We should check isConditional() and use ValidatingCacheData |
| 419 // only when |cachePolicy| below is UseProtocolCachePolicy. |
386 if (request.isConditional()) | 420 if (request.isConditional()) |
387 return WebCachePolicy::ValidatingCacheData; | 421 return WebCachePolicy::ValidatingCacheData; |
388 | 422 |
389 if (m_documentLoader && m_document && !m_document->loadEventFinished()) { | 423 return determineFrameWebCachePolicy(frame(), |
390 // For POST requests, we mutate the main resource's cache policy to avoid | 424 ResourceType::kIsNotMainResource); |
391 // form resubmission. This policy should not be inherited by subresources. | |
392 WebCachePolicy mainResourceCachePolicy = | |
393 m_documentLoader->getRequest().getCachePolicy(); | |
394 if (m_documentLoader->getRequest().httpMethod() == "POST") { | |
395 if (mainResourceCachePolicy == WebCachePolicy::ReturnCacheDataDontLoad) | |
396 return WebCachePolicy::ReturnCacheDataElseLoad; | |
397 return WebCachePolicy::UseProtocolCachePolicy; | |
398 } | |
399 return memoryCachePolicyToResourceRequestCachePolicy(getCachePolicy()); | |
400 } | |
401 return WebCachePolicy::UseProtocolCachePolicy; | |
402 } | 425 } |
403 | 426 |
404 // The |m_documentLoader| is null in the FrameFetchContext of an imported | 427 // The |m_documentLoader| is null in the FrameFetchContext of an imported |
405 // document. | 428 // document. |
406 // FIXME(http://crbug.com/274173): This means Inspector, which uses | 429 // FIXME(http://crbug.com/274173): This means Inspector, which uses |
407 // DocumentLoader as a grouping entity, cannot see imported documents. | 430 // DocumentLoader as a grouping entity, cannot see imported documents. |
408 inline DocumentLoader* FrameFetchContext::masterDocumentLoader() const { | 431 inline DocumentLoader* FrameFetchContext::masterDocumentLoader() const { |
409 if (m_documentLoader) | 432 if (m_documentLoader) |
410 return m_documentLoader.get(); | 433 return m_documentLoader.get(); |
411 | 434 |
(...skipping 645 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1057 response); | 1080 response); |
1058 } | 1081 } |
1059 | 1082 |
1060 DEFINE_TRACE(FrameFetchContext) { | 1083 DEFINE_TRACE(FrameFetchContext) { |
1061 visitor->trace(m_document); | 1084 visitor->trace(m_document); |
1062 visitor->trace(m_documentLoader); | 1085 visitor->trace(m_documentLoader); |
1063 FetchContext::trace(visitor); | 1086 FetchContext::trace(visitor); |
1064 } | 1087 } |
1065 | 1088 |
1066 } // namespace blink | 1089 } // namespace blink |
OLD | NEW |