Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(178)

Side by Side Diff: Source/WebCore/loader/DocumentLoader.cpp

Issue 14264012: Create errors (especially cancellation errors) internally to WebCore, rather (Closed) Base URL: svn://svn.chromium.org/blink/trunk/
Patch Set: Created 7 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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 258 matching lines...) Expand 10 before | Expand all | Expand 10 after
269 return; 269 return;
270 } 270 }
271 271
272 // We might run in to infinite recursion if we're stopping loading as the re sult of 272 // We might run in to infinite recursion if we're stopping loading as the re sult of
273 // detaching from the frame, so break out of that recursion here. 273 // detaching from the frame, so break out of that recursion here.
274 // See <rdar://problem/9673866> for more details. 274 // See <rdar://problem/9673866> for more details.
275 if (m_isStopping) 275 if (m_isStopping)
276 return; 276 return;
277 277
278 m_isStopping = true; 278 m_isStopping = true;
279
280 FrameLoader* frameLoader = DocumentLoader::frameLoader();
281 279
282 if (isLoadingMainResource()) 280 if (isLoadingMainResource())
283 // Stop the main resource loader and let it send the cancelled message. 281 // Stop the main resource loader and let it send the cancelled message.
284 cancelMainResourceLoad(frameLoader->cancelledError(m_request)); 282 cancelMainResourceLoad(ResourceError::createCancelledError(m_request.url ()));
285 else if (!m_resourceLoaders.isEmpty()) 283 else if (!m_resourceLoaders.isEmpty())
286 // The main resource loader already finished loading. Set the cancelled error on the 284 // The main resource loader already finished loading. Set the cancelled error on the
287 // document and let the resourceLoaders send individual cancelled messag es below. 285 // document and let the resourceLoaders send individual cancelled messag es below.
288 setMainDocumentError(frameLoader->cancelledError(m_request)); 286 setMainDocumentError(ResourceError::createCancelledError(m_request.url() ));
289 else 287 else
290 // If there are no resource loaders, we need to manufacture a cancelled message. 288 // If there are no resource loaders, we need to manufacture a cancelled message.
291 // (A back/forward navigation has no resource loaders because its resour ces are cached.) 289 // (A back/forward navigation has no resource loaders because its resour ces are cached.)
292 mainReceivedError(frameLoader->cancelledError(m_request)); 290 mainReceivedError(ResourceError::createCancelledError(m_request.url()));
293 291
294 stopLoadingSubresources(); 292 stopLoadingSubresources();
295 293
296 m_isStopping = false; 294 m_isStopping = false;
297 } 295 }
298 296
299 void DocumentLoader::commitIfReady() 297 void DocumentLoader::commitIfReady()
300 { 298 {
301 if (!m_committed) { 299 if (!m_committed) {
302 m_committed = true; 300 m_committed = true;
(...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after
419 417
420 void DocumentLoader::willSendRequest(ResourceRequest& newRequest, const Resource Response& redirectResponse) 418 void DocumentLoader::willSendRequest(ResourceRequest& newRequest, const Resource Response& redirectResponse)
421 { 419 {
422 // Note that there are no asserts here as there are for the other callbacks. This is due to the 420 // Note that there are no asserts here as there are for the other callbacks. This is due to the
423 // fact that this "callback" is sent when starting every load, and the state of callback 421 // fact that this "callback" is sent when starting every load, and the state of callback
424 // deferrals plays less of a part in this function in preventing the bad beh avior deferring 422 // deferrals plays less of a part in this function in preventing the bad beh avior deferring
425 // callbacks is meant to prevent. 423 // callbacks is meant to prevent.
426 ASSERT(!newRequest.isNull()); 424 ASSERT(!newRequest.isNull());
427 425
428 if (!frameLoader()->checkIfFormActionAllowedByCSP(newRequest.url())) { 426 if (!frameLoader()->checkIfFormActionAllowedByCSP(newRequest.url())) {
429 cancelMainResourceLoad(frameLoader()->cancelledError(newRequest)); 427 cancelMainResourceLoad(ResourceError::createCancelledError(newRequest.ur l()));
430 return; 428 return;
431 } 429 }
432 430
433 ASSERT(timing()->fetchStart()); 431 ASSERT(timing()->fetchStart());
434 if (!redirectResponse.isNull()) { 432 if (!redirectResponse.isNull()) {
435 // If the redirecting url is not allowed to display content from the tar get origin, 433 // If the redirecting url is not allowed to display content from the tar get origin,
436 // then block the redirect. 434 // then block the redirect.
437 RefPtr<SecurityOrigin> redirectingOrigin = SecurityOrigin::create(redire ctResponse.url()); 435 RefPtr<SecurityOrigin> redirectingOrigin = SecurityOrigin::create(redire ctResponse.url());
438 if (!redirectingOrigin->canDisplay(newRequest.url())) { 436 if (!redirectingOrigin->canDisplay(newRequest.url())) {
439 FrameLoader::reportLocalLoadFailed(m_frame, newRequest.url().string( )); 437 FrameLoader::reportLocalLoadFailed(m_frame, newRequest.url().string( ));
440 cancelMainResourceLoad(frameLoader()->cancelledError(newRequest)); 438 cancelMainResourceLoad(ResourceError::createCancelledError(newReques t.url()));
441 return; 439 return;
442 } 440 }
443 timing()->addRedirect(redirectResponse.url(), newRequest.url()); 441 timing()->addRedirect(redirectResponse.url(), newRequest.url());
444 } 442 }
445 443
446 // Update cookie policy base URL as URL changes, except for subframes, which use the 444 // Update cookie policy base URL as URL changes, except for subframes, which use the
447 // URL of the main frame which doesn't change when we redirect. 445 // URL of the main frame which doesn't change when we redirect.
448 if (frameLoader()->isLoadingMainFrame()) 446 if (frameLoader()->isLoadingMainFrame())
449 newRequest.setFirstPartyForCookies(newRequest.url()); 447 newRequest.setFirstPartyForCookies(newRequest.url());
450 448
451 // If we're fielding a redirect in response to a POST, force a load from ori gin, since 449 // If we're fielding a redirect in response to a POST, force a load from ori gin, since
452 // this is a common site technique to return to a page viewing some data tha t the POST 450 // this is a common site technique to return to a page viewing some data tha t the POST
453 // just modified. 451 // just modified.
454 // Also, POST requests always load from origin, but this does not affect sub resources. 452 // Also, POST requests always load from origin, but this does not affect sub resources.
455 if (newRequest.cachePolicy() == UseProtocolCachePolicy && isPostOrRedirectAf terPost(newRequest, redirectResponse)) 453 if (newRequest.cachePolicy() == UseProtocolCachePolicy && isPostOrRedirectAf terPost(newRequest, redirectResponse))
456 newRequest.setCachePolicy(ReloadIgnoringCacheData); 454 newRequest.setCachePolicy(ReloadIgnoringCacheData);
457 455
458 Frame* top = m_frame->tree()->top(); 456 Frame* top = m_frame->tree()->top();
459 if (top != m_frame) { 457 if (top != m_frame) {
460 if (!frameLoader()->mixedContentChecker()->canDisplayInsecureContent(top ->document()->securityOrigin(), newRequest.url())) { 458 if (!frameLoader()->mixedContentChecker()->canDisplayInsecureContent(top ->document()->securityOrigin(), newRequest.url())) {
461 cancelMainResourceLoad(frameLoader()->cancelledError(newRequest)); 459 cancelMainResourceLoad(ResourceError::createCancelledError(newReques t.url()));
462 return; 460 return;
463 } 461 }
464 } 462 }
465 463
466 setRequest(newRequest); 464 setRequest(newRequest);
467 465
468 if (!redirectResponse.isNull()) { 466 if (!redirectResponse.isNull()) {
469 // We checked application cache for initial URL, now we need to check it for redirected one. 467 // We checked application cache for initial URL, now we need to check it for redirected one.
470 ASSERT(!m_substituteData.isValid()); 468 ASSERT(!m_substituteData.isValid());
471 m_applicationCacheHost->maybeLoadMainResourceForRedirect(newRequest, m_s ubstituteData); 469 m_applicationCacheHost->maybeLoadMainResourceForRedirect(newRequest, m_s ubstituteData);
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after
532 ASSERT(m_mainResource); 530 ASSERT(m_mainResource);
533 unsigned long identifier = m_identifierForLoadWithoutResourceLoader ? m_ identifierForLoadWithoutResourceLoader : m_mainResource->identifier(); 531 unsigned long identifier = m_identifierForLoadWithoutResourceLoader ? m_ identifierForLoadWithoutResourceLoader : m_mainResource->identifier();
534 ASSERT(identifier); 532 ASSERT(identifier);
535 if (frameLoader()->shouldInterruptLoadForXFrameOptions(content, response .url(), identifier)) { 533 if (frameLoader()->shouldInterruptLoadForXFrameOptions(content, response .url(), identifier)) {
536 InspectorInstrumentation::continueAfterXFrameOptionsDenied(m_frame, this, identifier, response); 534 InspectorInstrumentation::continueAfterXFrameOptionsDenied(m_frame, this, identifier, response);
537 String message = "Refused to display '" + response.url().elidedStrin g() + "' in a frame because it set 'X-Frame-Options' to '" + content + "'."; 535 String message = "Refused to display '" + response.url().elidedStrin g() + "' in a frame because it set 'X-Frame-Options' to '" + content + "'.";
538 frame()->document()->addConsoleMessage(SecurityMessageSource, ErrorM essageLevel, message, identifier); 536 frame()->document()->addConsoleMessage(SecurityMessageSource, ErrorM essageLevel, message, identifier);
539 frame()->document()->enforceSandboxFlags(SandboxOrigin); 537 frame()->document()->enforceSandboxFlags(SandboxOrigin);
540 if (HTMLFrameOwnerElement* ownerElement = frame()->ownerElement()) 538 if (HTMLFrameOwnerElement* ownerElement = frame()->ownerElement())
541 ownerElement->dispatchEvent(Event::create(eventNames().loadEvent , false, false)); 539 ownerElement->dispatchEvent(Event::create(eventNames().loadEvent , false, false));
542 cancelMainResourceLoad(frameLoader()->cancelledError(m_request)); 540 cancelMainResourceLoad(ResourceError::createCancelledError(m_request .url()));
543 return; 541 return;
544 } 542 }
545 } 543 }
546 544
547 ASSERT(!mainResourceLoader() || !mainResourceLoader()->defersLoading()); 545 ASSERT(!mainResourceLoader() || !mainResourceLoader()->defersLoading());
548 546
549 if (m_isLoadingMultipartContent) { 547 if (m_isLoadingMultipartContent) {
550 setupForReplace(); 548 setupForReplace();
551 m_mainResource->clear(); 549 m_mainResource->clear();
552 } else if (response.isMultipart()) { 550 } else if (response.isMultipart()) {
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
585 583
586 KURL url = m_request.url(); 584 KURL url = m_request.url();
587 const String& mimeType = m_response.mimeType(); 585 const String& mimeType = m_response.mimeType();
588 586
589 switch (policy) { 587 switch (policy) {
590 case PolicyUse: { 588 case PolicyUse: {
591 // Prevent remote web archives from loading because they can claim to be from any domain and thus avoid cross-domain security checks (4120255). 589 // Prevent remote web archives from loading because they can claim to be from any domain and thus avoid cross-domain security checks (4120255).
592 bool isRemoteWebArchive = equalIgnoringCase("multipart/related", mimeTyp e) 590 bool isRemoteWebArchive = equalIgnoringCase("multipart/related", mimeTyp e)
593 && !m_substituteData.isValid() && !SchemeRegistry::shouldTreatURLSch emeAsLocal(url.protocol()); 591 && !m_substituteData.isValid() && !SchemeRegistry::shouldTreatURLSch emeAsLocal(url.protocol());
594 if (!frameLoader()->client()->canShowMIMEType(mimeType) || isRemoteWebAr chive) { 592 if (!frameLoader()->client()->canShowMIMEType(mimeType) || isRemoteWebAr chive) {
595 frameLoader()->policyChecker()->cannotShowMIMEType(m_response); 593 ASSERT_NOT_REACHED();
596 // Check reachedTerminalState since the load may have already been c anceled inside of _handleUnimplementablePolicyWithErrorCode::.
597 stopLoadingForPolicyChange(); 594 stopLoadingForPolicyChange();
598 return; 595 return;
599 } 596 }
600 break; 597 break;
601 } 598 }
602 599
603 case PolicyDownload: { 600 case PolicyDownload: {
604 // m_mainResource can be null, e.g. when loading a substitute resource f rom application cache. 601 ASSERT(m_mainResource);
605 if (!m_mainResource) {
606 mainReceivedError(frameLoader()->client()->cannotShowURLError(m_requ est));
607 return;
608 }
609 InspectorInstrumentation::continueWithPolicyDownload(m_frame, this, main ResourceLoader()->identifier(), m_response); 602 InspectorInstrumentation::continueWithPolicyDownload(m_frame, this, main ResourceLoader()->identifier(), m_response);
610 603
611 // When starting the request, we didn't know that it would result in dow nload and not navigation. Now we know that main document URL didn't change. 604 // When starting the request, we didn't know that it would result in dow nload and not navigation. Now we know that main document URL didn't change.
612 // Download may use this knowledge for purposes unrelated to cookies, no tably for setting file quarantine data. 605 // Download may use this knowledge for purposes unrelated to cookies, no tably for setting file quarantine data.
613 frameLoader()->setOriginalURLForDownloadRequest(m_request); 606 frameLoader()->setOriginalURLForDownloadRequest(m_request);
614 return; 607 return;
615 } 608 }
616 case PolicyIgnore: 609 case PolicyIgnore:
617 InspectorInstrumentation::continueWithPolicyIgnore(m_frame, this, mainRe sourceLoader()->identifier(), m_response); 610 InspectorInstrumentation::continueWithPolicyIgnore(m_frame, this, mainRe sourceLoader()->identifier(), m_response);
618 stopLoadingForPolicyChange(); 611 stopLoadingForPolicyChange();
619 return; 612 return;
620 613
621 default: 614 default:
622 ASSERT_NOT_REACHED(); 615 ASSERT_NOT_REACHED();
623 } 616 }
624 617
625 if (m_response.isHTTP()) { 618 if (m_response.isHTTP()) {
626 int status = m_response.httpStatusCode(); 619 int status = m_response.httpStatusCode();
627 if (status < 200 || status >= 300) { 620 if (status < 200 || status >= 300) {
628 bool hostedByObject = frameLoader()->isHostedByObjectElement(); 621 bool hostedByObject = frameLoader()->isHostedByObjectElement();
629 622
630 frameLoader()->handleFallbackContent(); 623 frameLoader()->handleFallbackContent();
631 // object elements are no longer rendered after we fallback, so don' t 624 // object elements are no longer rendered after we fallback, so don' t
632 // keep trying to process data from their load 625 // keep trying to process data from their load
633 626
634 if (hostedByObject) 627 if (hostedByObject)
635 cancelMainResourceLoad(frameLoader()->cancelledError(m_request)) ; 628 cancelMainResourceLoad(ResourceError::createCancelledError(m_req uest.url()));
636 } 629 }
637 } 630 }
638 631
639 if (!isStopping() && m_substituteData.isValid()) { 632 if (!isStopping() && m_substituteData.isValid()) {
640 if (m_substituteData.content()->size()) 633 if (m_substituteData.content()->size())
641 dataReceived(0, m_substituteData.content()->data(), m_substituteData .content()->size()); 634 dataReceived(0, m_substituteData.content()->data(), m_substituteData .content()->size());
642 if (isLoadingMainResource()) 635 if (isLoadingMainResource())
643 finishedLoading(0); 636 finishedLoading(0);
644 } 637 }
645 } 638 }
(...skipping 12 matching lines...) Expand all
658 651
659 commitIfReady(); 652 commitIfReady();
660 FrameLoader* frameLoader = DocumentLoader::frameLoader(); 653 FrameLoader* frameLoader = DocumentLoader::frameLoader();
661 if (!frameLoader) 654 if (!frameLoader)
662 return; 655 return;
663 if (isArchiveMIMEType(response().mimeType())) 656 if (isArchiveMIMEType(response().mimeType()))
664 return; 657 return;
665 frameLoader->client()->committedLoad(this, data, length); 658 frameLoader->client()->committedLoad(this, data, length);
666 } 659 }
667 660
668 ResourceError DocumentLoader::interruptedForPolicyChangeError() const
669 {
670 return frameLoader()->client()->interruptedForPolicyChangeError(request());
671 }
672
673 void DocumentLoader::stopLoadingForPolicyChange() 661 void DocumentLoader::stopLoadingForPolicyChange()
674 { 662 {
675 ResourceError error = interruptedForPolicyChangeError(); 663 ResourceError error = ResourceError::createPolicyChangeError(m_request.url() );
676 error.setIsCancellation(true); 664 error.setIsCancellation(true);
677 cancelMainResourceLoad(error); 665 cancelMainResourceLoad(error);
678 } 666 }
679 667
680 void DocumentLoader::commitData(const char* bytes, size_t length) 668 void DocumentLoader::commitData(const char* bytes, size_t length)
681 { 669 {
682 if (!m_gotFirstByte) { 670 if (!m_gotFirstByte) {
683 m_gotFirstByte = true; 671 m_gotFirstByte = true;
684 m_writer.begin(documentURL(), false); 672 m_writer.begin(documentURL(), false);
685 m_writer.setDocumentWasLoadedAsPartOfNavigation(); 673 m_writer.setDocumentWasLoadedAsPartOfNavigation();
(...skipping 233 matching lines...) Expand 10 before | Expand all | Expand 10 after
919 if (m_frame->page()->defersLoading()) 907 if (m_frame->page()->defersLoading())
920 return; 908 return;
921 909
922 SubstituteResourceMap copy; 910 SubstituteResourceMap copy;
923 copy.swap(m_pendingSubstituteResources); 911 copy.swap(m_pendingSubstituteResources);
924 912
925 SubstituteResourceMap::const_iterator end = copy.end(); 913 SubstituteResourceMap::const_iterator end = copy.end();
926 for (SubstituteResourceMap::const_iterator it = copy.begin(); it != end; ++i t) { 914 for (SubstituteResourceMap::const_iterator it = copy.begin(); it != end; ++i t) {
927 RefPtr<ResourceLoader> loader = it->key; 915 RefPtr<ResourceLoader> loader = it->key;
928 SubstituteResource* resource = it->value.get(); 916 SubstituteResource* resource = it->value.get();
917 ASSERT(resource);
929 918
930 if (resource) { 919 if (resource) {
931 SharedBuffer* data = resource->data(); 920 SharedBuffer* data = resource->data();
932 921
933 loader->didReceiveResponse(0, resource->response()); 922 loader->didReceiveResponse(0, resource->response());
934 923
935 // Calling ResourceLoader::didReceiveResponse can end up cancelling the load, 924 // Calling ResourceLoader::didReceiveResponse can end up cancelling the load,
936 // so we need to check if the loader has reached its terminal state. 925 // so we need to check if the loader has reached its terminal state.
937 if (loader->reachedTerminalState()) 926 if (loader->reachedTerminalState())
938 return; 927 return;
939 928
940 loader->didReceiveData(0, data->data(), data->size(), data->size()); 929 loader->didReceiveData(0, data->data(), data->size(), data->size());
941 930
942 // Calling ResourceLoader::didReceiveData can end up cancelling the load, 931 // Calling ResourceLoader::didReceiveData can end up cancelling the load,
943 // so we need to check if the loader has reached its terminal state. 932 // so we need to check if the loader has reached its terminal state.
944 if (loader->reachedTerminalState()) 933 if (loader->reachedTerminalState())
945 return; 934 return;
946 935
947 loader->didFinishLoading(0, 0); 936 loader->didFinishLoading(0, 0);
948 } else {
949 // A null resource means that we should fail the load.
950 // FIXME: Maybe we should use another error here - something like "n ot in cache".
951 loader->didFail(0, loader->cannotShowURLError());
952 } 937 }
953 } 938 }
954 } 939 }
955 940
956 #ifndef NDEBUG 941 #ifndef NDEBUG
957 bool DocumentLoader::isSubstituteLoadPending(ResourceLoader* loader) const 942 bool DocumentLoader::isSubstituteLoadPending(ResourceLoader* loader) const
958 { 943 {
959 return m_pendingSubstituteResources.contains(loader); 944 return m_pendingSubstituteResources.contains(loader);
960 } 945 }
961 #endif 946 #endif
(...skipping 198 matching lines...) Expand 10 before | Expand all | Expand 10 after
1160 // If there was a fragment identifier on m_request, the cache will have stri pped it. m_request should include 1145 // If there was a fragment identifier on m_request, the cache will have stri pped it. m_request should include
1161 // the fragment identifier, so add that back in. 1146 // the fragment identifier, so add that back in.
1162 if (equalIgnoringFragmentIdentifier(m_request.url(), request.url())) 1147 if (equalIgnoringFragmentIdentifier(m_request.url(), request.url()))
1163 request.setURL(m_request.url()); 1148 request.setURL(m_request.url());
1164 setRequest(request); 1149 setRequest(request);
1165 } 1150 }
1166 1151
1167 void DocumentLoader::cancelMainResourceLoad(const ResourceError& resourceError) 1152 void DocumentLoader::cancelMainResourceLoad(const ResourceError& resourceError)
1168 { 1153 {
1169 RefPtr<DocumentLoader> protect(this); 1154 RefPtr<DocumentLoader> protect(this);
1170 ResourceError error = resourceError.isNull() ? frameLoader()->cancelledError (m_request) : resourceError; 1155 ResourceError error = resourceError.isNull() ? ResourceError::createCancelle dError(m_request.url()) : resourceError;
1171 1156
1172 m_dataLoadTimer.stop(); 1157 m_dataLoadTimer.stop();
1173 if (m_waitingForContentPolicy) { 1158 if (m_waitingForContentPolicy) {
1174 frameLoader()->policyChecker()->cancelCheck(); 1159 frameLoader()->policyChecker()->cancelCheck();
1175 ASSERT(m_waitingForContentPolicy); 1160 ASSERT(m_waitingForContentPolicy);
1176 m_waitingForContentPolicy = false; 1161 m_waitingForContentPolicy = false;
1177 } 1162 }
1178 1163
1179 if (mainResourceLoader()) 1164 if (mainResourceLoader())
1180 mainResourceLoader()->cancel(error); 1165 mainResourceLoader()->cancel(error);
(...skipping 21 matching lines...) Expand all
1202 commitLoad(resourceData->data(), resourceData->size()); 1187 commitLoad(resourceData->data(), resourceData->size());
1203 } 1188 }
1204 1189
1205 void DocumentLoader::handledOnloadEvents() 1190 void DocumentLoader::handledOnloadEvents()
1206 { 1191 {
1207 m_wasOnloadHandled = true; 1192 m_wasOnloadHandled = true;
1208 applicationCacheHost()->stopDeferringEvents(); 1193 applicationCacheHost()->stopDeferringEvents();
1209 } 1194 }
1210 1195
1211 } // namespace WebCore 1196 } // namespace WebCore
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698