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 }; | |
Nate Chapin
2017/03/09 20:02:47
I'm behind on the style guide: is kEnumValue prefe
Takashi Toyoshima
2017/03/13 11:54:29
Yeah, I also recently noticed this style change th
| |
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: | |
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(). | |
254 WebCachePolicy determineFrameWebCachePolicy(Frame* frame, Resource::Type type) { | |
Nate Chapin
2017/03/09 20:02:46
Can we use the local ResourceType instead of Resou
Takashi Toyoshima
2017/03/13 11:54:30
Ah, yes. Sorry, I just forgot to revert this type
| |
255 if (!frame) | |
256 return WebCachePolicy::UseProtocolCachePolicy; | |
257 if (!frame->isLocalFrame()) | |
Nate Chapin
2017/03/09 20:02:46
Should this have a TODO to remove when |type| is r
Takashi Toyoshima
2017/03/13 11:54:29
Ah, yes. Subresources will not need to check paren
| |
258 return determineFrameWebCachePolicy(frame->tree().parent(), type); | |
259 | |
260 // Does not propagate cache policy for subresources after the load event. | |
261 if (type != Resource::MainResource && | |
262 toLocalFrame(frame)->document()->fetcher()->context().isLoadComplete()) { | |
Nate Chapin
2017/03/09 20:02:47
Optional: Just check loadEventFinished() directly
Takashi Toyoshima
2017/03/13 11:54:30
Done.
| |
263 return WebCachePolicy::UseProtocolCachePolicy; | |
264 } | |
265 | |
266 // Respects BypassingCache rather than parent's policy. | |
267 // TODO(toyoshim): Adopt BypassingCache even for MainResource. | |
Nate Chapin
2017/03/09 20:02:46
Why is the MainResource special case necessary?
Takashi Toyoshima
2017/03/13 11:54:29
Just because the old behavior is so.
I already con
| |
268 FrameLoadType loadType = | |
269 toLocalFrame(frame)->loader().documentLoader()->loadType(); | |
270 if (type != Resource::MainResource && | |
271 loadType == FrameLoadTypeReloadBypassingCache) { | |
272 return WebCachePolicy::BypassingCache; | |
273 } | |
274 | |
275 // Respects parent's policy if it has a special one. | |
276 WebCachePolicy parentPolicy = | |
277 determineFrameWebCachePolicy(frame->tree().parent(), type); | |
278 if (parentPolicy != WebCachePolicy::UseProtocolCachePolicy) | |
279 return parentPolicy; | |
280 | |
281 // Otherwise, follows FrameLoadType. Use kIsNotPost, kIsNotConditional, and | |
282 // kIsNotMainResource to obtain a representative policy for the frame. | |
283 return determineWebCachePolicy(RequestMethod::kIsNotPost, | |
284 RequestType::kIsNotConditional, | |
285 ResourceType::kIsNotMainResource, loadType); | |
286 } | |
287 | |
218 } // namespace | 288 } // namespace |
219 | 289 |
220 FrameFetchContext::FrameFetchContext(DocumentLoader* loader, Document* document) | 290 FrameFetchContext::FrameFetchContext(DocumentLoader* loader, Document* document) |
221 : m_document(document), m_documentLoader(loader) { | 291 : m_document(document), m_documentLoader(loader) { |
222 DCHECK(frame()); | 292 DCHECK(frame()); |
223 } | 293 } |
224 | 294 |
225 FrameFetchContext::~FrameFetchContext() { | 295 FrameFetchContext::~FrameFetchContext() { |
226 m_document = nullptr; | 296 m_document = nullptr; |
227 m_documentLoader = nullptr; | 297 m_documentLoader = nullptr; |
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
278 if (!request.url().isEmpty() && !request.url().protocolIsInHTTPFamily()) | 348 if (!request.url().isEmpty() && !request.url().protocolIsInHTTPFamily()) |
279 return; | 349 return; |
280 | 350 |
281 if (masterDocumentLoader()->loadType() == FrameLoadTypeReload) | 351 if (masterDocumentLoader()->loadType() == FrameLoadTypeReload) |
282 request.clearHTTPHeaderField("Save-Data"); | 352 request.clearHTTPHeaderField("Save-Data"); |
283 | 353 |
284 if (frame()->settings() && frame()->settings()->getDataSaverEnabled()) | 354 if (frame()->settings() && frame()->settings()->getDataSaverEnabled()) |
285 request.setHTTPHeaderField("Save-Data", "on"); | 355 request.setHTTPHeaderField("Save-Data", "on"); |
286 } | 356 } |
287 | 357 |
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( | 358 WebCachePolicy FrameFetchContext::resourceRequestCachePolicy( |
345 ResourceRequest& request, | 359 ResourceRequest& request, |
346 Resource::Type type, | 360 Resource::Type type, |
347 FetchRequest::DeferOption defer) const { | 361 FetchRequest::DeferOption defer) const { |
348 DCHECK(frame()); | 362 DCHECK(frame()); |
349 if (type == Resource::MainResource) { | 363 if (type == Resource::MainResource) { |
350 FrameLoadType frameLoadType = masterDocumentLoader()->loadType(); | 364 const WebCachePolicy cachePolicy = determineWebCachePolicy( |
351 if (request.httpMethod() == "POST" && | 365 request.httpMethod() == "POST" ? RequestMethod::kIsPost |
352 frameLoadType == FrameLoadTypeBackForward) | 366 : RequestMethod::kIsNotPost, |
353 return WebCachePolicy::ReturnCacheDataDontLoad; | 367 request.isConditional() ? RequestType::kIsConditional |
354 if (frameLoadType == FrameLoadTypeReloadMainResource || | 368 : RequestType::kIsNotConditional, |
355 request.isConditional() || request.httpMethod() == "POST") | 369 ResourceType::kIsMainResource, masterDocumentLoader()->loadType()); |
356 return WebCachePolicy::ValidatingCacheData; | 370 // Follows the parent frame's policy. |
357 | 371 // TODO(toyoshim): Probably, FrameLoadType for each frame should have a |
358 WebCachePolicy policy = frameLoadTypeToWebCachePolicy(frameLoadType); | 372 // right type for reload or history navigations, and should not need to |
359 if (policy != WebCachePolicy::UseProtocolCachePolicy) | 373 // check parent's frame policy here. Once it has a right FrameLoadType, |
360 return policy; | 374 // we can remove Resource::Type argument from determineFrameWebCachePolicy. |
361 | 375 // See also crbug.com/332602. |
362 for (Frame* f = frame()->tree().parent(); f; f = f->tree().parent()) { | 376 if (cachePolicy != WebCachePolicy::UseProtocolCachePolicy) |
363 if (!f->isLocalFrame()) | 377 return cachePolicy; |
364 continue; | 378 return determineFrameWebCachePolicy(frame()->tree().parent(), type); |
365 policy = frameLoadTypeToWebCachePolicy( | |
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 } | 379 } |
376 | 380 |
377 // For users on slow connections, we want to avoid blocking the parser in | 381 // 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 | 382 // 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. | 383 // add significant delays before page content is displayed on the screen. |
384 // TODO(toyoshim): Move following logic that rewrites ResourceRequest to | |
385 // somewhere that should be relevant to the script resource handling. | |
380 if (type == Resource::Script && isMainFrame() && m_document && | 386 if (type == Resource::Script && isMainFrame() && m_document && |
381 shouldDisallowFetchForMainFrameScript(request, defer, *m_document)) | 387 shouldDisallowFetchForMainFrameScript(request, defer, *m_document)) |
382 return WebCachePolicy::ReturnCacheDataDontLoad; | 388 return WebCachePolicy::ReturnCacheDataDontLoad; |
383 | 389 |
390 // TODO(toyoshim): We should check isConditional() and use ValidatingCacheData | |
391 // only when |cachePolicy| below is UseProtocolCachePolicy. | |
384 if (request.isConditional()) | 392 if (request.isConditional()) |
385 return WebCachePolicy::ValidatingCacheData; | 393 return WebCachePolicy::ValidatingCacheData; |
386 | 394 |
387 if (m_documentLoader && m_document && !m_document->loadEventFinished()) { | 395 return determineFrameWebCachePolicy(frame(), type); |
388 // For POST requests, we mutate the main resource's cache policy to avoid | |
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") { | |
393 if (mainResourceCachePolicy == WebCachePolicy::ReturnCacheDataDontLoad) | |
394 return WebCachePolicy::ReturnCacheDataElseLoad; | |
395 return WebCachePolicy::UseProtocolCachePolicy; | |
396 } | |
397 return memoryCachePolicyToResourceRequestCachePolicy(getCachePolicy()); | |
398 } | |
399 return WebCachePolicy::UseProtocolCachePolicy; | |
400 } | 396 } |
401 | 397 |
402 // The |m_documentLoader| is null in the FrameFetchContext of an imported | 398 // The |m_documentLoader| is null in the FrameFetchContext of an imported |
403 // document. | 399 // document. |
404 // FIXME(http://crbug.com/274173): This means Inspector, which uses | 400 // FIXME(http://crbug.com/274173): This means Inspector, which uses |
405 // DocumentLoader as a grouping entity, cannot see imported documents. | 401 // DocumentLoader as a grouping entity, cannot see imported documents. |
406 inline DocumentLoader* FrameFetchContext::masterDocumentLoader() const { | 402 inline DocumentLoader* FrameFetchContext::masterDocumentLoader() const { |
407 if (m_documentLoader) | 403 if (m_documentLoader) |
408 return m_documentLoader.get(); | 404 return m_documentLoader.get(); |
409 | 405 |
(...skipping 672 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1082 response); | 1078 response); |
1083 } | 1079 } |
1084 | 1080 |
1085 DEFINE_TRACE(FrameFetchContext) { | 1081 DEFINE_TRACE(FrameFetchContext) { |
1086 visitor->trace(m_document); | 1082 visitor->trace(m_document); |
1087 visitor->trace(m_documentLoader); | 1083 visitor->trace(m_documentLoader); |
1088 FetchContext::trace(visitor); | 1084 FetchContext::trace(visitor); |
1089 } | 1085 } |
1090 | 1086 |
1091 } // namespace blink | 1087 } // namespace blink |
OLD | NEW |