Changeset 138962 in webkit
- Timestamp:
- Jan 7, 2013 10:40:55 AM (11 years ago)
- Location:
- trunk/Source/WebCore
- Files:
-
- 15 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/WebCore/ChangeLog
r138960 r138962 1 2013-01-04 Alexey Proskuryakov <ap@apple.com> 2 3 ResourceHandle::willLoadFromCache is evil 4 https://bugs.webkit.org/show_bug.cgi?id=106147 5 6 Reviewed by Brady Eidson. 7 8 For back/forward navigations to a page that's a result of form submission, we may 9 never silently re-submit the form. So, we show a warning dialog when about to re-submit, 10 but try to load from cache if possible. 11 12 This patch changes the logic so that we always try to fetch from cache, without 13 any preflighting. If cache load fails, we restart the load as a known re-submit. 14 15 No behavior change expected, so no tests. 16 17 * html/HTMLAnchorElement.cpp: (WebCore::HTMLAnchorElement::handleClick): 18 Added a FIXME. 19 20 * loader/DocumentLoader.cpp: (WebCore::DocumentLoader::startLoadingMainResource): 21 Amended a FIXME with some information about why this call may still be needed. 22 23 * loader/FrameLoader.h: 24 * loader/FrameLoader.cpp: 25 (WebCore::FrameLoader::loadURLIntoChildFrame): Pass an explicit argument for unchanged caching behavior. 26 (WebCore::FrameLoader::reloadWithOverrideEncoding): Added a FIXME. This function 27 can silently re-submit a form. 28 (WebCore::FrameLoader::addExtraFieldsToMainResourceRequest): Added a FIXME about 29 an incorrect use of current load type. 30 (WebCore::FrameLoader::addExtraFieldsToRequest): Make sure that a correct caching 31 policy is used for subresources even if main resource was loaded from cache. We 32 didn't need that before because initial request had wrong extra fields due to a use 33 of m_loadType when it was first called. 34 Removed code to change caching policy for b/f navigations. This function does not 35 have enough context to decide what the policy should be. 36 (WebCore::FrameLoader::loadDifferentDocumentItem): Added an argument telling the 37 function whether it should attempt loading from cache. It should do that on first 38 attempt to navigate to a form submission result, but not if that failed. 39 Pass a correct loadType - m_loadType is one for _previous_ load. 40 Removed a special case for https - we've long stopped prohibiting caching of https 41 resources, and using a resource that's already cached should definitely be allowed. 42 (WebCore::FrameLoader::loadItem): Pass an explicit argument for unchanged caching behavior. 43 (WebCore::FrameLoader::retryAfterFailedCacheOnlyMainResourceLoad): Added. 44 45 * loader/MainResourceLoader.cpp: (WebCore::MainResourceLoader::notifyFinished): 46 Removed a check for m_resource being null, because we were immediately dereferencing 47 it anyway. 48 Call retryAfterFailedCacheOnlyMainResourceLoad() to let FrameLoader restart the navigation. 49 50 * platform/network/ResourceHandle.h: 51 * platform/network/blackberry/ResourceHandleBlackBerry.cpp: 52 * platform/network/cf/ResourceHandleCFNet.cpp: 53 * platform/network/chromium/ResourceHandle.cpp: 54 * platform/network/curl/ResourceHandleCurl.cpp: 55 * platform/network/mac/ResourceHandleMac.mm: 56 * platform/network/qt/ResourceHandleQt.cpp: 57 * platform/network/soup/ResourceHandleSoup.cpp: 58 * platform/network/win/ResourceHandleWin.cpp: 59 Removed willLoadFromCache() - the new logic is cross-platform. 60 1 61 2013-01-07 Alberto Garcia <agarcia@igalia.com> 2 62 -
trunk/Source/WebCore/html/HTMLAnchorElement.cpp
r135690 r138962 513 513 ResourceRequest request(kurl); 514 514 515 // FIXME: Why are we not calling addExtraFieldsToMainResourceRequest() if this check fails? It sets many important header fields. 515 516 if (!hasRel(RelationNoReferrer)) { 516 517 String referrer = SecurityPolicy::generateReferrerHeader(document()->referrerPolicy(), kurl, frame->loader()->outgoingReferrer()); -
trunk/Source/WebCore/loader/DocumentLoader.cpp
r138926 r138962 885 885 // FIXME: Is there any way the extra fields could have not been added by now? 886 886 // If not, it would be great to remove this line of code. 887 // Note that currently, some requests may have incorrect extra fields even if this function has been called, 888 // because we pass a wrong loadType (see FIXME in addExtraFieldsToMainResourceRequest()). 887 889 frameLoader()->addExtraFieldsToMainResourceRequest(m_request); 888 890 m_mainResourceLoader->load(m_request, m_substituteData); -
trunk/Source/WebCore/loader/FrameLoader.cpp
r137573 r138962 853 853 HistoryItem* childItem = parentItem->childItemWithTarget(childFrame->tree()->uniqueName()); 854 854 if (childItem) { 855 childFrame->loader()->loadDifferentDocumentItem(childItem, loadType() );855 childFrame->loader()->loadDifferentDocumentItem(childItem, loadType(), MayAttemptCacheOnlyLoadForFormSubmissionItem); 856 856 return; 857 857 } … … 1462 1462 request.setURL(unreachableURL); 1463 1463 1464 // FIXME: If the resource is a result of form submission and is not cached, the form will be silently resubmitted. 1465 // We should ask the user for confirmation in this case. 1464 1466 request.setCachePolicy(ReturnCacheDataElseLoad); 1465 1467 … … 2419 2421 void FrameLoader::addExtraFieldsToMainResourceRequest(ResourceRequest& request) 2420 2422 { 2423 // FIXME: Using m_loadType seems wrong for some callers. 2424 // If we are only preparing to load the main resource, that is previous load's load type! 2421 2425 addExtraFieldsToRequest(request, m_loadType, true); 2422 2426 } … … 2425 2429 { 2426 2430 // Don't set the cookie policy URL if it's already been set. 2427 // But make sure to set it on all requests , as it has significance beyond the cookie policy for all protocols(<rdar://problem/6616664>).2431 // But make sure to set it on all requests regardless of protocol, as it has significance beyond the cookie policy (<rdar://problem/6616664>). 2428 2432 if (request.firstPartyForCookies().isEmpty()) { 2429 2433 if (mainResource && isLoadingMainFrame()) … … 2438 2442 2439 2443 applyUserAgent(request); 2440 2441 // If we inherit cache policy from a main resource, we use the DocumentLoader's 2442 // original request cache policy for two reasons: 2443 // 1. For POST requests, we mutate the cache policy for the main resource, 2444 // but we do not want this to apply to subresources 2445 // 2. Delegates that modify the cache policy using willSendRequest: should 2446 // not affect any other resources. Such changes need to be done 2447 // per request. 2444 2448 2445 if (!mainResource) { 2449 2446 if (request.isConditional()) 2450 2447 request.setCachePolicy(ReloadIgnoringCacheData); 2451 else if (documentLoader()->isLoadingInAPISense()) 2452 request.setCachePolicy(documentLoader()->originalRequest().cachePolicy()); 2453 else 2448 else if (documentLoader()->isLoadingInAPISense()) { 2449 // If we inherit cache policy from a main resource, we use the DocumentLoader's 2450 // original request cache policy for two reasons: 2451 // 1. For POST requests, we mutate the cache policy for the main resource, 2452 // but we do not want this to apply to subresources 2453 // 2. Delegates that modify the cache policy using willSendRequest: should 2454 // not affect any other resources. Such changes need to be done 2455 // per request. 2456 ResourceRequestCachePolicy mainDocumentOriginalCachePolicy = documentLoader()->originalRequest().cachePolicy(); 2457 // Back-forward navigations try to load main resource from cache only to avoid re-submitting form data, and start over (with a warning dialog) if that fails. 2458 // This policy is set on initial request too, but should not be inherited. 2459 ResourceRequestCachePolicy subresourceCachePolicy = (mainDocumentOriginalCachePolicy == ReturnCacheDataDontLoad) ? ReturnCacheDataElseLoad : mainDocumentOriginalCachePolicy; 2460 request.setCachePolicy(subresourceCachePolicy); 2461 } else 2454 2462 request.setCachePolicy(UseProtocolCachePolicy); 2463 2464 // FIXME: Other FrameLoader functions have duplicated code for setting cache policy of main request when reloading. 2465 // It seems better to manage it explicitly than to hide the logic inside addExtraFieldsToRequest(). 2455 2466 } else if (loadType == FrameLoadTypeReload || loadType == FrameLoadTypeReloadFromOrigin || request.isConditional()) 2456 2467 request.setCachePolicy(ReloadIgnoringCacheData); 2457 else if (isBackForwardLoadType(loadType) && m_stateMachine.committedFirstRealDocumentLoad()) 2458 request.setCachePolicy(ReturnCacheDataElseLoad); 2459 2468 2460 2469 if (request.cachePolicy() == ReloadIgnoringCacheData) { 2461 2470 if (loadType == FrameLoadTypeReload) … … 3034 3043 // which should be methods of HistoryController and some of which should be 3035 3044 // methods of FrameLoader. 3036 void FrameLoader::loadDifferentDocumentItem(HistoryItem* item, FrameLoadType loadType )3045 void FrameLoader::loadDifferentDocumentItem(HistoryItem* item, FrameLoadType loadType, FormSubmissionCacheLoadPolicy cacheLoadPolicy) 3037 3046 { 3038 3047 // Remember this item so we can traverse any child items as child frames load … … 3069 3078 // Make sure to add extra fields to the request after the Origin header is added for the FormData case. 3070 3079 // See https://bugs.webkit.org/show_bug.cgi?id=22194 for more discussion. 3071 addExtraFieldsToRequest(request, m_loadType, true);3080 addExtraFieldsToRequest(request, loadType, true); 3072 3081 3073 3082 // FIXME: Slight hack to test if the NSURL cache contains the page we're going to. … … 3079 3088 // extremely rare, but in that case the user will get an error on the navigation. 3080 3089 3081 if (ResourceHandle::willLoadFromCache(request, m_frame)) 3090 if (cacheLoadPolicy == MayAttemptCacheOnlyLoadForFormSubmissionItem) { 3091 request.setCachePolicy(ReturnCacheDataDontLoad); 3082 3092 action = NavigationAction(request, loadType, false); 3083 else {3084 request.setCachePolicy(Re loadIgnoringCacheData);3093 } else { 3094 request.setCachePolicy(ReturnCacheDataElseLoad); 3085 3095 action = NavigationAction(request, NavigationTypeFormResubmitted); 3086 3096 } … … 3096 3106 // If the first load within a frame is a navigation within a back/forward list that was attached 3097 3107 // without any of the items being loaded then we should use the default caching policy (<rdar://problem/8131355>). 3098 if (m_stateMachine.committedFirstRealDocumentLoad() && !itemURL.protocolIs("https"))3108 if (m_stateMachine.committedFirstRealDocumentLoad()) 3099 3109 request.setCachePolicy(ReturnCacheDataElseLoad); 3100 3110 break; … … 3107 3117 } 3108 3118 3109 addExtraFieldsToRequest(request, m_loadType, true);3119 addExtraFieldsToRequest(request, loadType, true); 3110 3120 3111 3121 ResourceRequest requestForOriginalURL(request); … … 3127 3137 loadSameDocumentItem(item); 3128 3138 else 3129 loadDifferentDocumentItem(item, loadType); 3139 loadDifferentDocumentItem(item, loadType, MayAttemptCacheOnlyLoadForFormSubmissionItem); 3140 } 3141 3142 void FrameLoader::retryAfterFailedCacheOnlyMainResourceLoad() 3143 { 3144 ASSERT(m_state == FrameStateProvisional); 3145 ASSERT(!m_loadingFromCachedPage); 3146 // We only use cache-only loads to avoid resubmitting forms. 3147 ASSERT(isBackForwardLoadType(m_loadType)); 3148 ASSERT(m_history.provisionalItem()->formData()); 3149 ASSERT(m_history.provisionalItem() == m_requestedHistoryItem.get()); 3150 3151 FrameLoadType loadType = m_loadType; 3152 HistoryItem* item = m_history.provisionalItem(); 3153 3154 stopAllLoaders(ShouldNotClearProvisionalItem); 3155 loadDifferentDocumentItem(item, loadType, MayNotAttemptCacheOnlyLoadForFormSubmissionItem); 3130 3156 } 3131 3157 -
trunk/Source/WebCore/loader/FrameLoader.h
r135952 r138962 124 124 HistoryItem* requestedHistoryItem() const { return m_requestedHistoryItem.get(); } 125 125 126 void retryAfterFailedCacheOnlyMainResourceLoad(); 127 126 128 static void reportLocalLoadFailed(Frame*, const String& url); 127 129 … … 283 285 284 286 private: 287 enum FormSubmissionCacheLoadPolicy { 288 MayAttemptCacheOnlyLoadForFormSubmissionItem, 289 MayNotAttemptCacheOnlyLoadForFormSubmissionItem 290 }; 291 285 292 bool allChildrenAreComplete() const; // immediate children, not all descendants 286 293 … … 288 295 289 296 void loadSameDocumentItem(HistoryItem*); 290 void loadDifferentDocumentItem(HistoryItem*, FrameLoadType );297 void loadDifferentDocumentItem(HistoryItem*, FrameLoadType, FormSubmissionCacheLoadPolicy); 291 298 292 299 void loadProvisionalItemFromCachedPage(); -
trunk/Source/WebCore/loader/MainResourceLoader.cpp
r138782 r138962 551 551 { 552 552 ASSERT_UNUSED(resource, m_resource == resource); 553 if (!m_resource || (!m_resource->errorOccurred() && !m_resource->wasCanceled())) { 553 ASSERT(m_resource); 554 if (!m_resource->errorOccurred() && !m_resource->wasCanceled()) { 554 555 didFinishLoading(m_resource->loadFinishTime()); 556 return; 557 } 558 559 if (m_documentLoader->request().cachePolicy() == ReturnCacheDataDontLoad && !m_resource->wasCanceled()) { 560 frameLoader()->retryAfterFailedCacheOnlyMainResourceLoad(); 555 561 return; 556 562 } -
trunk/Source/WebCore/platform/network/ResourceHandle.h
r138413 r138962 105 105 static void loadResourceSynchronously(NetworkingContext*, const ResourceRequest&, StoredCredentials, ResourceError&, ResourceResponse&, Vector<char>& data); 106 106 107 static bool willLoadFromCache(ResourceRequest&, Frame*);108 107 static void cacheMetadata(const ResourceResponse&, const Vector<char>&); 109 108 -
trunk/Source/WebCore/platform/network/blackberry/ResourceHandleBlackBerry.cpp
r135243 r138962 127 127 } 128 128 129 bool ResourceHandle::willLoadFromCache(ResourceRequest&, Frame*)130 {131 notImplemented();132 return false;133 }134 135 129 void ResourceHandle::cancel() 136 130 { -
trunk/Source/WebCore/platform/network/cf/ResourceHandleCFNet.cpp
r138413 r138962 809 809 } 810 810 811 bool ResourceHandle::willLoadFromCache(ResourceRequest& request, Frame*)812 {813 request.setCachePolicy(ReturnCacheDataDontLoad);814 815 CFURLResponseRef cfResponse = 0;816 CFErrorRef cfError = 0;817 RetainPtr<CFDataRef> data = adoptCF(CFURLConnectionSendSynchronousRequest(request.cfURLRequest(), &cfResponse, &cfError, request.timeoutInterval()));818 bool cached = cfResponse && !cfError;819 820 if (cfError)821 CFRelease(cfError);822 if (cfResponse)823 CFRelease(cfResponse);824 825 return cached;826 }827 828 811 #if PLATFORM(MAC) 829 812 void ResourceHandle::schedule(SchedulePair* pair) -
trunk/Source/WebCore/platform/network/chromium/ResourceHandle.cpp
r138413 r138962 278 278 279 279 // static 280 bool ResourceHandle::willLoadFromCache(ResourceRequest& request, Frame*)281 {282 // This method is used to determine if a POST request can be repeated from283 // cache, but you cannot really know until you actually try to read from the284 // cache. Even if we checked now, something else could come along and wipe285 // out the cache entry by the time we fetch it.286 //287 // So, we always say yes here, to prevent the FrameLoader from initiating a288 // reload. Then in FrameLoaderClientImpl::dispatchWillSendRequest, we289 // fix-up the cache policy of the request to force a load from the cache.290 //291 ASSERT(request.httpMethod() == "POST");292 return true;293 }294 295 // static296 280 void ResourceHandle::cacheMetadata(const ResourceResponse& response, const Vector<char>& data) 297 281 { -
trunk/Source/WebCore/platform/network/curl/ResourceHandleCurl.cpp
r138413 r138962 167 167 } 168 168 169 bool ResourceHandle::willLoadFromCache(ResourceRequest&, Frame*)170 {171 notImplemented();172 return false;173 }174 175 169 bool ResourceHandle::loadsBlocked() 176 170 { -
trunk/Source/WebCore/platform/network/mac/ResourceHandleMac.mm
r138413 r138962 358 358 } 359 359 360 bool ResourceHandle::willLoadFromCache(ResourceRequest& request, Frame*)361 {362 request.setCachePolicy(ReturnCacheDataDontLoad);363 NSURLResponse *nsURLResponse = nil;364 BEGIN_BLOCK_OBJC_EXCEPTIONS;365 366 [NSURLConnection sendSynchronousRequest:request.nsURLRequest() returningResponse:&nsURLResponse error:nil];367 368 END_BLOCK_OBJC_EXCEPTIONS;369 370 return nsURLResponse;371 }372 373 360 CFStringRef ResourceHandle::synchronousLoadRunLoopMode() 374 361 { -
trunk/Source/WebCore/platform/network/qt/ResourceHandleQt.cpp
r132053 r138962 126 126 } 127 127 128 bool ResourceHandle::willLoadFromCache(ResourceRequest& request, Frame* frame)129 {130 if (!frame)131 return false;132 133 QNetworkAccessManager* manager = 0;134 QAbstractNetworkCache* cache = 0;135 if (frame->loader()->networkingContext()) {136 manager = frame->loader()->networkingContext()->networkAccessManager();137 cache = manager->cache();138 }139 140 if (!cache)141 return false;142 143 QNetworkCacheMetaData data = cache->metaData(request.url());144 if (data.isValid()) {145 request.setCachePolicy(ReturnCacheDataDontLoad);146 return true;147 }148 149 return false;150 }151 152 128 void ResourceHandle::loadResourceSynchronously(NetworkingContext* context, const ResourceRequest& request, StoredCredentials /*storedCredentials*/, ResourceError& error, ResourceResponse& response, Vector<char>& data) 153 129 { -
trunk/Source/WebCore/platform/network/soup/ResourceHandleSoup.cpp
r138413 r138962 1174 1174 } 1175 1175 1176 bool ResourceHandle::willLoadFromCache(ResourceRequest&, Frame*)1177 {1178 // Not having this function means that we'll ask the user about re-posting a form1179 // even when we go back to a page that's still in the cache.1180 notImplemented();1181 return false;1182 }1183 1184 1176 void ResourceHandle::loadResourceSynchronously(NetworkingContext* context, const ResourceRequest& request, StoredCredentials /*storedCredentials*/, ResourceError& error, ResourceResponse& response, Vector<char>& data) 1185 1177 { -
trunk/Source/WebCore/platform/network/win/ResourceHandleWin.cpp
r138413 r138962 432 432 } 433 433 434 bool ResourceHandle::willLoadFromCache(ResourceRequest&, Frame*)434 void prefetchDNS(const String&) 435 435 { 436 436 notImplemented(); 437 } 438 439 bool ResourceHandle::loadsBlocked() 440 { 437 441 return false; 438 442 } 439 443 440 void prefetchDNS(const String&)444 void ResourceHandle::platformSetDefersLoading(bool) 441 445 { 442 446 notImplemented(); 443 447 } 444 448 445 bool ResourceHandle::loadsBlocked()446 {447 return false;448 }449 450 void ResourceHandle::platformSetDefersLoading(bool)451 {452 notImplemented();453 }454 455 449 } // namespace WebCore
Note: See TracChangeset
for help on using the changeset viewer.