Changeset 146216 in webkit
- Timestamp:
- Mar 19, 2013, 10:08:17 AM (12 years ago)
- Location:
- trunk/Source/WebCore
- Files:
-
- 5 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/WebCore/ChangeLog
r146215 r146216 1 2013-03-19 Nate Chapin <japhet@chromium.org> 2 3 Merge MainResourceLoader::responseReceived into DocumentLoader 4 https://bugs.webkit.org/show_bug.cgi?id=112593 5 6 Part of the ongoing effort to merge MainResourceLoader entirely 7 into DocumentLoader. 8 9 Reviewed by Adam Barth. 10 11 No new tests, refactor only. 12 13 * loader/DocumentLoader.cpp: 14 (WebCore::DocumentLoader::DocumentLoader): 15 (WebCore::DocumentLoader::stopLoading): 16 (WebCore::DocumentLoader::finishedLoading): The only thing left in 17 MainResourceLoader related to this function was a RefPtr which indirectly 18 protected DocumentLoader. Move the RefPtr here and protect DocumentLoader directly. 19 (WebCore::DocumentLoader::responseReceived): Moved from MainResourceLoader. 20 (WebCore::DocumentLoader::callContinueAfterContentPolicy): Moved from MainResourceLoader. 21 (WebCore::DocumentLoader::continueAfterContentPolicy): Moved from MainResourceLoader. 22 (WebCore::DocumentLoader::interruptedForPolicyChangeError): Moved from MainResourceLoader. 23 (WebCore::DocumentLoader::stopLoadingForPolicyChange): Moved from MainResourceLoader. 24 (WebCore::DocumentLoader::receivedData): 25 (WebCore::DocumentLoader::cancelMainResourceLoad): 26 * loader/DocumentLoader.h: 27 (WebCore::DocumentLoader::isLoadingMultipartContent): Store multipart bit here. 28 * loader/MainResourceLoader.cpp: 29 (WebCore::MainResourceLoader::MainResourceLoader): 30 (WebCore::MainResourceLoader::cancel): 31 (WebCore::MainResourceLoader::responseReceived): 32 (WebCore::MainResourceLoader::notifyFinished): 33 * loader/MainResourceLoader.h: 34 1 35 2013-03-19 Tony Chang <tony@chromium.org> 2 36 -
trunk/Source/WebCore/loader/DocumentLoader.cpp
r145973 r146216 106 106 , m_gotFirstByte(false) 107 107 , m_isClientRedirect(false) 108 , m_isLoadingMultipartContent(false) 108 109 , m_loadingEmptyDocument(false) 109 110 , m_wasOnloadHandled(false) … … 112 113 , m_didCreateGlobalHistoryEntry(false) 113 114 , m_timeOfLastDataReceived(0.0) 115 , m_waitingForContentPolicy(false) 114 116 , m_applicationCacheHost(adoptPtr(new ApplicationCacheHost(this))) 115 117 { … … 277 279 if (m_mainResourceLoader) 278 280 // Stop the main resource loader and let it send the cancelled message. 279 m_mainResourceLoader->cancel( );281 m_mainResourceLoader->cancel(frameLoader->cancelledError(m_request)); 280 282 else if (!m_subresourceLoaders.isEmpty()) 281 283 // The main resource loader already finished loading. Set the cancelled error on the … … 321 323 #endif 322 324 325 RefPtr<DocumentLoader> protect(this); 326 323 327 if (m_mainResourceLoader && m_mainResourceLoader->identifierForLoadWithoutResourceLoader()) { 324 328 frameLoader()->notifier()->dispatchDidFinishLoading(this, m_mainResourceLoader->identifier(), finishTime); … … 458 462 { 459 463 if (!shouldContinue) 460 m_mainResourceLoader->stopLoadingForPolicyChange();464 stopLoadingForPolicyChange(); 461 465 else if (m_substituteData.isValid()) { 462 466 // A redirect resulted in loading substitute data. … … 480 484 void DocumentLoader::responseReceived(const ResourceResponse& response) 481 485 { 486 bool willLoadFallback = m_applicationCacheHost->maybeLoadFallbackForMainResponse(request(), response); 487 488 // The memory cache doesn't understand the application cache or its caching rules. So if a main resource is served 489 // from the application cache, ensure we don't save the result for future use. 490 bool shouldRemoveResourceFromCache = willLoadFallback; 491 #if PLATFORM(CHROMIUM) 492 // chromium's ApplicationCacheHost implementation always returns true for maybeLoadFallbackForMainResponse(). However, all responses loaded 493 // from appcache will have a non-zero appCacheID(). 494 if (response.appCacheID()) 495 shouldRemoveResourceFromCache = true; 496 #endif 497 if (shouldRemoveResourceFromCache) 498 memoryCache()->remove(m_mainResourceLoader->cachedMainResource()); 499 500 if (willLoadFallback) 501 return; 502 503 DEFINE_STATIC_LOCAL(AtomicString, xFrameOptionHeader, ("x-frame-options", AtomicString::ConstructFromLiteral)); 504 HTTPHeaderMap::const_iterator it = response.httpHeaderFields().find(xFrameOptionHeader); 505 if (it != response.httpHeaderFields().end()) { 506 String content = it->value; 507 unsigned long identifier = m_mainResourceLoader->identifier(); 508 if (frameLoader()->shouldInterruptLoadForXFrameOptions(content, response.url(), identifier)) { 509 InspectorInstrumentation::continueAfterXFrameOptionsDenied(m_frame, this, identifier, response); 510 String message = "Refused to display '" + response.url().elidedString() + "' in a frame because it set 'X-Frame-Options' to '" + content + "'."; 511 frame()->document()->addConsoleMessage(SecurityMessageSource, ErrorMessageLevel, message, identifier); 512 cancelMainResourceLoad(frameLoader()->cancelledError(m_request)); 513 return; 514 } 515 } 516 517 // There is a bug in CFNetwork where callbacks can be dispatched even when loads are deferred. 518 // See <rdar://problem/6304600> for more details. 519 #if !USE(CF) 520 ASSERT(!m_frame->page()->defersLoading()); 521 #endif 522 523 if (m_isLoadingMultipartContent) { 524 setupForReplace(); 525 m_mainResourceLoader->cachedMainResource()->clear(); 526 } else if (response.isMultipart()) { 527 FeatureObserver::observe(m_frame->document(), FeatureObserver::MultipartMainResource); 528 m_isLoadingMultipartContent = true; 529 } 530 482 531 setResponse(response); 532 533 if (m_mainResourceLoader->identifierForLoadWithoutResourceLoader()) 534 frameLoader()->notifier()->dispatchDidReceiveResponse(this, m_mainResourceLoader->identifierForLoadWithoutResourceLoader(), m_response, 0); 535 536 ASSERT(!m_waitingForContentPolicy); 537 m_waitingForContentPolicy = true; 538 539 // Always show content with valid substitute data. 540 if (m_substituteData.isValid()) { 541 continueAfterContentPolicy(PolicyUse); 542 return; 543 } 544 545 #if ENABLE(FTPDIR) 546 // Respect the hidden FTP Directory Listing pref so it can be tested even if the policy delegate might otherwise disallow it 547 Settings* settings = m_frame->settings(); 548 if (settings && settings->forceFTPDirectoryListings() && m_response.mimeType() == "application/x-ftp-directory") { 549 continueAfterContentPolicy(PolicyUse); 550 return; 551 } 552 #endif 483 553 484 554 #if USE(CONTENT_FILTERING) … … 487 557 #endif 488 558 559 frameLoader()->policyChecker()->checkContentPolicy(m_response, callContinueAfterContentPolicy, this); 560 } 561 562 void DocumentLoader::callContinueAfterContentPolicy(void* argument, PolicyAction policy) 563 { 564 static_cast<DocumentLoader*>(argument)->continueAfterContentPolicy(policy); 565 } 566 567 void DocumentLoader::continueAfterContentPolicy(PolicyAction policy) 568 { 569 ASSERT(m_waitingForContentPolicy); 570 m_waitingForContentPolicy = false; 571 if (isStopping()) 572 return; 573 574 KURL url = m_request.url(); 575 const String& mimeType = m_response.mimeType(); 576 577 switch (policy) { 578 case PolicyUse: { 579 // Prevent remote web archives from loading because they can claim to be from any domain and thus avoid cross-domain security checks (4120255). 580 bool isRemoteWebArchive = (equalIgnoringCase("application/x-webarchive", mimeType) 581 #if PLATFORM(GTK) 582 || equalIgnoringCase("message/rfc822", mimeType) 583 #endif 584 || equalIgnoringCase("multipart/related", mimeType)) 585 && !m_substituteData.isValid() && !SchemeRegistry::shouldTreatURLSchemeAsLocal(url.protocol()); 586 if (!frameLoader()->client()->canShowMIMEType(mimeType) || isRemoteWebArchive) { 587 frameLoader()->policyChecker()->cannotShowMIMEType(m_response); 588 // Check reachedTerminalState since the load may have already been canceled inside of _handleUnimplementablePolicyWithErrorCode::. 589 stopLoadingForPolicyChange(); 590 return; 591 } 592 break; 593 } 594 595 case PolicyDownload: { 596 // The main CachedResource can be null, e.g. when loading a substitute resource from application cache. 597 if (!m_mainResourceLoader->cachedMainResource()) { 598 mainReceivedError(frameLoader()->client()->cannotShowURLError(m_request)); 599 return; 600 } 601 InspectorInstrumentation::continueWithPolicyDownload(m_frame, this, mainResourceLoader()->identifier(), m_response); 602 603 // When starting the request, we didn't know that it would result in download and not navigation. Now we know that main document URL didn't change. 604 // Download may use this knowledge for purposes unrelated to cookies, notably for setting file quarantine data. 605 frameLoader()->setOriginalURLForDownloadRequest(m_request); 606 frameLoader()->client()->convertMainResourceLoadToDownload(this, m_request, m_response); 607 608 // It might have gone missing 609 if (mainResourceLoader()) 610 mainResourceLoader()->didFail(interruptedForPolicyChangeError()); 611 return; 612 } 613 case PolicyIgnore: 614 InspectorInstrumentation::continueWithPolicyIgnore(m_frame, this, mainResourceLoader()->identifier(), m_response); 615 stopLoadingForPolicyChange(); 616 return; 617 618 default: 619 ASSERT_NOT_REACHED(); 620 } 621 622 if (m_response.isHTTP()) { 623 int status = m_response.httpStatusCode(); 624 if (status < 200 || status >= 300) { 625 bool hostedByObject = frameLoader()->isHostedByObjectElement(); 626 627 frameLoader()->handleFallbackContent(); 628 // object elements are no longer rendered after we fallback, so don't 629 // keep trying to process data from their load 630 631 if (hostedByObject) 632 cancelMainResourceLoad(frameLoader()->cancelledError(m_request)); 633 } 634 } 635 636 if (!isStopping() && m_substituteData.isValid()) { 637 if (m_substituteData.content()->size()) 638 receivedData(m_substituteData.content()->data(), m_substituteData.content()->size()); 639 if (isLoadingMainResource()) 640 finishedLoading(0); 641 } 489 642 } 490 643 … … 505 658 #endif 506 659 frameLoader->client()->committedLoad(this, data, length); 660 } 661 662 ResourceError DocumentLoader::interruptedForPolicyChangeError() const 663 { 664 return frameLoader()->client()->interruptedForPolicyChangeError(request()); 665 } 666 667 void DocumentLoader::stopLoadingForPolicyChange() 668 { 669 ResourceError error = interruptedForPolicyChangeError(); 670 error.setIsCancellation(true); 671 cancelMainResourceLoad(error); 507 672 } 508 673 … … 627 792 #if USE(CONTENT_FILTERING) 628 793 if (loadWasBlockedBeforeFinishing) 629 cancelMainResourceLoad( ResourceError());794 cancelMainResourceLoad(frameLoader()->cancelledError(m_request)); 630 795 #endif 631 796 } … … 1099 1264 } 1100 1265 1101 bool DocumentLoader::isLoadingMultipartContent() const1102 {1103 return m_mainResourceLoader && m_mainResourceLoader->isLoadingMultipartContent();1104 }1105 1106 1266 bool DocumentLoader::isMultipartReplacingLoad() const 1107 1267 { … … 1166 1326 void DocumentLoader::cancelMainResourceLoad(const ResourceError& error) 1167 1327 { 1328 ASSERT(!error.isNull()); 1329 1330 if (m_waitingForContentPolicy) { 1331 frameLoader()->policyChecker()->cancelCheck(); 1332 ASSERT(m_waitingForContentPolicy); 1333 m_waitingForContentPolicy = false; 1334 } 1168 1335 m_mainResourceLoader->cancel(error); 1169 1336 } -
trunk/Source/WebCore/loader/DocumentLoader.h
r145973 r146216 213 213 214 214 bool isLoadingMainResource() const; 215 bool isLoadingMultipartContent() const ;215 bool isLoadingMultipartContent() const { return m_isLoadingMultipartContent; } 216 216 217 217 void stopLoadingPlugIns(); … … 286 286 void continueAfterNavigationPolicy(const ResourceRequest&, bool shouldContinue); 287 287 288 static void callContinueAfterContentPolicy(void*, PolicyAction); 289 void continueAfterContentPolicy(PolicyAction); 290 291 void stopLoadingForPolicyChange(); 292 ResourceError interruptedForPolicyChangeError() const; 293 288 294 void deliverSubstituteResourcesAfterDelay(); 289 295 void substituteResourceDeliveryTimerFired(Timer<DocumentLoader>*); … … 326 332 bool m_gotFirstByte; 327 333 bool m_isClientRedirect; 334 bool m_isLoadingMultipartContent; 328 335 bool m_loadingEmptyDocument; 329 336 … … 369 376 370 377 double m_timeOfLastDataReceived; 378 379 bool m_waitingForContentPolicy; 371 380 372 381 RefPtr<IconLoadDecisionCallback> m_iconLoadDecisionCallback; -
trunk/Source/WebCore/loader/MainResourceLoader.cpp
r145973 r146216 69 69 : m_dataLoadTimer(this, &MainResourceLoader::handleSubstituteDataLoadNow) 70 70 , m_documentLoader(documentLoader) 71 , m_loadingMultipartContent(false)72 , m_waitingForContentPolicy(false)73 71 , m_identifierForLoadWithoutResourceLoader(0) 74 72 { … … 114 112 115 113 m_dataLoadTimer.stop(); 116 117 if (m_waitingForContentPolicy) {118 frameLoader()->policyChecker()->cancelCheck();119 ASSERT(m_waitingForContentPolicy);120 m_waitingForContentPolicy = false;121 deref(); // balances ref in responseReceived122 }123 124 114 if (loader()) 125 115 loader()->cancel(resourceError); … … 147 137 } 148 138 149 ResourceError MainResourceLoader::interruptedForPolicyChangeError() const150 {151 return frameLoader()->client()->interruptedForPolicyChangeError(request());152 }153 154 void MainResourceLoader::stopLoadingForPolicyChange()155 {156 ResourceError error = interruptedForPolicyChangeError();157 error.setIsCancellation(true);158 cancel(error);159 }160 161 139 PassRefPtr<ResourceBuffer> MainResourceLoader::resourceData() 162 140 { … … 172 150 } 173 151 174 void MainResourceLoader::continueAfterContentPolicy(PolicyAction contentPolicy, const ResourceResponse& r)175 {176 KURL url = request().url();177 const String& mimeType = r.mimeType();178 179 switch (contentPolicy) {180 case PolicyUse: {181 // Prevent remote web archives from loading because they can claim to be from any domain and thus avoid cross-domain security checks (4120255).182 bool isRemoteWebArchive = (equalIgnoringCase("application/x-webarchive", mimeType)183 #if PLATFORM(GTK)184 || equalIgnoringCase("message/rfc822", mimeType)185 #endif186 || equalIgnoringCase("multipart/related", mimeType))187 && !m_documentLoader->substituteData().isValid() && !SchemeRegistry::shouldTreatURLSchemeAsLocal(url.protocol());188 if (!frameLoader()->client()->canShowMIMEType(mimeType) || isRemoteWebArchive) {189 frameLoader()->policyChecker()->cannotShowMIMEType(r);190 // Check reachedTerminalState since the load may have already been canceled inside of _handleUnimplementablePolicyWithErrorCode::.191 stopLoadingForPolicyChange();192 return;193 }194 break;195 }196 197 case PolicyDownload: {198 // m_resource can be null, e.g. when loading a substitute resource from application cache.199 if (!m_resource) {200 receivedError(frameLoader()->client()->cannotShowURLError(request()));201 return;202 }203 InspectorInstrumentation::continueWithPolicyDownload(m_documentLoader->frame(), documentLoader(), identifier(), r);204 205 // When starting the request, we didn't know that it would result in download and not navigation. Now we know that main document URL didn't change.206 // Download may use this knowledge for purposes unrelated to cookies, notably for setting file quarantine data.207 ResourceRequest request = this->request();208 frameLoader()->setOriginalURLForDownloadRequest(request);209 210 frameLoader()->client()->convertMainResourceLoadToDownload(documentLoader(), request, r);211 212 // It might have gone missing213 if (loader())214 loader()->didFail(interruptedForPolicyChangeError());215 return;216 }217 case PolicyIgnore:218 InspectorInstrumentation::continueWithPolicyIgnore(m_documentLoader->frame(), documentLoader(), identifier(), r);219 stopLoadingForPolicyChange();220 return;221 222 default:223 ASSERT_NOT_REACHED();224 }225 226 RefPtr<MainResourceLoader> protect(this);227 228 if (r.isHTTP()) {229 int status = r.httpStatusCode();230 if (status < 200 || status >= 300) {231 bool hostedByObject = frameLoader()->isHostedByObjectElement();232 233 frameLoader()->handleFallbackContent();234 // object elements are no longer rendered after we fallback, so don't235 // keep trying to process data from their load236 237 if (hostedByObject)238 cancel();239 }240 }241 242 if (!m_documentLoader->isStopping() && m_documentLoader->substituteData().isValid()) {243 if (m_documentLoader->substituteData().content()->size())244 dataReceived(0, m_documentLoader->substituteData().content()->data(), m_documentLoader->substituteData().content()->size());245 if (m_documentLoader->isLoadingMainResource())246 didFinishLoading(0);247 }248 }249 250 void MainResourceLoader::callContinueAfterContentPolicy(void* argument, PolicyAction policy)251 {252 static_cast<MainResourceLoader*>(argument)->continueAfterContentPolicy(policy);253 }254 255 void MainResourceLoader::continueAfterContentPolicy(PolicyAction policy)256 {257 ASSERT(m_waitingForContentPolicy);258 m_waitingForContentPolicy = false;259 if (!m_documentLoader->isStopping())260 continueAfterContentPolicy(policy, m_response);261 deref(); // balances ref in responseReceived262 }263 264 152 void MainResourceLoader::responseReceived(CachedResource* resource, const ResourceResponse& r) 265 153 { 266 154 ASSERT_UNUSED(resource, m_resource == resource); 267 bool willLoadFallback = documentLoader()->applicationCacheHost()->maybeLoadFallbackForMainResponse(request(), r);268 269 // The memory cache doesn't understand the application cache or its caching rules. So if a main resource is served270 // from the application cache, ensure we don't save the result for future use.271 bool shouldRemoveResourceFromCache = willLoadFallback;272 #if PLATFORM(CHROMIUM)273 // chromium's ApplicationCacheHost implementation always returns true for maybeLoadFallbackForMainResponse(). However, all responses loaded274 // from appcache will have a non-zero appCacheID().275 if (r.appCacheID())276 shouldRemoveResourceFromCache = true;277 #endif278 if (shouldRemoveResourceFromCache)279 memoryCache()->remove(m_resource.get());280 281 if (willLoadFallback)282 return;283 284 DEFINE_STATIC_LOCAL(AtomicString, xFrameOptionHeader, ("x-frame-options", AtomicString::ConstructFromLiteral));285 HTTPHeaderMap::const_iterator it = r.httpHeaderFields().find(xFrameOptionHeader);286 if (it != r.httpHeaderFields().end()) {287 String content = it->value;288 if (frameLoader()->shouldInterruptLoadForXFrameOptions(content, r.url(), identifier())) {289 InspectorInstrumentation::continueAfterXFrameOptionsDenied(m_documentLoader->frame(), documentLoader(), identifier(), r);290 String message = "Refused to display '" + r.url().elidedString() + "' in a frame because it set 'X-Frame-Options' to '" + content + "'.";291 m_documentLoader->frame()->document()->addConsoleMessage(SecurityMessageSource, ErrorMessageLevel, message, identifier());292 293 cancel();294 return;295 }296 }297 298 // There is a bug in CFNetwork where callbacks can be dispatched even when loads are deferred.299 // See <rdar://problem/6304600> for more details.300 #if !USE(CF)301 ASSERT(!defersLoading());302 #endif303 304 if (m_loadingMultipartContent) {305 m_documentLoader->setupForReplace();306 m_resource->clear();307 }308 309 if (r.isMultipart()) {310 FeatureObserver::observe(m_documentLoader->frame()->document(), FeatureObserver::MultipartMainResource);311 m_loadingMultipartContent = true;312 }313 314 // The additional processing can do anything including possibly removing the last315 // reference to this object; one example of this is 3266216.316 RefPtr<MainResourceLoader> protect(this);317 318 155 m_documentLoader->responseReceived(r); 319 320 m_response = r;321 322 if (m_identifierForLoadWithoutResourceLoader)323 frameLoader()->notifier()->dispatchDidReceiveResponse(documentLoader(), identifier(), m_response, 0);324 325 ASSERT(!m_waitingForContentPolicy);326 m_waitingForContentPolicy = true;327 ref(); // balanced by deref in continueAfterContentPolicy and cancel328 329 // Always show content with valid substitute data.330 if (m_documentLoader->substituteData().isValid()) {331 callContinueAfterContentPolicy(this, PolicyUse);332 return;333 }334 335 #if ENABLE(FTPDIR)336 // Respect the hidden FTP Directory Listing pref so it can be tested even if the policy delegate might otherwise disallow it337 Settings* settings = m_documentLoader->frame()->settings();338 if (settings && settings->forceFTPDirectoryListings() && m_response.mimeType() == "application/x-ftp-directory") {339 callContinueAfterContentPolicy(this, PolicyUse);340 return;341 }342 #endif343 344 frameLoader()->policyChecker()->checkContentPolicy(m_response, callContinueAfterContentPolicy, this);345 156 } 346 157 … … 349 160 ASSERT_UNUSED(resource, resource == m_resource); 350 161 documentLoader()->receivedData(data, length); 351 }352 353 void MainResourceLoader::didFinishLoading(double finishTime)354 {355 // The additional processing can do anything including possibly removing the last356 // reference to this object.357 RefPtr<MainResourceLoader> protect(this);358 documentLoader()->finishedLoading(finishTime);359 162 } 360 163 … … 364 167 ASSERT(m_resource); 365 168 if (!m_resource->errorOccurred() && !m_resource->wasCanceled()) { 366 d idFinishLoading(m_resource->loadFinishTime());169 documentLoader()->finishedLoading(m_resource->loadFinishTime()); 367 170 return; 368 171 } -
trunk/Source/WebCore/loader/MainResourceLoader.h
r145973 r146216 73 73 74 74 unsigned long identifier() const; 75 bool isLoadingMultipartContent() const { return m_loadingMultipartContent; }76 75 77 76 void reportMemoryUsage(MemoryObjectInfo*) const; 78 77 79 78 void takeIdentifierFromResourceLoader() { m_identifierForLoadWithoutResourceLoader = identifier(); } 80 void stopLoadingForPolicyChange();81 79 void handleSubstituteDataLoadSoon(const ResourceRequest&); 82 80 void clearResource(); … … 90 88 virtual void notifyFinished(CachedResource*) OVERRIDE; 91 89 92 void didFinishLoading(double finishTime);93 90 void handleSubstituteDataLoadNow(MainResourceLoaderTimer*); 94 91 … … 96 93 97 94 void receivedError(const ResourceError&); 98 ResourceError interruptedForPolicyChangeError() const;99 100 static void callContinueAfterContentPolicy(void*, PolicyAction);101 void continueAfterContentPolicy(PolicyAction);102 void continueAfterContentPolicy(PolicyAction, const ResourceResponse&);103 95 104 96 #if PLATFORM(QT) … … 116 108 117 109 ResourceRequest m_initialRequest; 118 ResourceResponse m_response;119 110 120 111 MainResourceLoaderTimer m_dataLoadTimer; 121 112 RefPtr<DocumentLoader> m_documentLoader; 122 113 123 bool m_loadingMultipartContent;124 bool m_waitingForContentPolicy;125 114 unsigned long m_identifierForLoadWithoutResourceLoader; 126 115 };
Note:
See TracChangeset
for help on using the changeset viewer.