OLD | NEW |
1 /* | 1 /* |
2 * Copyright (C) 2006, 2007, 2008 Apple Inc. All rights reserved. | 2 * Copyright (C) 2006, 2007, 2008 Apple Inc. All rights reserved. |
3 * Copyright (C) 2011 Google Inc. All rights reserved. | 3 * Copyright (C) 2011 Google Inc. All rights reserved. |
4 * | 4 * |
5 * Redistribution and use in source and binary forms, with or without | 5 * Redistribution and use in source and binary forms, with or without |
6 * modification, are permitted provided that the following conditions | 6 * modification, are permitted provided that the following conditions |
7 * are met: | 7 * are met: |
8 * | 8 * |
9 * 1. Redistributions of source code must retain the above copyright | 9 * 1. Redistributions of source code must retain the above copyright |
10 * notice, this list of conditions and the following disclaimer. | 10 * notice, this list of conditions and the following disclaimer. |
(...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
104 m_substituteData(substituteData), | 104 m_substituteData(substituteData), |
105 m_request(req), | 105 m_request(req), |
106 m_isClientRedirect(clientRedirectPolicy == | 106 m_isClientRedirect(clientRedirectPolicy == |
107 ClientRedirectPolicy::ClientRedirect), | 107 ClientRedirectPolicy::ClientRedirect), |
108 m_replacesCurrentHistoryItem(false), | 108 m_replacesCurrentHistoryItem(false), |
109 m_dataReceived(false), | 109 m_dataReceived(false), |
110 m_navigationType(NavigationTypeOther), | 110 m_navigationType(NavigationTypeOther), |
111 m_documentLoadTiming(*this), | 111 m_documentLoadTiming(*this), |
112 m_timeOfLastDataReceived(0.0), | 112 m_timeOfLastDataReceived(0.0), |
113 m_applicationCacheHost(ApplicationCacheHost::create(this)), | 113 m_applicationCacheHost(ApplicationCacheHost::create(this)), |
114 m_wasBlockedAfterXFrameOptionsOrCSP(false), | 114 m_wasBlockedAfterCSP(false), |
115 m_state(NotStarted), | 115 m_state(NotStarted), |
116 m_inDataReceived(false), | 116 m_inDataReceived(false), |
117 m_dataBuffer(SharedBuffer::create()) { | 117 m_dataBuffer(SharedBuffer::create()) { |
118 // The document URL needs to be added to the head of the list as that is | 118 // The document URL needs to be added to the head of the list as that is |
119 // where the redirects originated. | 119 // where the redirects originated. |
120 if (m_isClientRedirect) | 120 if (m_isClientRedirect) |
121 appendRedirect(m_frame->document()->url()); | 121 appendRedirect(m_frame->document()->url()); |
122 } | 122 } |
123 | 123 |
124 FrameLoader* DocumentLoader::frameLoader() const { | 124 FrameLoader* DocumentLoader::frameLoader() const { |
(...skipping 149 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
274 DCHECK(m_mainResource); | 274 DCHECK(m_mainResource); |
275 | 275 |
276 if (!m_mainResource->errorOccurred() && !m_mainResource->wasCanceled()) { | 276 if (!m_mainResource->errorOccurred() && !m_mainResource->wasCanceled()) { |
277 finishedLoading(m_mainResource->loadFinishTime()); | 277 finishedLoading(m_mainResource->loadFinishTime()); |
278 return; | 278 return; |
279 } | 279 } |
280 | 280 |
281 if (m_applicationCacheHost) | 281 if (m_applicationCacheHost) |
282 m_applicationCacheHost->failedLoadingMainResource(); | 282 m_applicationCacheHost->failedLoadingMainResource(); |
283 m_state = MainResourceDone; | 283 m_state = MainResourceDone; |
| 284 |
| 285 if (m_mainResource->resourceError().wasBlockedByResponse()) { |
| 286 InspectorInstrumentation::canceledAfterReceivedResourceResponse( |
| 287 m_frame, this, mainResourceIdentifier(), resource->response(), |
| 288 m_mainResource.get()); |
| 289 } |
| 290 |
284 frameLoader()->loadFailed(this, m_mainResource->resourceError()); | 291 frameLoader()->loadFailed(this, m_mainResource->resourceError()); |
285 clearMainResourceHandle(); | 292 clearMainResourceHandle(); |
286 } | 293 } |
287 | 294 |
288 void DocumentLoader::finishedLoading(double finishTime) { | 295 void DocumentLoader::finishedLoading(double finishTime) { |
289 DCHECK(m_frame->loader().stateMachine()->creatingInitialEmptyDocument() || | 296 DCHECK(m_frame->loader().stateMachine()->creatingInitialEmptyDocument() || |
290 !m_frame->page()->suspended() || | 297 !m_frame->page()->suspended() || |
291 InspectorInstrumentation::isDebuggerPaused(m_frame)); | 298 InspectorInstrumentation::isDebuggerPaused(m_frame)); |
292 | 299 |
293 double responseEndTime = finishTime; | 300 double responseEndTime = finishTime; |
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
377 // Downloading is handled by the embedder, but we still get the initial | 384 // Downloading is handled by the embedder, but we still get the initial |
378 // response so that we can ignore it and clean up properly. | 385 // response so that we can ignore it and clean up properly. |
379 return false; | 386 return false; |
380 } | 387 } |
381 | 388 |
382 if (!canShowMIMEType(m_response.mimeType(), m_frame)) | 389 if (!canShowMIMEType(m_response.mimeType(), m_frame)) |
383 return false; | 390 return false; |
384 return true; | 391 return true; |
385 } | 392 } |
386 | 393 |
387 void DocumentLoader::cancelLoadAfterXFrameOptionsOrCSPDenied( | 394 void DocumentLoader::cancelLoadAfterCSPDenied( |
388 const ResourceResponse& response) { | 395 const ResourceResponse& response) { |
389 InspectorInstrumentation::continueAfterXFrameOptionsDenied( | 396 InspectorInstrumentation::canceledAfterReceivedResourceResponse( |
390 m_frame, this, mainResourceIdentifier(), response, m_mainResource.get()); | 397 m_frame, this, mainResourceIdentifier(), response, m_mainResource.get()); |
391 | 398 |
392 setWasBlockedAfterXFrameOptionsOrCSP(); | 399 setWasBlockedAfterCSP(); |
393 | 400 |
394 // Pretend that this was an empty HTTP 200 response. Don't reuse the original | 401 // Pretend that this was an empty HTTP 200 response. Don't reuse the original |
395 // URL for the empty page (https://crbug.com/622385). | 402 // URL for the empty page (https://crbug.com/622385). |
396 // | 403 // |
397 // TODO(mkwst): Remove this once XFO moves to the browser. | 404 // TODO(mkwst): Remove this once XFO moves to the browser. |
398 // https://crbug.com/555418. | 405 // https://crbug.com/555418. |
399 clearMainResourceHandle(); | 406 clearMainResourceHandle(); |
400 m_contentSecurityPolicy.clear(); | 407 m_contentSecurityPolicy.clear(); |
401 KURL blockedURL = SecurityOrigin::urlWithUniqueSecurityOrigin(); | 408 KURL blockedURL = SecurityOrigin::urlWithUniqueSecurityOrigin(); |
402 m_originalRequest.setURL(blockedURL); | 409 m_originalRequest.setURL(blockedURL); |
(...skipping 21 matching lines...) Expand all Loading... |
424 // we don't save the result for future use. All responses loaded from appcache | 431 // we don't save the result for future use. All responses loaded from appcache |
425 // will have a non-zero appCacheID(). | 432 // will have a non-zero appCacheID(). |
426 if (response.appCacheID()) | 433 if (response.appCacheID()) |
427 memoryCache()->remove(m_mainResource.get()); | 434 memoryCache()->remove(m_mainResource.get()); |
428 | 435 |
429 m_contentSecurityPolicy = ContentSecurityPolicy::create(); | 436 m_contentSecurityPolicy = ContentSecurityPolicy::create(); |
430 m_contentSecurityPolicy->setOverrideURLForSelf(response.url()); | 437 m_contentSecurityPolicy->setOverrideURLForSelf(response.url()); |
431 m_contentSecurityPolicy->didReceiveHeaders( | 438 m_contentSecurityPolicy->didReceiveHeaders( |
432 ContentSecurityPolicyResponseHeaders(response)); | 439 ContentSecurityPolicyResponseHeaders(response)); |
433 if (!m_contentSecurityPolicy->allowAncestors(m_frame, response.url())) { | 440 if (!m_contentSecurityPolicy->allowAncestors(m_frame, response.url())) { |
434 cancelLoadAfterXFrameOptionsOrCSPDenied(response); | 441 cancelLoadAfterCSPDenied(response); |
435 return; | 442 return; |
436 } | 443 } |
437 | 444 |
438 // 'frame-ancestors' obviates 'x-frame-options': | |
439 // https://w3c.github.io/webappsec/specs/content-security-policy/#frame-ancest
ors-and-frame-options | |
440 if (!m_contentSecurityPolicy->isFrameAncestorsEnforced()) { | |
441 HTTPHeaderMap::const_iterator it = | |
442 response.httpHeaderFields().find(HTTPNames::X_Frame_Options); | |
443 if (it != response.httpHeaderFields().end()) { | |
444 String content = it->value; | |
445 if (frameLoader()->shouldInterruptLoadForXFrameOptions( | |
446 content, response.url(), mainResourceIdentifier())) { | |
447 String message = "Refused to display '" + | |
448 response.url().elidedString() + | |
449 "' in a frame because it set 'X-Frame-Options' to '" + | |
450 content + "'."; | |
451 ConsoleMessage* consoleMessage = ConsoleMessage::createForRequest( | |
452 SecurityMessageSource, ErrorMessageLevel, message, response.url(), | |
453 mainResourceIdentifier()); | |
454 frame()->document()->addConsoleMessage(consoleMessage); | |
455 | |
456 cancelLoadAfterXFrameOptionsOrCSPDenied(response); | |
457 return; | |
458 } | |
459 } | |
460 } | |
461 | |
462 if (RuntimeEnabledFeatures::embedderCSPEnforcementEnabled() && | 445 if (RuntimeEnabledFeatures::embedderCSPEnforcementEnabled() && |
463 !frameLoader()->requiredCSP().isEmpty()) { | 446 !frameLoader()->requiredCSP().isEmpty()) { |
464 SecurityOrigin* parentSecurityOrigin = | 447 SecurityOrigin* parentSecurityOrigin = |
465 frame()->tree().parent()->securityContext()->getSecurityOrigin(); | 448 frame()->tree().parent()->securityContext()->getSecurityOrigin(); |
466 if (ContentSecurityPolicy::shouldEnforceEmbeddersPolicy( | 449 if (ContentSecurityPolicy::shouldEnforceEmbeddersPolicy( |
467 response, parentSecurityOrigin)) { | 450 response, parentSecurityOrigin)) { |
468 m_contentSecurityPolicy->addPolicyFromHeaderValue( | 451 m_contentSecurityPolicy->addPolicyFromHeaderValue( |
469 frameLoader()->requiredCSP(), ContentSecurityPolicyHeaderTypeEnforce, | 452 frameLoader()->requiredCSP(), ContentSecurityPolicyHeaderTypeEnforce, |
470 ContentSecurityPolicyHeaderSourceHTTP); | 453 ContentSecurityPolicyHeaderSourceHTTP); |
471 } else { | 454 } else { |
472 ContentSecurityPolicy* embeddingCSP = ContentSecurityPolicy::create(); | 455 ContentSecurityPolicy* embeddingCSP = ContentSecurityPolicy::create(); |
473 embeddingCSP->addPolicyFromHeaderValue( | 456 embeddingCSP->addPolicyFromHeaderValue( |
474 frameLoader()->requiredCSP(), ContentSecurityPolicyHeaderTypeEnforce, | 457 frameLoader()->requiredCSP(), ContentSecurityPolicyHeaderTypeEnforce, |
475 ContentSecurityPolicyHeaderSourceHTTP); | 458 ContentSecurityPolicyHeaderSourceHTTP); |
476 if (!embeddingCSP->subsumes(*m_contentSecurityPolicy)) { | 459 if (!embeddingCSP->subsumes(*m_contentSecurityPolicy)) { |
477 String message = "Refused to display '" + | 460 String message = "Refused to display '" + |
478 response.url().elidedString() + | 461 response.url().elidedString() + |
479 "' because it has not opted-into the following policy " | 462 "' because it has not opted-into the following policy " |
480 "required by its embedder: '" + | 463 "required by its embedder: '" + |
481 frameLoader()->requiredCSP() + "'."; | 464 frameLoader()->requiredCSP() + "'."; |
482 ConsoleMessage* consoleMessage = ConsoleMessage::createForRequest( | 465 ConsoleMessage* consoleMessage = ConsoleMessage::createForRequest( |
483 SecurityMessageSource, ErrorMessageLevel, message, response.url(), | 466 SecurityMessageSource, ErrorMessageLevel, message, response.url(), |
484 mainResourceIdentifier()); | 467 mainResourceIdentifier()); |
485 frame()->document()->addConsoleMessage(consoleMessage); | 468 frame()->document()->addConsoleMessage(consoleMessage); |
486 cancelLoadAfterXFrameOptionsOrCSPDenied(response); | 469 cancelLoadAfterCSPDenied(response); |
487 return; | 470 return; |
488 } | 471 } |
489 } | 472 } |
490 } | 473 } |
491 | 474 |
492 DCHECK(!m_frame->page()->suspended()); | 475 DCHECK(!m_frame->page()->suspended()); |
493 | 476 |
494 m_response = response; | 477 m_response = response; |
495 | 478 |
496 if (isArchiveMIMEType(m_response.mimeType()) && | 479 if (isArchiveMIMEType(m_response.mimeType()) && |
(...skipping 304 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
801 m_writer ? m_writer->encoding() : emptyAtom, true, | 784 m_writer ? m_writer->encoding() : emptyAtom, true, |
802 ForceSynchronousParsing); | 785 ForceSynchronousParsing); |
803 if (!source.isNull()) | 786 if (!source.isNull()) |
804 m_writer->appendReplacingData(source); | 787 m_writer->appendReplacingData(source); |
805 endWriting(); | 788 endWriting(); |
806 } | 789 } |
807 | 790 |
808 DEFINE_WEAK_IDENTIFIER_MAP(DocumentLoader); | 791 DEFINE_WEAK_IDENTIFIER_MAP(DocumentLoader); |
809 | 792 |
810 } // namespace blink | 793 } // namespace blink |
OLD | NEW |