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 257 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
268 return; | 268 return; |
269 } | 269 } |
270 | 270 |
271 // We might run in to infinite recursion if we're stopping loading as the re
sult of | 271 // We might run in to infinite recursion if we're stopping loading as the re
sult of |
272 // detaching from the frame, so break out of that recursion here. | 272 // detaching from the frame, so break out of that recursion here. |
273 // See <rdar://problem/9673866> for more details. | 273 // See <rdar://problem/9673866> for more details. |
274 if (m_isStopping) | 274 if (m_isStopping) |
275 return; | 275 return; |
276 | 276 |
277 m_isStopping = true; | 277 m_isStopping = true; |
278 | |
279 FrameLoader* frameLoader = DocumentLoader::frameLoader(); | |
280 | 278 |
281 if (isLoadingMainResource()) | 279 if (isLoadingMainResource()) |
282 // Stop the main resource loader and let it send the cancelled message. | 280 // Stop the main resource loader and let it send the cancelled message. |
283 cancelMainResourceLoad(frameLoader->cancelledError(m_request)); | 281 cancelMainResourceLoad(ResourceError::cancelledError(m_request.url())); |
284 else if (!m_resourceLoaders.isEmpty()) | 282 else if (!m_resourceLoaders.isEmpty()) |
285 // The main resource loader already finished loading. Set the cancelled
error on the | 283 // The main resource loader already finished loading. Set the cancelled
error on the |
286 // document and let the resourceLoaders send individual cancelled messag
es below. | 284 // document and let the resourceLoaders send individual cancelled messag
es below. |
287 setMainDocumentError(frameLoader->cancelledError(m_request)); | 285 setMainDocumentError(ResourceError::cancelledError(m_request.url())); |
288 else | 286 else |
289 // If there are no resource loaders, we need to manufacture a cancelled
message. | 287 // If there are no resource loaders, we need to manufacture a cancelled
message. |
290 // (A back/forward navigation has no resource loaders because its resour
ces are cached.) | 288 // (A back/forward navigation has no resource loaders because its resour
ces are cached.) |
291 mainReceivedError(frameLoader->cancelledError(m_request)); | 289 mainReceivedError(ResourceError::cancelledError(m_request.url())); |
292 | 290 |
293 stopLoadingSubresources(); | 291 stopLoadingSubresources(); |
294 | 292 |
295 m_isStopping = false; | 293 m_isStopping = false; |
296 } | 294 } |
297 | 295 |
298 void DocumentLoader::commitIfReady() | 296 void DocumentLoader::commitIfReady() |
299 { | 297 { |
300 if (!m_committed) { | 298 if (!m_committed) { |
301 m_committed = true; | 299 m_committed = true; |
(...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
418 | 416 |
419 void DocumentLoader::willSendRequest(ResourceRequest& newRequest, const Resource
Response& redirectResponse) | 417 void DocumentLoader::willSendRequest(ResourceRequest& newRequest, const Resource
Response& redirectResponse) |
420 { | 418 { |
421 // Note that there are no asserts here as there are for the other callbacks.
This is due to the | 419 // Note that there are no asserts here as there are for the other callbacks.
This is due to the |
422 // fact that this "callback" is sent when starting every load, and the state
of callback | 420 // fact that this "callback" is sent when starting every load, and the state
of callback |
423 // deferrals plays less of a part in this function in preventing the bad beh
avior deferring | 421 // deferrals plays less of a part in this function in preventing the bad beh
avior deferring |
424 // callbacks is meant to prevent. | 422 // callbacks is meant to prevent. |
425 ASSERT(!newRequest.isNull()); | 423 ASSERT(!newRequest.isNull()); |
426 | 424 |
427 if (!frameLoader()->checkIfFormActionAllowedByCSP(newRequest.url())) { | 425 if (!frameLoader()->checkIfFormActionAllowedByCSP(newRequest.url())) { |
428 cancelMainResourceLoad(frameLoader()->cancelledError(newRequest)); | 426 cancelMainResourceLoad(ResourceError::cancelledError(newRequest.url())); |
429 return; | 427 return; |
430 } | 428 } |
431 | 429 |
432 ASSERT(timing()->fetchStart()); | 430 ASSERT(timing()->fetchStart()); |
433 if (!redirectResponse.isNull()) { | 431 if (!redirectResponse.isNull()) { |
434 // If the redirecting url is not allowed to display content from the tar
get origin, | 432 // If the redirecting url is not allowed to display content from the tar
get origin, |
435 // then block the redirect. | 433 // then block the redirect. |
436 RefPtr<SecurityOrigin> redirectingOrigin = SecurityOrigin::create(redire
ctResponse.url()); | 434 RefPtr<SecurityOrigin> redirectingOrigin = SecurityOrigin::create(redire
ctResponse.url()); |
437 if (!redirectingOrigin->canDisplay(newRequest.url())) { | 435 if (!redirectingOrigin->canDisplay(newRequest.url())) { |
438 FrameLoader::reportLocalLoadFailed(m_frame, newRequest.url().string(
)); | 436 FrameLoader::reportLocalLoadFailed(m_frame, newRequest.url().string(
)); |
439 cancelMainResourceLoad(frameLoader()->cancelledError(newRequest)); | 437 cancelMainResourceLoad(ResourceError::cancelledError(newRequest.url(
))); |
440 return; | 438 return; |
441 } | 439 } |
442 timing()->addRedirect(redirectResponse.url(), newRequest.url()); | 440 timing()->addRedirect(redirectResponse.url(), newRequest.url()); |
443 } | 441 } |
444 | 442 |
445 // Update cookie policy base URL as URL changes, except for subframes, which
use the | 443 // Update cookie policy base URL as URL changes, except for subframes, which
use the |
446 // URL of the main frame which doesn't change when we redirect. | 444 // URL of the main frame which doesn't change when we redirect. |
447 if (frameLoader()->isLoadingMainFrame()) | 445 if (frameLoader()->isLoadingMainFrame()) |
448 newRequest.setFirstPartyForCookies(newRequest.url()); | 446 newRequest.setFirstPartyForCookies(newRequest.url()); |
449 | 447 |
450 // If we're fielding a redirect in response to a POST, force a load from ori
gin, since | 448 // If we're fielding a redirect in response to a POST, force a load from ori
gin, since |
451 // this is a common site technique to return to a page viewing some data tha
t the POST | 449 // this is a common site technique to return to a page viewing some data tha
t the POST |
452 // just modified. | 450 // just modified. |
453 // Also, POST requests always load from origin, but this does not affect sub
resources. | 451 // Also, POST requests always load from origin, but this does not affect sub
resources. |
454 if (newRequest.cachePolicy() == UseProtocolCachePolicy && isPostOrRedirectAf
terPost(newRequest, redirectResponse)) | 452 if (newRequest.cachePolicy() == UseProtocolCachePolicy && isPostOrRedirectAf
terPost(newRequest, redirectResponse)) |
455 newRequest.setCachePolicy(ReloadIgnoringCacheData); | 453 newRequest.setCachePolicy(ReloadIgnoringCacheData); |
456 | 454 |
457 Frame* top = m_frame->tree()->top(); | 455 Frame* top = m_frame->tree()->top(); |
458 if (top != m_frame) { | 456 if (top != m_frame) { |
459 if (!frameLoader()->mixedContentChecker()->canDisplayInsecureContent(top
->document()->securityOrigin(), newRequest.url())) { | 457 if (!frameLoader()->mixedContentChecker()->canDisplayInsecureContent(top
->document()->securityOrigin(), newRequest.url())) { |
460 cancelMainResourceLoad(frameLoader()->cancelledError(newRequest)); | 458 cancelMainResourceLoad(ResourceError::cancelledError(newRequest.url(
))); |
461 return; | 459 return; |
462 } | 460 } |
463 } | 461 } |
464 | 462 |
465 setRequest(newRequest); | 463 setRequest(newRequest); |
466 | 464 |
467 if (!redirectResponse.isNull()) { | 465 if (!redirectResponse.isNull()) { |
468 // We checked application cache for initial URL, now we need to check it
for redirected one. | 466 // We checked application cache for initial URL, now we need to check it
for redirected one. |
469 ASSERT(!m_substituteData.isValid()); | 467 ASSERT(!m_substituteData.isValid()); |
470 m_applicationCacheHost->maybeLoadMainResourceForRedirect(newRequest, m_s
ubstituteData); | 468 m_applicationCacheHost->maybeLoadMainResourceForRedirect(newRequest, m_s
ubstituteData); |
(...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
559 ASSERT(m_mainResource); | 557 ASSERT(m_mainResource); |
560 unsigned long identifier = m_identifierForLoadWithoutResourceLoader ? m_
identifierForLoadWithoutResourceLoader : m_mainResource->identifier(); | 558 unsigned long identifier = m_identifierForLoadWithoutResourceLoader ? m_
identifierForLoadWithoutResourceLoader : m_mainResource->identifier(); |
561 ASSERT(identifier); | 559 ASSERT(identifier); |
562 if (frameLoader()->shouldInterruptLoadForXFrameOptions(content, response
.url(), identifier)) { | 560 if (frameLoader()->shouldInterruptLoadForXFrameOptions(content, response
.url(), identifier)) { |
563 InspectorInstrumentation::continueAfterXFrameOptionsDenied(m_frame,
this, identifier, response); | 561 InspectorInstrumentation::continueAfterXFrameOptionsDenied(m_frame,
this, identifier, response); |
564 String message = "Refused to display '" + response.url().elidedStrin
g() + "' in a frame because it set 'X-Frame-Options' to '" + content + "'."; | 562 String message = "Refused to display '" + response.url().elidedStrin
g() + "' in a frame because it set 'X-Frame-Options' to '" + content + "'."; |
565 frame()->document()->addConsoleMessage(SecurityMessageSource, ErrorM
essageLevel, message, identifier); | 563 frame()->document()->addConsoleMessage(SecurityMessageSource, ErrorM
essageLevel, message, identifier); |
566 frame()->document()->enforceSandboxFlags(SandboxOrigin); | 564 frame()->document()->enforceSandboxFlags(SandboxOrigin); |
567 if (HTMLFrameOwnerElement* ownerElement = frame()->ownerElement()) | 565 if (HTMLFrameOwnerElement* ownerElement = frame()->ownerElement()) |
568 ownerElement->dispatchEvent(Event::create(eventNames().loadEvent
, false, false)); | 566 ownerElement->dispatchEvent(Event::create(eventNames().loadEvent
, false, false)); |
569 cancelMainResourceLoad(frameLoader()->cancelledError(m_request)); | 567 cancelMainResourceLoad(ResourceError::cancelledError(m_request.url()
)); |
570 return; | 568 return; |
571 } | 569 } |
572 } | 570 } |
573 | 571 |
574 ASSERT(!mainResourceLoader() || !mainResourceLoader()->defersLoading()); | 572 ASSERT(!mainResourceLoader() || !mainResourceLoader()->defersLoading()); |
575 | 573 |
576 if (m_isLoadingMultipartContent) { | 574 if (m_isLoadingMultipartContent) { |
577 setupForReplace(); | 575 setupForReplace(); |
578 m_mainResource->clear(); | 576 m_mainResource->clear(); |
579 } else if (response.isMultipart()) { | 577 } else if (response.isMultipart()) { |
(...skipping 15 matching lines...) Expand all Loading... |
595 if (m_response.isHTTP()) { | 593 if (m_response.isHTTP()) { |
596 int status = m_response.httpStatusCode(); | 594 int status = m_response.httpStatusCode(); |
597 if (status < 200 || status >= 300) { | 595 if (status < 200 || status >= 300) { |
598 bool hostedByObject = frameLoader()->isHostedByObjectElement(); | 596 bool hostedByObject = frameLoader()->isHostedByObjectElement(); |
599 | 597 |
600 frameLoader()->handleFallbackContent(); | 598 frameLoader()->handleFallbackContent(); |
601 // object elements are no longer rendered after we fallback, so don'
t | 599 // object elements are no longer rendered after we fallback, so don'
t |
602 // keep trying to process data from their load | 600 // keep trying to process data from their load |
603 | 601 |
604 if (hostedByObject) | 602 if (hostedByObject) |
605 cancelMainResourceLoad(frameLoader()->cancelledError(m_request))
; | 603 cancelMainResourceLoad(ResourceError::cancelledError(m_request.u
rl())); |
606 } | 604 } |
607 } | 605 } |
608 | 606 |
609 if (!isStopping() && m_substituteData.isValid()) { | 607 if (!isStopping() && m_substituteData.isValid()) { |
610 if (m_substituteData.content()->size()) | 608 if (m_substituteData.content()->size()) |
611 dataReceived(0, m_substituteData.content()->data(), m_substituteData
.content()->size()); | 609 dataReceived(0, m_substituteData.content()->data(), m_substituteData
.content()->size()); |
612 if (isLoadingMainResource()) | 610 if (isLoadingMainResource()) |
613 finishedLoading(0); | 611 finishedLoading(0); |
614 } | 612 } |
615 } | 613 } |
(...skipping 12 matching lines...) Expand all Loading... |
628 | 626 |
629 commitIfReady(); | 627 commitIfReady(); |
630 FrameLoader* frameLoader = DocumentLoader::frameLoader(); | 628 FrameLoader* frameLoader = DocumentLoader::frameLoader(); |
631 if (!frameLoader) | 629 if (!frameLoader) |
632 return; | 630 return; |
633 if (isArchiveMIMEType(response().mimeType())) | 631 if (isArchiveMIMEType(response().mimeType())) |
634 return; | 632 return; |
635 frameLoader->client()->committedLoad(this, data, length); | 633 frameLoader->client()->committedLoad(this, data, length); |
636 } | 634 } |
637 | 635 |
638 ResourceError DocumentLoader::interruptedForPolicyChangeError() const | |
639 { | |
640 return frameLoader()->client()->interruptedForPolicyChangeError(request()); | |
641 } | |
642 | |
643 void DocumentLoader::stopLoadingForPolicyChange() | 636 void DocumentLoader::stopLoadingForPolicyChange() |
644 { | 637 { |
645 ResourceError error = interruptedForPolicyChangeError(); | 638 ResourceError error = frameLoader()->client()->interruptedForPolicyChangeErr
or(m_request); |
646 error.setIsCancellation(true); | 639 error.setIsCancellation(true); |
647 cancelMainResourceLoad(error); | 640 cancelMainResourceLoad(error); |
648 } | 641 } |
649 | 642 |
650 void DocumentLoader::commitData(const char* bytes, size_t length) | 643 void DocumentLoader::commitData(const char* bytes, size_t length) |
651 { | 644 { |
652 if (!m_gotFirstByte) { | 645 if (!m_gotFirstByte) { |
653 m_gotFirstByte = true; | 646 m_gotFirstByte = true; |
654 m_writer.begin(documentURL(), false); | 647 m_writer.begin(documentURL(), false); |
655 m_writer.setDocumentWasLoadedAsPartOfNavigation(); | 648 m_writer.setDocumentWasLoadedAsPartOfNavigation(); |
(...skipping 233 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
889 if (m_frame->page()->defersLoading()) | 882 if (m_frame->page()->defersLoading()) |
890 return; | 883 return; |
891 | 884 |
892 SubstituteResourceMap copy; | 885 SubstituteResourceMap copy; |
893 copy.swap(m_pendingSubstituteResources); | 886 copy.swap(m_pendingSubstituteResources); |
894 | 887 |
895 SubstituteResourceMap::const_iterator end = copy.end(); | 888 SubstituteResourceMap::const_iterator end = copy.end(); |
896 for (SubstituteResourceMap::const_iterator it = copy.begin(); it != end; ++i
t) { | 889 for (SubstituteResourceMap::const_iterator it = copy.begin(); it != end; ++i
t) { |
897 RefPtr<ResourceLoader> loader = it->key; | 890 RefPtr<ResourceLoader> loader = it->key; |
898 SubstituteResource* resource = it->value.get(); | 891 SubstituteResource* resource = it->value.get(); |
| 892 ASSERT(resource); |
899 | 893 |
900 if (resource) { | 894 if (resource) { |
901 SharedBuffer* data = resource->data(); | 895 SharedBuffer* data = resource->data(); |
902 | 896 |
903 loader->didReceiveResponse(0, resource->response()); | 897 loader->didReceiveResponse(0, resource->response()); |
904 | 898 |
905 // Calling ResourceLoader::didReceiveResponse can end up cancelling
the load, | 899 // Calling ResourceLoader::didReceiveResponse can end up cancelling
the load, |
906 // so we need to check if the loader has reached its terminal state. | 900 // so we need to check if the loader has reached its terminal state. |
907 if (loader->reachedTerminalState()) | 901 if (loader->reachedTerminalState()) |
908 return; | 902 return; |
909 | 903 |
910 loader->didReceiveData(0, data->data(), data->size(), data->size()); | 904 loader->didReceiveData(0, data->data(), data->size(), data->size()); |
911 | 905 |
912 // Calling ResourceLoader::didReceiveData can end up cancelling the
load, | 906 // Calling ResourceLoader::didReceiveData can end up cancelling the
load, |
913 // so we need to check if the loader has reached its terminal state. | 907 // so we need to check if the loader has reached its terminal state. |
914 if (loader->reachedTerminalState()) | 908 if (loader->reachedTerminalState()) |
915 return; | 909 return; |
916 | 910 |
917 loader->didFinishLoading(0, 0); | 911 loader->didFinishLoading(0, 0); |
918 } else { | |
919 // A null resource means that we should fail the load. | |
920 // FIXME: Maybe we should use another error here - something like "n
ot in cache". | |
921 loader->didFail(0, loader->cannotShowURLError()); | |
922 } | 912 } |
923 } | 913 } |
924 } | 914 } |
925 | 915 |
926 #ifndef NDEBUG | 916 #ifndef NDEBUG |
927 bool DocumentLoader::isSubstituteLoadPending(ResourceLoader* loader) const | 917 bool DocumentLoader::isSubstituteLoadPending(ResourceLoader* loader) const |
928 { | 918 { |
929 return m_pendingSubstituteResources.contains(loader); | 919 return m_pendingSubstituteResources.contains(loader); |
930 } | 920 } |
931 #endif | 921 #endif |
(...skipping 198 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1130 // If there was a fragment identifier on m_request, the cache will have stri
pped it. m_request should include | 1120 // If there was a fragment identifier on m_request, the cache will have stri
pped it. m_request should include |
1131 // the fragment identifier, so add that back in. | 1121 // the fragment identifier, so add that back in. |
1132 if (equalIgnoringFragmentIdentifier(m_request.url(), request.url())) | 1122 if (equalIgnoringFragmentIdentifier(m_request.url(), request.url())) |
1133 request.setURL(m_request.url()); | 1123 request.setURL(m_request.url()); |
1134 setRequest(request); | 1124 setRequest(request); |
1135 } | 1125 } |
1136 | 1126 |
1137 void DocumentLoader::cancelMainResourceLoad(const ResourceError& resourceError) | 1127 void DocumentLoader::cancelMainResourceLoad(const ResourceError& resourceError) |
1138 { | 1128 { |
1139 RefPtr<DocumentLoader> protect(this); | 1129 RefPtr<DocumentLoader> protect(this); |
1140 ResourceError error = resourceError.isNull() ? frameLoader()->cancelledError
(m_request) : resourceError; | 1130 ResourceError error = resourceError.isNull() ? ResourceError::cancelledError
(m_request.url()) : resourceError; |
1141 | 1131 |
1142 m_dataLoadTimer.stop(); | 1132 m_dataLoadTimer.stop(); |
1143 if (mainResourceLoader()) | 1133 if (mainResourceLoader()) |
1144 mainResourceLoader()->cancel(error); | 1134 mainResourceLoader()->cancel(error); |
1145 | 1135 |
1146 mainReceivedError(error); | 1136 mainReceivedError(error); |
1147 } | 1137 } |
1148 | 1138 |
1149 void DocumentLoader::subresourceLoaderFinishedLoadingOnePart(ResourceLoader* loa
der) | 1139 void DocumentLoader::subresourceLoaderFinishedLoadingOnePart(ResourceLoader* loa
der) |
1150 { | 1140 { |
(...skipping 15 matching lines...) Expand all Loading... |
1166 commitLoad(resourceData->data(), resourceData->size()); | 1156 commitLoad(resourceData->data(), resourceData->size()); |
1167 } | 1157 } |
1168 | 1158 |
1169 void DocumentLoader::handledOnloadEvents() | 1159 void DocumentLoader::handledOnloadEvents() |
1170 { | 1160 { |
1171 m_wasOnloadHandled = true; | 1161 m_wasOnloadHandled = true; |
1172 applicationCacheHost()->stopDeferringEvents(); | 1162 applicationCacheHost()->stopDeferringEvents(); |
1173 } | 1163 } |
1174 | 1164 |
1175 } // namespace WebCore | 1165 } // namespace WebCore |
OLD | NEW |