Changeset 137607 in webkit


Ignore:
Timestamp:
Dec 13, 2012 10:27:51 AM (11 years ago)
Author:
Nate Chapin
Message:

Route main resource loads through the memory cache.
https://bugs.webkit.org/show_bug.cgi?id=49246

Reviewed by Alexey Proskuryakov.

Source/WebCore:

Note that this patch doesn't actually enable caching of main resources. That will be done in a later patch.
The MainResourceLoader actually has an underlying SubresourceLoader (with the cache layer between them).
In several places, the MainResourceLoader's SubresourceLoader is treated as special.

No new tests, as this is primarily a refactor. A couple of expected results changed slightly.

  • loader/DocumentLoader.cpp:

(WebCore::DocumentLoader::setRequest):
(WebCore::DocumentLoader::subresource):
(WebCore::DocumentLoader::addSubresourceLoader): Because the SubresourceLoader underlying the main resource

needs special handling in certain cases, track it separately from the real SubresourceLoaders.

(WebCore::DocumentLoader::removeSubresourceLoader):
(WebCore::DocumentLoader::startLoadingMainResource):

  • loader/MainResourceLoader.cpp:

(WebCore::MainResourceLoader::MainResourceLoader):
(WebCore::MainResourceLoader::receivedError):
(WebCore::MainResourceLoader::cancel):
(WebCore::MainResourceLoader::clearResource):
(WebCore):
(WebCore::MainResourceLoader::frameLoader):
(WebCore::MainResourceLoader::request):
(WebCore::MainResourceLoader::continueAfterNavigationPolicy):
(WebCore::MainResourceLoader::resourceData):
(WebCore::MainResourceLoader::redirectReceived):
(WebCore::MainResourceLoader::willSendRequest):
(WebCore::MainResourceLoader::continueAfterContentPolicy):
(WebCore::MainResourceLoader::responseReceived):
(WebCore::MainResourceLoader::dataReceived):
(WebCore::MainResourceLoader::didFinishLoading):
(WebCore::MainResourceLoader::notifyFinished):
(WebCore::MainResourceLoader::reportMemoryUsage):
(WebCore::MainResourceLoader::handleSubstituteDataLoadNow):
(WebCore::MainResourceLoader::load):
(WebCore::MainResourceLoader::setDefersLoading):
(WebCore::MainResourceLoader::defersLoading):
(WebCore::MainResourceLoader::setShouldBufferData):
(WebCore::MainResourceLoader::loader):
(WebCore::MainResourceLoader::identifier):

  • loader/MainResourceLoader.h:

(MainResourceLoader):
(WebCore::MainResourceLoader::documentLoader):

  • loader/ResourceLoader.cpp:

(WebCore::ResourceLoader::willSendRequest):

  • loader/ResourceLoader.h:

(WebCore::ResourceLoader::defersLoading):
(WebCore::ResourceLoader::cancelled):

  • loader/appcache/ApplicationCacheHost.cpp:

(WebCore::ApplicationCacheHost::maybeLoadFallbackForMainResponse):
(WebCore::ApplicationCacheHost::maybeLoadFallbackForMainError):

  • loader/mac/DocumentLoaderMac.cpp:

(WebCore::DocumentLoader::schedule):
(WebCore::DocumentLoader::unschedule):

LayoutTests:

  • http/tests/misc/will-send-request-returns-null-on-redirect-expected.txt: The error code for loads cancelled

by an embedder's willSendRequest() will show as standard load cancellations rather than as a content policy
failure. This was an odd quirk of how MainResourceLoader::willSendRequest() was implemented (namely, doing a
content policy check on ResourceRequests with empty urls).

  • platform/chromium-linux/fast/replaced/border-radius-clip-content-edge-expected.png:
  • platform/chromium/http/tests/misc/will-send-request-returns-null-on-redirect-expected.txt: The error code for loads cancelled

by an embedder's willSendRequest() will show as standard load cancellations rather than as a content policy
failure. This was an odd quirk of how MainResourceLoader::willSendRequest() was implemented (namely, doing a
content policy check on ResourceRequests with empty urls).

Location:
trunk
Files:
14 edited

Legend:

