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 94 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
105 m_substituteData(substituteData), | 105 m_substituteData(substituteData), |
106 m_request(req), | 106 m_request(req), |
107 m_isClientRedirect(clientRedirectPolicy == | 107 m_isClientRedirect(clientRedirectPolicy == |
108 ClientRedirectPolicy::ClientRedirect), | 108 ClientRedirectPolicy::ClientRedirect), |
109 m_replacesCurrentHistoryItem(false), | 109 m_replacesCurrentHistoryItem(false), |
110 m_dataReceived(false), | 110 m_dataReceived(false), |
111 m_navigationType(NavigationTypeOther), | 111 m_navigationType(NavigationTypeOther), |
112 m_documentLoadTiming(*this), | 112 m_documentLoadTiming(*this), |
113 m_timeOfLastDataReceived(0.0), | 113 m_timeOfLastDataReceived(0.0), |
114 m_applicationCacheHost(ApplicationCacheHost::create(this)), | 114 m_applicationCacheHost(ApplicationCacheHost::create(this)), |
115 m_wasBlockedAfterXFrameOptionsOrCSP(false), | 115 m_wasBlockedAfterCSP(false), |
116 m_state(NotStarted), | 116 m_state(NotStarted), |
117 m_inDataReceived(false), | 117 m_inDataReceived(false), |
118 m_dataBuffer(SharedBuffer::create()) { | 118 m_dataBuffer(SharedBuffer::create()) { |
119 // The document URL needs to be added to the head of the list as that is | 119 // The document URL needs to be added to the head of the list as that is |
120 // where the redirects originated. | 120 // where the redirects originated. |
121 if (m_isClientRedirect) | 121 if (m_isClientRedirect) |
122 appendRedirect(m_frame->document()->url()); | 122 appendRedirect(m_frame->document()->url()); |
123 } | 123 } |
124 | 124 |
125 FrameLoader* DocumentLoader::frameLoader() const { | 125 FrameLoader* DocumentLoader::frameLoader() const { |
(...skipping 153 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
279 DCHECK(m_mainResource); | 279 DCHECK(m_mainResource); |
280 | 280 |
281 if (!m_mainResource->errorOccurred() && !m_mainResource->wasCanceled()) { | 281 if (!m_mainResource->errorOccurred() && !m_mainResource->wasCanceled()) { |
282 finishedLoading(m_mainResource->loadFinishTime()); | 282 finishedLoading(m_mainResource->loadFinishTime()); |
283 return; | 283 return; |
284 } | 284 } |
285 | 285 |
286 if (m_applicationCacheHost) | 286 if (m_applicationCacheHost) |
287 m_applicationCacheHost->failedLoadingMainResource(); | 287 m_applicationCacheHost->failedLoadingMainResource(); |
288 m_state = MainResourceDone; | 288 m_state = MainResourceDone; |
| 289 |
| 290 if (m_mainResource->resourceError().wasBlockedByResponse()) { |
| 291 InspectorInstrumentation::canceledAfterReceivedResourceResponse( |
| 292 m_frame, this, mainResourceIdentifier(), resource->response(), |
| 293 m_mainResource.get()); |
| 294 } |
| 295 |
289 frameLoader()->loadFailed(this, m_mainResource->resourceError()); | 296 frameLoader()->loadFailed(this, m_mainResource->resourceError()); |
290 clearMainResourceHandle(); | 297 clearMainResourceHandle(); |
291 } | 298 } |
292 | 299 |
293 void DocumentLoader::finishedLoading(double finishTime) { | 300 void DocumentLoader::finishedLoading(double finishTime) { |
294 DCHECK(m_frame->loader().stateMachine()->creatingInitialEmptyDocument() || | 301 DCHECK(m_frame->loader().stateMachine()->creatingInitialEmptyDocument() || |
295 !m_frame->page()->suspended() || | 302 !m_frame->page()->suspended() || |
296 InspectorInstrumentation::isDebuggerPaused(m_frame)); | 303 InspectorInstrumentation::isDebuggerPaused(m_frame)); |
297 | 304 |
298 double responseEndTime = finishTime; | 305 double responseEndTime = finishTime; |
(...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
395 // Downloading is handled by the embedder, but we still get the initial | 402 // Downloading is handled by the embedder, but we still get the initial |
396 // response so that we can ignore it and clean up properly. | 403 // response so that we can ignore it and clean up properly. |
397 return false; | 404 return false; |
398 } | 405 } |
399 | 406 |
400 if (!canShowMIMEType(m_response.mimeType(), m_frame)) | 407 if (!canShowMIMEType(m_response.mimeType(), m_frame)) |
401 return false; | 408 return false; |
402 return true; | 409 return true; |
403 } | 410 } |
404 | 411 |
405 void DocumentLoader::cancelLoadAfterXFrameOptionsOrCSPDenied( | 412 void DocumentLoader::cancelLoadAfterCSPDenied( |
406 const ResourceResponse& response) { | 413 const ResourceResponse& response) { |
407 InspectorInstrumentation::continueAfterXFrameOptionsDenied( | 414 InspectorInstrumentation::canceledAfterReceivedResourceResponse( |
408 m_frame, this, mainResourceIdentifier(), response, m_mainResource.get()); | 415 m_frame, this, mainResourceIdentifier(), response, m_mainResource.get()); |
409 | 416 |
410 setWasBlockedAfterXFrameOptionsOrCSP(); | 417 setWasBlockedAfterCSP(); |
411 | 418 |
412 // Pretend that this was an empty HTTP 200 response. Don't reuse the original | 419 // Pretend that this was an empty HTTP 200 response. Don't reuse the original |
413 // URL for the empty page (https://crbug.com/622385). | 420 // URL for the empty page (https://crbug.com/622385). |
414 // | 421 // |
415 // TODO(mkwst): Remove this once XFO moves to the browser. | 422 // TODO(mkwst): Remove this once XFO moves to the browser. |
416 // https://crbug.com/555418. | 423 // https://crbug.com/555418. |
417 clearMainResourceHandle(); | 424 clearMainResourceHandle(); |
418 m_contentSecurityPolicy.clear(); | 425 m_contentSecurityPolicy.clear(); |
419 KURL blockedURL = SecurityOrigin::urlWithUniqueSecurityOrigin(); | 426 KURL blockedURL = SecurityOrigin::urlWithUniqueSecurityOrigin(); |
420 m_originalRequest.setURL(blockedURL); | 427 m_originalRequest.setURL(blockedURL); |
(...skipping 21 matching lines...) Expand all Loading... |
442 // we don't save the result for future use. All responses loaded from appcache | 449 // we don't save the result for future use. All responses loaded from appcache |
443 // will have a non-zero appCacheID(). | 450 // will have a non-zero appCacheID(). |
444 if (response.appCacheID()) | 451 if (response.appCacheID()) |
445 memoryCache()->remove(m_mainResource.get()); | 452 memoryCache()->remove(m_mainResource.get()); |
446 | 453 |
447 m_contentSecurityPolicy = ContentSecurityPolicy::create(); | 454 m_contentSecurityPolicy = ContentSecurityPolicy::create(); |
448 m_contentSecurityPolicy->setOverrideURLForSelf(response.url()); | 455 m_contentSecurityPolicy->setOverrideURLForSelf(response.url()); |
449 m_contentSecurityPolicy->didReceiveHeaders( | 456 m_contentSecurityPolicy->didReceiveHeaders( |
450 ContentSecurityPolicyResponseHeaders(response)); | 457 ContentSecurityPolicyResponseHeaders(response)); |
451 if (!m_contentSecurityPolicy->allowAncestors(m_frame, response.url())) { | 458 if (!m_contentSecurityPolicy->allowAncestors(m_frame, response.url())) { |
452 cancelLoadAfterXFrameOptionsOrCSPDenied(response); | 459 cancelLoadAfterCSPDenied(response); |
453 return; | 460 return; |
454 } | 461 } |
455 | 462 |
456 // 'frame-ancestors' obviates 'x-frame-options': | |
457 // https://w3c.github.io/webappsec/specs/content-security-policy/#frame-ancest
ors-and-frame-options | |
458 if (!m_contentSecurityPolicy->isFrameAncestorsEnforced()) { | |
459 HTTPHeaderMap::const_iterator it = | |
460 response.httpHeaderFields().find(HTTPNames::X_Frame_Options); | |
461 if (it != response.httpHeaderFields().end()) { | |
462 String content = it->value; | |
463 if (frameLoader()->shouldInterruptLoadForXFrameOptions( | |
464 content, response.url(), mainResourceIdentifier())) { | |
465 String message = "Refused to display '" + | |
466 response.url().elidedString() + | |
467 "' in a frame because it set 'X-Frame-Options' to '" + | |
468 content + "'."; | |
469 ConsoleMessage* consoleMessage = ConsoleMessage::createForRequest( | |
470 SecurityMessageSource, ErrorMessageLevel, message, response.url(), | |
471 mainResourceIdentifier()); | |
472 frame()->document()->addConsoleMessage(consoleMessage); | |
473 | |
474 cancelLoadAfterXFrameOptionsOrCSPDenied(response); | |
475 return; | |
476 } | |
477 } | |
478 } | |
479 | |
480 if (RuntimeEnabledFeatures::embedderCSPEnforcementEnabled() && | 463 if (RuntimeEnabledFeatures::embedderCSPEnforcementEnabled() && |
481 !frameLoader()->requiredCSP().isEmpty()) { | 464 !frameLoader()->requiredCSP().isEmpty()) { |
482 SecurityOrigin* parentSecurityOrigin = | 465 SecurityOrigin* parentSecurityOrigin = |
483 frame()->tree().parent()->securityContext()->getSecurityOrigin(); | 466 frame()->tree().parent()->securityContext()->getSecurityOrigin(); |
484 if (ContentSecurityPolicy::shouldEnforceEmbeddersPolicy( | 467 if (ContentSecurityPolicy::shouldEnforceEmbeddersPolicy( |
485 response, parentSecurityOrigin)) { | 468 response, parentSecurityOrigin)) { |
486 m_contentSecurityPolicy->addPolicyFromHeaderValue( | 469 m_contentSecurityPolicy->addPolicyFromHeaderValue( |
487 frameLoader()->requiredCSP(), ContentSecurityPolicyHeaderTypeEnforce, | 470 frameLoader()->requiredCSP(), ContentSecurityPolicyHeaderTypeEnforce, |
488 ContentSecurityPolicyHeaderSourceHTTP); | 471 ContentSecurityPolicyHeaderSourceHTTP); |
489 } else { | 472 } else { |
490 ContentSecurityPolicy* embeddingCSP = ContentSecurityPolicy::create(); | 473 ContentSecurityPolicy* embeddingCSP = ContentSecurityPolicy::create(); |
491 embeddingCSP->addPolicyFromHeaderValue( | 474 embeddingCSP->addPolicyFromHeaderValue( |
492 frameLoader()->requiredCSP(), ContentSecurityPolicyHeaderTypeEnforce, | 475 frameLoader()->requiredCSP(), ContentSecurityPolicyHeaderTypeEnforce, |
493 ContentSecurityPolicyHeaderSourceHTTP); | 476 ContentSecurityPolicyHeaderSourceHTTP); |
494 if (!embeddingCSP->subsumes(*m_contentSecurityPolicy)) { | 477 if (!embeddingCSP->subsumes(*m_contentSecurityPolicy)) { |
495 String message = "Refused to display '" + | 478 String message = "Refused to display '" + |
496 response.url().elidedString() + | 479 response.url().elidedString() + |
497 "' because it has not opted-into the following policy " | 480 "' because it has not opted-into the following policy " |
498 "required by its embedder: '" + | 481 "required by its embedder: '" + |
499 frameLoader()->requiredCSP() + "'."; | 482 frameLoader()->requiredCSP() + "'."; |
500 ConsoleMessage* consoleMessage = ConsoleMessage::createForRequest( | 483 ConsoleMessage* consoleMessage = ConsoleMessage::createForRequest( |
501 SecurityMessageSource, ErrorMessageLevel, message, response.url(), | 484 SecurityMessageSource, ErrorMessageLevel, message, response.url(), |
502 mainResourceIdentifier()); | 485 mainResourceIdentifier()); |
503 frame()->document()->addConsoleMessage(consoleMessage); | 486 frame()->document()->addConsoleMessage(consoleMessage); |
504 cancelLoadAfterXFrameOptionsOrCSPDenied(response); | 487 cancelLoadAfterCSPDenied(response); |
505 return; | 488 return; |
506 } | 489 } |
507 } | 490 } |
508 } | 491 } |
509 | 492 |
510 DCHECK(!m_frame->page()->suspended()); | 493 DCHECK(!m_frame->page()->suspended()); |
511 | 494 |
512 m_response = response; | 495 m_response = response; |
513 | 496 |
514 if (isArchiveMIMEType(m_response.mimeType()) && | 497 if (isArchiveMIMEType(m_response.mimeType()) && |
(...skipping 302 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
817 m_writer ? m_writer->encoding() : emptyAtom, true, | 800 m_writer ? m_writer->encoding() : emptyAtom, true, |
818 ForceSynchronousParsing); | 801 ForceSynchronousParsing); |
819 if (!source.isNull()) | 802 if (!source.isNull()) |
820 m_writer->appendReplacingData(source); | 803 m_writer->appendReplacingData(source); |
821 endWriting(); | 804 endWriting(); |
822 } | 805 } |
823 | 806 |
824 DEFINE_WEAK_IDENTIFIER_MAP(DocumentLoader); | 807 DEFINE_WEAK_IDENTIFIER_MAP(DocumentLoader); |
825 | 808 |
826 } // namespace blink | 809 } // namespace blink |
OLD | NEW |