Unmodified
Added
Removed
  • trunk/LayoutTests/ChangeLog

    r137596 r137607  
     12012-12-13  Nate Chapin  <japhet@chromium.org>
     2
     3        Route main resource loads through the memory cache.
     4        https://bugs.webkit.org/show_bug.cgi?id=49246
     5
     6        Reviewed by Alexey Proskuryakov.
     7
     8        * http/tests/misc/will-send-request-returns-null-on-redirect-expected.txt: The error code for loads cancelled
     9            by an embedder's willSendRequest() will show as standard load cancellations rather than as a content policy
     10            failure. This was an odd quirk of how MainResourceLoader::willSendRequest() was implemented (namely, doing a
     11            content policy check on ResourceRequests with empty urls).
     12        * platform/chromium-linux/fast/replaced/border-radius-clip-content-edge-expected.png:
     13        * platform/chromium/http/tests/misc/will-send-request-returns-null-on-redirect-expected.txt: The error code for loads cancelled
     14            by an embedder's willSendRequest() will show as standard load cancellations rather than as a content policy
     15            failure. This was an odd quirk of how MainResourceLoader::willSendRequest() was implemented (namely, doing a
     16            content policy check on ResourceRequests with empty urls).
     17
    1182012-12-13  Joanmarie Diggs  <jdiggs@igalia.com>
    219
  • trunk/LayoutTests/http/tests/misc/will-send-request-returns-null-on-redirect-expected.txt

    r137424 r137607  
    33http://127.0.0.1:8000/misc/resources/redirect-to-http-url.php - willSendRequest <NSURLRequest URL http://www.example.com/, main document URL http://127.0.0.1:8000/misc/will-send-request-returns-null-on-redirect.html, http method GET> redirectResponse <NSURLResponse http://127.0.0.1:8000/misc/resources/redirect-to-http-url.php, http status code 302>
    44Returning null for this redirect
    5 http://127.0.0.1:8000/misc/resources/redirect-to-http-url.php - didFailLoadingWithError: <NSError domain WebKitErrorDomain, code 102>
     5http://127.0.0.1:8000/misc/resources/redirect-to-http-url.php - didFailLoadingWithError: <NSError domain NSURLErrorDomain, code -999>
    66https://bugs.webkit.org/show_bug.cgi?id=27595
    77This test checks to make sure that things behave as expected when the resource load delegate returns null in response to willSendRequest.
  • trunk/LayoutTests/platform/chromium/http/tests/misc/will-send-request-returns-null-on-redirect-expected.txt

    r137424 r137607  
    33http://127.0.0.1:8000/misc/resources/redirect-to-http-url.php - willSendRequest <NSURLRequest URL http://www.example.com/, main document URL http://127.0.0.1:8000/misc/will-send-request-returns-null-on-redirect.html, http method GET> redirectResponse <NSURLResponse http://127.0.0.1:8000/misc/resources/redirect-to-http-url.php, http status code 302>
    44Returning null for this redirect
    5 http://127.0.0.1:8000/misc/resources/redirect-to-http-url.php - didFailLoadingWithError: <NSError domain WebKit, code -10000, failing URL "(null)">
     5http://127.0.0.1:8000/misc/resources/redirect-to-http-url.php - didFailLoadingWithError: <NSError domain NSURLErrorDomain, code -999, failing URL "(null)">
    66https://bugs.webkit.org/show_bug.cgi?id=27595
    77This test checks to make sure that things behave as expected when the resource load delegate returns null in response to willSendRequest.
  • trunk/Source/WebCore/ChangeLog

    r137606 r137607  
     12012-12-13  Nate Chapin  <japhet@chromium.org>
     2
     3        Route main resource loads through the memory cache.
     4        https://bugs.webkit.org/show_bug.cgi?id=49246
     5
     6        Reviewed by Alexey Proskuryakov.
     7
     8        Note that this patch doesn't actually enable caching of main resources. That will be done in a later patch.
     9        The MainResourceLoader actually has an underlying SubresourceLoader (with the cache layer between them).
     10        In several places, the MainResourceLoader's SubresourceLoader is treated as special.
     11
     12        No new tests, as this is primarily a refactor. A couple of expected results changed slightly.
     13
     14        * loader/DocumentLoader.cpp:
     15        (WebCore::DocumentLoader::setRequest):
     16        (WebCore::DocumentLoader::subresource):
     17        (WebCore::DocumentLoader::addSubresourceLoader): Because the SubresourceLoader underlying the main resource
     18            needs special handling in certain cases, track it separately from the real SubresourceLoaders.
     19        (WebCore::DocumentLoader::removeSubresourceLoader):
     20        (WebCore::DocumentLoader::startLoadingMainResource):
     21        * loader/MainResourceLoader.cpp:
     22        (WebCore::MainResourceLoader::MainResourceLoader):
     23        (WebCore::MainResourceLoader::receivedError):
     24        (WebCore::MainResourceLoader::cancel):
     25        (WebCore::MainResourceLoader::clearResource):
     26        (WebCore):
     27        (WebCore::MainResourceLoader::frameLoader):
     28        (WebCore::MainResourceLoader::request):
     29        (WebCore::MainResourceLoader::continueAfterNavigationPolicy):
     30        (WebCore::MainResourceLoader::resourceData):
     31        (WebCore::MainResourceLoader::redirectReceived):
     32        (WebCore::MainResourceLoader::willSendRequest):
     33        (WebCore::MainResourceLoader::continueAfterContentPolicy):
     34        (WebCore::MainResourceLoader::responseReceived):
     35        (WebCore::MainResourceLoader::dataReceived):
     36        (WebCore::MainResourceLoader::didFinishLoading):
     37        (WebCore::MainResourceLoader::notifyFinished):
     38        (WebCore::MainResourceLoader::reportMemoryUsage):
     39        (WebCore::MainResourceLoader::handleSubstituteDataLoadNow):
     40        (WebCore::MainResourceLoader::load):
     41        (WebCore::MainResourceLoader::setDefersLoading):
     42        (WebCore::MainResourceLoader::defersLoading):
     43        (WebCore::MainResourceLoader::setShouldBufferData):
     44        (WebCore::MainResourceLoader::loader):
     45        (WebCore::MainResourceLoader::identifier):
     46        * loader/MainResourceLoader.h:
     47        (MainResourceLoader):
     48        (WebCore::MainResourceLoader::documentLoader):
     49        * loader/ResourceLoader.cpp:
     50        (WebCore::ResourceLoader::willSendRequest):
     51        * loader/ResourceLoader.h:
     52        (WebCore::ResourceLoader::defersLoading):
     53        (WebCore::ResourceLoader::cancelled):
     54        * loader/appcache/ApplicationCacheHost.cpp:
     55        (WebCore::ApplicationCacheHost::maybeLoadFallbackForMainResponse):
     56        (WebCore::ApplicationCacheHost::maybeLoadFallbackForMainError):
     57        * loader/mac/DocumentLoaderMac.cpp:
     58        (WebCore::DocumentLoader::schedule):
     59        (WebCore::DocumentLoader::unschedule):
     60
    1612012-12-13  Pratik Solanki  <psolanki@apple.com>
    262
  • trunk/Source/WebCore/loader/DocumentLoader.cpp

    r137424 r137607  
    181181    ASSERT(!m_committed);
    182182
    183     KURL oldURL = m_request.url();
    184183    m_request = req;
    185 
    186     // Only dispatchDidReceiveServerRedirectForProvisionalLoad() if URL changed (and is non-null).
    187     // Also, don't send it when replacing unreachable URLs with alternate content.
    188     if (!handlingUnreachableURL && !req.url().isNull() && oldURL != req.url())
    189         frameLoader()->client()->dispatchDidReceiveServerRedirectForProvisionalLoad();
    190184}
    191185
     
    586580        return archiveResourceForURL(url);
    587581
     582    if (resource->type() == CachedResource::MainResource)
     583        return 0;
     584
    588585    // FIXME: This has the side effect of making the resource non-purgeable.
    589586    // It would be better if it didn't have this permanent effect.
     
    812809void DocumentLoader::addSubresourceLoader(ResourceLoader* loader)
    813810{
     811    // The main resource's underlying ResourceLoader will ask to be added here.
     812    // It is much simpler to handle special casing of main resource loads if we don't
     813    // let it be added. In the main resource load case, m_mainResourceLoader->loader()
     814    // will still be null at this point, but m_gotFirstByte should be false here if and only
     815    // if we are just starting the main resource load.
     816    if (!m_gotFirstByte)
     817        return;
     818    ASSERT(!m_subresourceLoaders.contains(loader));
     819    ASSERT(!m_mainResourceLoader || m_mainResourceLoader->loader() != loader);
    814820    m_subresourceLoaders.add(loader);
    815821}
     
    817823void DocumentLoader::removeSubresourceLoader(ResourceLoader* loader)
    818824{
     825    if (!m_subresourceLoaders.contains(loader))
     826        return;
    819827    m_subresourceLoaders.remove(loader);
    820828    checkLoadComplete();
     
    882890    if (m_request.isNull()) {
    883891        m_mainResourceLoader = 0;
     892        // If the load was aborted by clearing m_request, it's possible the ApplicationCacheHost
     893        // is now in a state where starting an empty load will be inconsistent. Replace it with
     894        // a new ApplicationCacheHost.
     895        m_applicationCacheHost = adoptPtr(new ApplicationCacheHost(this));
    884896        maybeLoadEmpty();
    885897    }
  • trunk/Source/WebCore/loader/MainResourceLoader.cpp

    r137424 r137607  
    3333#include "ApplicationCacheHost.h"
    3434#include "BackForwardController.h"
     35#include "CachedResourceLoader.h"
     36#include "CachedResourceRequest.h"
    3537#include "Console.h"
    3638#include "DOMWindow.h"
     
    4547#include "HistoryItem.h"
    4648#include "InspectorInstrumentation.h"
    47 #include "LoaderStrategy.h"
    4849#include "Page.h"
    49 #include "PlatformStrategies.h"
     50#include "ProgressTracker.h"
     51#include "ResourceBuffer.h"
    5052#include "ResourceError.h"
    5153#include "ResourceHandle.h"
    52 #include "ResourceLoadScheduler.h"
    5354#include "SchemeRegistry.h"
    5455#include "SecurityOrigin.h"
    5556#include "Settings.h"
     57#include "SubresourceLoader.h"
    5658#include <wtf/CurrentTime.h>
    5759
     
    6466#endif
    6567
    66 // FIXME: More that is in common with SubresourceLoader should move up into ResourceLoader.
    67 
    6868namespace WebCore {
    6969
    7070MainResourceLoader::MainResourceLoader(DocumentLoader* documentLoader)
    71     : ResourceLoader(documentLoader->frame(), ResourceLoaderOptions(SendCallbacks, SniffContent, BufferData, AllowStoredCredentials, AskClientForCrossOriginCredentials, SkipSecurityCheck))
    72     , m_dataLoadTimer(this, &MainResourceLoader::handleSubstituteDataLoadNow)
     71    : m_dataLoadTimer(this, &MainResourceLoader::handleSubstituteDataLoadNow)
     72    , m_documentLoader(documentLoader)
    7373    , m_loadingMultipartContent(false)
    7474    , m_waitingForContentPolicy(false)
     
    8282MainResourceLoader::~MainResourceLoader()
    8383{
     84    clearResource();
    8485#if PLATFORM(MAC) && !PLATFORM(IOS) && __MAC_OS_X_VERSION_MIN_REQUIRED >= 1080
    8586    ASSERT(!m_filter);
     
    103104    // and didFailToLoad calls a ResourceLoadDelegate method and they need to be in the correct order.
    104105    documentLoader()->mainReceivedError(error);
    105 
    106     if (!cancelled()) {
    107         ASSERT(!reachedTerminalState());
    108         frameLoader()->notifier()->didFailToLoad(this, error);
    109        
    110         releaseResources();
    111     }
    112 
    113     ASSERT(reachedTerminalState());
    114 }
    115 
    116 void MainResourceLoader::willCancel(const ResourceError&)
    117 {
     106}
     107
     108void MainResourceLoader::cancel()
     109{
     110    cancel(ResourceError());
     111}
     112
     113void MainResourceLoader::cancel(const ResourceError& error)
     114{
     115    RefPtr<MainResourceLoader> protect(this);
     116    ResourceError resourceError = error.isNull() ? frameLoader()->cancelledError(request()) : error;
     117
    118118    m_dataLoadTimer.stop();
    119119
     
    122122        ASSERT(m_waitingForContentPolicy);
    123123        m_waitingForContentPolicy = false;
    124         deref(); // balances ref in didReceiveResponse
    125     }
    126 }
    127 
    128 void MainResourceLoader::didCancel(const ResourceError& error)
    129 {
    130     // We should notify the frame loader after fully canceling the load, because it can do complicated work
    131     // like calling DOMWindow::print(), during which a half-canceled load could try to finish.
    132     documentLoader()->mainReceivedError(error);
     124        deref(); // balances ref in responseReceived
     125    }
     126
     127    if (loader())
     128        loader()->cancel(resourceError);
     129
     130    clearResource();
     131    receivedError(resourceError);
    133132
    134133#if PLATFORM(MAC) && !PLATFORM(IOS) && __MAC_OS_X_VERSION_MIN_REQUIRED >= 1080
     
    138137    }
    139138#endif
     139}
     140
     141void MainResourceLoader::clearResource()
     142{
     143    if (m_resource) {
     144        m_resource->removeClient(this);
     145        m_resource = 0;
     146    }
     147}
     148
     149FrameLoader* MainResourceLoader::frameLoader() const
     150{
     151    return m_documentLoader->frameLoader();
     152}
     153
     154const ResourceRequest& MainResourceLoader::request() const
     155{
     156    return m_resource ? m_resource->resourceRequest() : m_initialRequest;
    140157}
    141158
     
    164181        // A redirect resulted in loading substitute data.
    165182        ASSERT(documentLoader()->timing()->redirectCount());
    166         handle()->cancel();
     183        clearResource();
    167184        handleSubstituteDataLoadSoon(request);
    168185    }
     
    184201}
    185202
    186 void MainResourceLoader::addData(const char* data, int length, bool allAtOnce)
    187 {
    188     ResourceLoader::addData(data, length, allAtOnce);
    189     documentLoader()->receivedData(data, length);
     203PassRefPtr<ResourceBuffer> MainResourceLoader::resourceData()
     204{
     205    return m_resource ? m_resource->resourceBuffer() : 0;
     206}
     207
     208void MainResourceLoader::redirectReceived(CachedResource* resource, ResourceRequest& request, const ResourceResponse& redirectResponse)
     209{
     210    ASSERT_UNUSED(resource, resource == m_resource);
     211    willSendRequest(request, redirectResponse);
    190212}
    191213
     
    240262    }
    241263
    242     ResourceLoader::willSendRequest(newRequest, redirectResponse);
    243 
    244264    // Don't set this on the first request. It is set when the main load was started.
    245265    m_documentLoader->setRequest(newRequest);
     
    278298            frameLoader()->policyChecker()->cannotShowMIMEType(r);
    279299            // Check reachedTerminalState since the load may have already been canceled inside of _handleUnimplementablePolicyWithErrorCode::.
    280             if (!reachedTerminalState())
    281                 stopLoadingForPolicyChange();
     300            stopLoadingForPolicyChange();
    282301            return;
    283302        }
     
    286305
    287306    case PolicyDownload: {
    288         // m_handle can be null, e.g. when loading a substitute resource from application cache.
    289         if (!m_handle) {
    290             receivedError(cannotShowURLError());
     307        // m_resource can be null, e.g. when loading a substitute resource from application cache.
     308        if (!m_resource) {
     309            receivedError(frameLoader()->client()->cannotShowURLError(request()));
    291310            return;
    292311        }
     
    298317        frameLoader()->setOriginalURLForDownloadRequest(request);
    299318
    300         frameLoader()->client()->download(m_handle.get(), request, r);
     319        frameLoader()->client()->download(loader()->handle(), request, r);
    301320
    302321        // It might have gone missing
     
    330349    }
    331350
    332     // we may have cancelled this load as part of switching to fallback content
    333     if (!reachedTerminalState())
    334         ResourceLoader::didReceiveResponse(r);
    335 
    336     if (m_documentLoader && !m_documentLoader->isStopping() && m_substituteData.isValid()) {
     351    if (!m_documentLoader->isStopping() && m_substituteData.isValid()) {
    337352        if (m_substituteData.content()->size())
    338             didReceiveData(m_substituteData.content()->data(), m_substituteData.content()->size(), m_substituteData.content()->size(), true);
     353            dataReceived(0, m_substituteData.content()->data(), m_substituteData.content()->size());
    339354        if (!m_documentLoader->isStopping())
    340355            didFinishLoading(0);
     
    353368    if (!m_documentLoader->isStopping())
    354369        continueAfterContentPolicy(policy, m_response);
    355     deref(); // balances ref in didReceiveResponse
    356 }
    357 
    358 void MainResourceLoader::didReceiveResponse(const ResourceResponse& r)
    359 {
     370    deref(); // balances ref in responseReceived
     371}
     372
     373void MainResourceLoader::responseReceived(CachedResource* resource, const ResourceResponse& r)
     374{
     375    ASSERT_UNUSED(resource, m_resource == resource);
    360376    if (documentLoader()->applicationCacheHost()->maybeLoadFallbackForMainResponse(request(), r))
    361377        return;
     
    383399    if (m_loadingMultipartContent) {
    384400        m_documentLoader->setupForReplace();
    385         clearResourceData();
     401        m_resource->clear();
    386402    }
    387403   
     
    399415    ASSERT(!m_waitingForContentPolicy);
    400416    m_waitingForContentPolicy = true;
    401     ref(); // balanced by deref in continueAfterContentPolicy and didCancel
     417    ref(); // balanced by deref in continueAfterContentPolicy and cancel
    402418
    403419    // Always show content with valid substitute data.
     
    424440}
    425441
    426 void MainResourceLoader::didReceiveData(const char* data, int length, long long encodedDataLength, bool allAtOnce)
     442void MainResourceLoader::dataReceived(CachedResource* resource, const char* data, int length)
    427443{
    428444    ASSERT(data);
    429445    ASSERT(length != 0);
    430 
     446    ASSERT_UNUSED(resource, resource == m_resource);
    431447    ASSERT(!m_response.isNull());
    432448
     
    453469        if (!blockedData) {
    454470            // Transition to committed state.
    455             ResourceLoader::didReceiveData("", 0, 0, false);
     471            documentLoader()->receivedData(0, 0);
    456472            return;
    457473        }
    458474
    459475        data = blockedData;
    460         encodedDataLength = -1;
    461     }
    462 #endif
    463 
    464     documentLoader()->applicationCacheHost()->mainResourceDataReceived(data, length, encodedDataLength, allAtOnce);
     476    }
     477#endif
     478
     479    documentLoader()->applicationCacheHost()->mainResourceDataReceived(data, length, -1, false);
    465480
    466481    // The additional processing can do anything including possibly removing the last
     
    470485    m_timeOfLastDataReceived = monotonicallyIncreasingTime();
    471486
    472     ResourceLoader::didReceiveData(data, length, encodedDataLength, allAtOnce);
     487    documentLoader()->receivedData(data, length);
    473488
    474489#if PLATFORM(MAC) && !PLATFORM(IOS) && __MAC_OS_X_VERSION_MIN_REQUIRED >= 1080
     
    491506    // See <rdar://problem/6304600> for more details.
    492507#if !USE(CF)
    493     ASSERT(!defersLoading() || InspectorInstrumentation::isDebuggerPaused(m_frame.get()));
     508    ASSERT(!defersLoading() || InspectorInstrumentation::isDebuggerPaused(m_documentLoader->frame()));
    494509#endif
    495510
     
    507522        m_filter = 0;
    508523        if (data)
    509             didReceiveData(data, length, -1, false);
     524            dataReceived(m_resource.get(), data, length);
    510525        wkFilterRelease(filter);
    511526    }
     
    517532    documentLoader()->timing()->setResponseEnd(finishTime ? finishTime : (m_timeOfLastDataReceived ? m_timeOfLastDataReceived : monotonicallyIncreasingTime()));
    518533    documentLoader()->finishedLoading();
    519     ResourceLoader::didFinishLoading(finishTime);
    520534
    521535    dl->applicationCacheHost()->finishedLoadingMainResource();
    522536}
    523537
    524 void MainResourceLoader::didFail(const ResourceError& error)
    525 {
     538void MainResourceLoader::notifyFinished(CachedResource* resource)
     539{
     540    ASSERT_UNUSED(resource, m_resource == resource);
     541    if (!m_resource || (!m_resource->errorOccurred() && !m_resource->wasCanceled())) {
     542        didFinishLoading(m_resource->loadFinishTime());
     543        return;
     544    }
     545
    526546#if PLATFORM(MAC) && !PLATFORM(IOS) && __MAC_OS_X_VERSION_MIN_REQUIRED >= 1080
    527547    if (m_filter) {
     
    531551#endif
    532552
     553    const ResourceError& error = m_resource->resourceError();
    533554    if (documentLoader()->applicationCacheHost()->maybeLoadFallbackForMainError(request(), error))
    534555        return;
     
    546567{
    547568    MemoryClassInfo info(memoryObjectInfo, this, WebCoreMemoryTypes::Loader);
    548     ResourceLoader::reportMemoryUsage(memoryObjectInfo);
    549569    info.addMember(m_initialRequest);
    550570    info.addMember(m_substituteData);
     
    565585       
    566586    ResourceResponse response(url, m_substituteData.mimeType(), m_substituteData.content()->size(), m_substituteData.textEncoding(), "");
    567     didReceiveResponse(response);
     587    responseReceived(0, response);
    568588}
    569589
     
    588608}
    589609
    590 void MainResourceLoader::loadNow(ResourceRequest& r)
    591 {
    592     ASSERT(!m_handle);
    593     ASSERT(!defersLoading());
    594 
    595 #if USE(PLATFORM_STRATEGIES)
    596     platformStrategies()->loaderStrategy()->resourceLoadScheduler()->addMainResourceLoad(this);
    597 #else
    598     resourceLoadScheduler()->addMainResourceLoad(this);
    599 #endif
    600 
    601     if (m_substituteData.isValid())
    602         handleSubstituteDataLoadSoon(r);
    603     else
    604         m_handle = ResourceHandle::create(m_frame->loader()->networkingContext(), r, this, false, true);
    605 
    606     return;
    607 }
    608 
    609 void MainResourceLoader::load(const ResourceRequest& r, const SubstituteData& substituteData)
    610 {
    611     ASSERT(!m_handle);
    612 
     610void MainResourceLoader::load(const ResourceRequest& initialRequest, const SubstituteData& substituteData)
     611{
    613612    // It appears that it is possible for this load to be cancelled and derefenced by the DocumentLoader
    614613    // in willSendRequest() if loadNow() is called.
     
    620619    ASSERT(!documentLoader()->timing()->fetchStart());
    621620    documentLoader()->timing()->markFetchStart();
    622     ResourceRequest request(r);
     621    ResourceRequest request(initialRequest);
    623622
    624623    // Send this synthetic delegate callback since clients expect it, and
     
    628627    ASSERT(!deletionHasBegun());
    629628
    630     // <rdar://problem/4801066>
    631     // willSendRequest() is liable to make the call to frameLoader() return null, so we need to check that here
    632     if (!frameLoader() || request.isNull()) {
    633         if (!reachedTerminalState())
    634             releaseResources();
    635         return;
    636     }
     629    // willSendRequest() may lead to our DocumentLoader being detached or cancelling the load via nulling the ResourceRequest.
     630    if (!documentLoader()->frame() || request.isNull())
     631        return;
    637632
    638633    documentLoader()->applicationCacheHost()->maybeLoadMainResource(request, m_substituteData);
    639634
    640     if (defersLoading())
    641         m_initialRequest = request;
    642     else
    643         loadNow(request);
     635    if (m_substituteData.isValid()) {
     636        handleSubstituteDataLoadSoon(request);
     637        return;
     638    }
     639
     640    DEFINE_STATIC_LOCAL(ResourceLoaderOptions, mainResourceLoadOptions,
     641        (SendCallbacks, SniffContent, BufferData, AllowStoredCredentials, AskClientForCrossOriginCredentials, SkipSecurityCheck));
     642    CachedResourceRequest cachedResourceRequest(request, mainResourceLoadOptions);
     643    m_resource = documentLoader()->cachedResourceLoader()->requestMainResource(cachedResourceRequest);
     644    if (!m_resource) {
     645        documentLoader()->setRequest(ResourceRequest());
     646        return;
     647    }
     648    m_resource->addClient(this);
     649
     650    // We need to wait until after requestMainResource() is called to setRequest(), because there are a bunch of headers set when
     651    // the underlying ResourceLoader is created, and DocumentLoader::m_request needs to include those. However, the cache will
     652    // strip the fragment identifier (which DocumentLoader::m_request should also include), so add that back in.
     653    if (loader())
     654        request = loader()->originalRequest();
     655    documentLoader()->setRequest(request);
    644656}
    645657
    646658void MainResourceLoader::setDefersLoading(bool defers)
    647659{
    648     ResourceLoader::setDefersLoading(defers);
    649 
    650     if (defers) {
    651         if (m_dataLoadTimer.isActive())
    652             m_dataLoadTimer.stop();
    653     } else {
    654         if (m_initialRequest.isNull())
    655             return;
    656 
    657         ResourceRequest initialRequest(m_initialRequest);
    658         m_initialRequest = ResourceRequest();
    659         loadNow(initialRequest);
    660     }
    661 }
    662 
    663 }
     660    if (loader())
     661        loader()->setDefersLoading(defers);
     662}
     663
     664bool MainResourceLoader::defersLoading() const
     665{
     666    return loader() ? loader()->defersLoading() : false;
     667}
     668
     669void MainResourceLoader::setShouldBufferData(DataBufferingPolicy shouldBufferData)
     670{
     671    ASSERT(m_resource);
     672    m_resource->setShouldBufferData(shouldBufferData);
     673}
     674
     675ResourceLoader* MainResourceLoader::loader() const
     676{
     677    return m_resource ? m_resource->loader() : 0;
     678}
     679
     680unsigned long MainResourceLoader::identifier() const
     681{
     682    if (ResourceLoader* resourceLoader = loader())
     683        return resourceLoader->identifier();
     684    return 0;
     685}
     686
     687}
  • trunk/Source/WebCore/loader/MainResourceLoader.h

    r137424 r137607  
    3030#define MainResourceLoader_h
    3131
     32#include "CachedRawResource.h"
     33#include "CachedResourceHandle.h"
    3234#include "FrameLoaderTypes.h"
    3335#include "ResourceLoader.h"
     
    5052class ResourceRequest;
    5153
    52 class MainResourceLoader : public ResourceLoader {
     54class MainResourceLoader : public RefCounted<MainResourceLoader>, public CachedRawResourceClient {
     55    WTF_MAKE_FAST_ALLOCATED;
    5356public:
    5457    static PassRefPtr<MainResourceLoader> create(DocumentLoader*);
     
    5659
    5760    void load(const ResourceRequest&, const SubstituteData&);
    58     virtual void addData(const char*, int, bool allAtOnce) OVERRIDE;
     61    void cancel();
     62    void cancel(const ResourceError&);
     63    ResourceLoader* loader() const;
     64    PassRefPtr<ResourceBuffer> resourceData();
    5965
    60     virtual void setDefersLoading(bool) OVERRIDE;
    61 
    62     virtual void willSendRequest(ResourceRequest&, const ResourceResponse& redirectResponse) OVERRIDE;
    63     virtual void didReceiveResponse(const ResourceResponse&) OVERRIDE;
    64     virtual void didReceiveData(const char*, int, long long encodedDataLength, bool allAtOnce) OVERRIDE;
    65     virtual void didFinishLoading(double finishTime) OVERRIDE;
    66     virtual void didFail(const ResourceError&) OVERRIDE;
     66    void setDefersLoading(bool);
     67    void setShouldBufferData(DataBufferingPolicy);
    6768
    6869#if HAVE(RUNLOOP_TIMER)
     
    7273#endif
    7374
     75    unsigned long identifier() const;
    7476    bool isLoadingMultipartContent() const { return m_loadingMultipartContent; }
    7577
    76     virtual void reportMemoryUsage(MemoryObjectInfo*) const OVERRIDE;
     78    void reportMemoryUsage(MemoryObjectInfo*) const;
    7779
    7880private:
    7981    explicit MainResourceLoader(DocumentLoader*);
    8082
    81     virtual void willCancel(const ResourceError&) OVERRIDE;
    82     virtual void didCancel(const ResourceError&) OVERRIDE;
     83    virtual void redirectReceived(CachedResource*, ResourceRequest&, const ResourceResponse&) OVERRIDE;
     84    virtual void responseReceived(CachedResource*, const ResourceResponse&) OVERRIDE;
     85    virtual void dataReceived(CachedResource*, const char* data, int dataLength) OVERRIDE;
     86    virtual void notifyFinished(CachedResource*) OVERRIDE;
    8387
    84     void loadNow(ResourceRequest&);
    85 
     88    void willSendRequest(ResourceRequest&, const ResourceResponse& redirectResponse);
     89    void didFinishLoading(double finishTime);
    8690    void handleSubstituteDataLoadSoon(const ResourceRequest&);
    8791    void handleSubstituteDataLoadNow(MainResourceLoaderTimer*);
     
    105109#endif
    106110
     111    FrameLoader* frameLoader() const;
     112    DocumentLoader* documentLoader() const { return m_documentLoader.get(); }
     113
     114    const ResourceRequest& request() const;
     115    void clearResource();
     116
     117    bool defersLoading() const;
     118
     119    CachedResourceHandle<CachedRawResource> m_resource;
     120
    107121    ResourceRequest m_initialRequest;
    108122    SubstituteData m_substituteData;
     123    ResourceResponse m_response;
    109124
    110125    MainResourceLoaderTimer m_dataLoadTimer;
     126    RefPtr<DocumentLoader> m_documentLoader;
    111127
    112128    bool m_loadingMultipartContent;
  • trunk/Source/WebCore/loader/ResourceLoader.cpp

    r137424 r137607  
    252252    }
    253253    m_request = request;
     254
     255    if (!redirectResponse.isNull() && !m_documentLoader->isCommitted())
     256        frameLoader()->client()->dispatchDidReceiveServerRedirectForProvisionalLoad();
    254257}
    255258
  • trunk/Source/WebCore/loader/ResourceLoader.h

    r137424 r137607  
    6666   
    6767    virtual void setDefersLoading(bool);
     68    bool defersLoading() const { return m_defersLoading; }
    6869
    6970    unsigned long identifier() const { return m_identifier; }
     
    168169
    169170    bool cancelled() const { return m_cancelled; }
    170     bool defersLoading() const { return m_defersLoading; }
    171171
    172172    RefPtr<ResourceHandle> m_handle;
  • trunk/Source/WebCore/loader/appcache/ApplicationCacheHost.cpp

    r137424 r137607  
    104104            m_mainResourceApplicationCache = ApplicationCacheGroup::fallbackCacheForMainRequest(request, documentLoader());
    105105
    106             if (scheduleLoadFallbackResourceFromApplicationCache(documentLoader()->mainResourceLoader(), m_mainResourceApplicationCache.get()))
     106            if (scheduleLoadFallbackResourceFromApplicationCache(documentLoader()->mainResourceLoader()->loader(), m_mainResourceApplicationCache.get()))
    107107                return true;
    108108        }
     
    118118            m_mainResourceApplicationCache = ApplicationCacheGroup::fallbackCacheForMainRequest(request, m_documentLoader);
    119119
    120             if (scheduleLoadFallbackResourceFromApplicationCache(documentLoader()->mainResourceLoader(), m_mainResourceApplicationCache.get()))
     120            if (scheduleLoadFallbackResourceFromApplicationCache(documentLoader()->mainResourceLoader()->loader(), m_mainResourceApplicationCache.get()))
    121121                return true;
    122122        }
  • trunk/Source/WebCore/loader/cache/CachedRawResource.cpp

    r137424 r137607  
    9999void CachedRawResource::willSendRequest(ResourceRequest& request, const ResourceResponse& response)
    100100{
     101    CachedResourceHandle<CachedRawResource> protect(this);
    101102    if (!response.isNull()) {
    102103        CachedResourceClientWalker<CachedRawResourceClient> w(m_clients);
  • trunk/Source/WebCore/loader/cache/CachedResourceLoader.cpp

    r137604 r137607  
    704704
    705705#if ENABLE(RESOURCE_TIMING)
    706     if (resource && !resource->errorOccurred() && !resource->wasCanceled()) {
     706    // FIXME: Add resource timing support for main resources.
     707    if (resource && resource->type() != CachedResource::MainResource && !resource->errorOccurred() && !resource->wasCanceled()) {
    707708        HashMap<CachedResource*, InitiatorInfo>::iterator initiatorIt = m_initiatorMap.find(resource);
    708709        if (initiatorIt != m_initiatorMap.end()) {
  • trunk/Source/WebCore/loader/mac/DocumentLoaderMac.cpp

    r137424 r137607  
    5656void DocumentLoader::schedule(SchedulePair* pair)
    5757{
    58     if (m_mainResourceLoader && m_mainResourceLoader->handle())
    59         m_mainResourceLoader->handle()->schedule(pair);
     58    if (m_mainResourceLoader && m_mainResourceLoader->loader() && m_mainResourceLoader->loader()->handle())
     59        m_mainResourceLoader->loader()->handle()->schedule(pair);
    6060    scheduleAll(m_subresourceLoaders, pair);
    6161    scheduleAll(m_plugInStreamLoaders, pair);
     
    6565void DocumentLoader::unschedule(SchedulePair* pair)
    6666{
    67     if (m_mainResourceLoader && m_mainResourceLoader->handle())
    68         m_mainResourceLoader->handle()->unschedule(pair);
     67    if (m_mainResourceLoader && m_mainResourceLoader->loader() && m_mainResourceLoader->loader()->handle())
     68        m_mainResourceLoader->loader()->handle()->unschedule(pair);
    6969    unscheduleAll(m_subresourceLoaders, pair);
    7070    unscheduleAll(m_plugInStreamLoaders, pair);
Note: See TracChangeset for help on using the changeset viewer.