Changeset 137333 in webkit


Ignore:
Timestamp:
Dec 11, 2012 10:28:26 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 Antti Koivisto.

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/inspector/resource-parameters.html: The main resource's url will exclude the fragment identifier here.
  • 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/http/tests/misc/will-send-request-returns-null-on-redirect-expected.txt: See previous.
Location:
trunk
Files:
15 edited

Legend:

Unmodified
Added
Removed
  • trunk/LayoutTests/ChangeLog

    r137332 r137333  
     12012-12-11  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 Antti Koivisto.
     7
     8        * http/tests/inspector/resource-parameters.html: The main resource's url will exclude the fragment identifier here.
     9        * http/tests/misc/will-send-request-returns-null-on-redirect-expected.txt: The error code for loads cancelled
     10            by an embedder's willSendRequest() will show as standard load cancellations rather than as a content policy
     11            failure. This was an odd quirk of how MainResourceLoader::willSendRequest() was implemented (namely, doing a
     12            content policy check on ResourceRequests with empty urls).
     13        * platform/chromium/http/tests/misc/will-send-request-returns-null-on-redirect-expected.txt: See previous.
     14
    1152012-12-11  Aaron Colwell  <acolwell@chromium.org>
    216
  • trunk/LayoutTests/http/tests/inspector/resource-parameters.html

    r113863 r137333  
    1818    {
    1919        var request = event.data;
    20         if (request.url !== "http://localhost:8000/inspector/resources/post-target.cgi?queryParam1=queryValue1&queryParam2=#fragmentParam1=fragmentValue1&fragmentParam2=")
     20        if (request.url !== "http://localhost:8000/inspector/resources/post-target.cgi?queryParam1=queryValue1&queryParam2=")
    2121            return;
    2222        InspectorTest.addObject(new WebInspector.HAREntry(request).build(), InspectorTest.HARPropertyFormatters);
  • trunk/LayoutTests/http/tests/misc/will-send-request-returns-null-on-redirect-expected.txt

    r84742 r137333  
    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

    r117009 r137333  
    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

    r137332 r137333  
     12012-12-11  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 Antti Koivisto.
     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-11  Aaron Colwell  <acolwell@chromium.org>
    262
  • trunk/Source/WebCore/loader/DocumentLoader.cpp

    r136412 r137333  
    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

    r137318 r137333  
    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)
     
    103103    // and didFailToLoad calls a ResourceLoadDelegate method and they need to be in the correct order.
    104104    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 {
     105}
     106
     107void MainResourceLoader::cancel()
     108{
     109    cancel(ResourceError());
     110}
     111
     112void MainResourceLoader::cancel(const ResourceError& error)
     113{
     114    RefPtr<MainResourceLoader> protect(this);
     115    ResourceError resourceError = error.isNull() ? frameLoader()->cancelledError(request()) : error;
     116
    118117    m_dataLoadTimer.stop();
    119118
     
    122121        ASSERT(m_waitingForContentPolicy);
    123122        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);
     123        deref(); // balances ref in responseReceived
     124    }
     125
     126    if (loader())
     127        loader()->cancel(resourceError);
     128
     129    clearResource();
     130    receivedError(resourceError);
    133131
    134132#if PLATFORM(MAC) && !PLATFORM(IOS) && __MAC_OS_X_VERSION_MIN_REQUIRED >= 1080
     
    138136    }
    139137#endif
     138}
     139
     140void MainResourceLoader::clearResource()
     141{
     142    if (m_resource) {
     143        m_resource->removeClient(this);
     144        m_resource = 0;
     145    }
     146}
     147
     148FrameLoader* MainResourceLoader::frameLoader() const
     149{
     150    return m_documentLoader->frameLoader();
     151}
     152
     153const ResourceRequest& MainResourceLoader::request() const
     154{
     155    return m_resource ? m_resource->resourceRequest() : m_initialRequest;
    140156}
    141157
     
    164180        // A redirect resulted in loading substitute data.
    165181        ASSERT(documentLoader()->timing()->redirectCount());
    166         handle()->cancel();
     182        clearResource();
    167183        handleSubstituteDataLoadSoon(request);
    168184    }
     
    184200}
    185201
    186 void MainResourceLoader::addData(const char* data, int length, bool allAtOnce)
    187 {
    188     ResourceLoader::addData(data, length, allAtOnce);
    189     documentLoader()->receivedData(data, length);
     202PassRefPtr<ResourceBuffer> MainResourceLoader::resourceData()
     203{
     204    return m_resource ? m_resource->resourceBuffer() : 0;
     205}
     206
     207void MainResourceLoader::redirectReceived(CachedResource* resource, ResourceRequest& request, const ResourceResponse& redirectResponse)
     208{
     209    ASSERT_UNUSED(resource, resource == m_resource);
     210    willSendRequest(request, redirectResponse);
    190211}
    191212
     
    240261    }
    241262
    242     ResourceLoader::willSendRequest(newRequest, redirectResponse);
    243 
    244263    // Don't set this on the first request. It is set when the main load was started.
    245264    m_documentLoader->setRequest(newRequest);
     
    278297            frameLoader()->policyChecker()->cannotShowMIMEType(r);
    279298            // Check reachedTerminalState since the load may have already been canceled inside of _handleUnimplementablePolicyWithErrorCode::.
    280             if (!reachedTerminalState())
    281                 stopLoadingForPolicyChange();
     299            stopLoadingForPolicyChange();
    282300            return;
    283301        }
     
    286304
    287305    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());
     306        // m_resource can be null, e.g. when loading a substitute resource from application cache.
     307        if (!m_resource) {
     308            receivedError(frameLoader()->client()->cannotShowURLError(request()));
    291309            return;
    292310        }
     
    298316        frameLoader()->setOriginalURLForDownloadRequest(request);
    299317
    300         frameLoader()->client()->download(m_handle.get(), request, r);
     318        frameLoader()->client()->download(loader()->handle(), request, r);
    301319
    302320        // It might have gone missing
     
    330348    }
    331349
    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()) {
     350    if (!m_documentLoader->isStopping() && m_substituteData.isValid()) {
    337351        if (m_substituteData.content()->size())
    338             didReceiveData(m_substituteData.content()->data(), m_substituteData.content()->size(), m_substituteData.content()->size(), true);
     352            dataReceived(0, m_substituteData.content()->data(), m_substituteData.content()->size());
    339353        if (!m_documentLoader->isStopping())
    340354            didFinishLoading(0);
     
    353367    if (!m_documentLoader->isStopping())
    354368        continueAfterContentPolicy(policy, m_response);
    355     deref(); // balances ref in didReceiveResponse
    356 }
    357 
    358 void MainResourceLoader::didReceiveResponse(const ResourceResponse& r)
    359 {
     369    deref(); // balances ref in responseReceived
     370}
     371
     372void MainResourceLoader::responseReceived(CachedResource* resource, const ResourceResponse& r)
     373{
     374    ASSERT_UNUSED(resource, m_resource == resource);
    360375    if (documentLoader()->applicationCacheHost()->maybeLoadFallbackForMainResponse(request(), r))
    361376        return;
     
    383398    if (m_loadingMultipartContent) {
    384399        m_documentLoader->setupForReplace();
    385         clearResourceData();
     400        m_resource->clear();
    386401    }
    387402   
     
    399414    ASSERT(!m_waitingForContentPolicy);
    400415    m_waitingForContentPolicy = true;
    401     ref(); // balanced by deref in continueAfterContentPolicy and didCancel
     416    ref(); // balanced by deref in continueAfterContentPolicy and cancel
    402417
    403418    // Always show content with valid substitute data.
     
    424439}
    425440
    426 void MainResourceLoader::didReceiveData(const char* data, int length, long long encodedDataLength, bool allAtOnce)
     441void MainResourceLoader::dataReceived(CachedResource* resource, const char* data, int length)
    427442{
    428443    ASSERT(data);
    429444    ASSERT(length != 0);
    430 
     445    ASSERT_UNUSED(resource, resource == m_resource);
    431446    ASSERT(!m_response.isNull());
    432447
     
    453468        if (!blockedData) {
    454469            // Transition to committed state.
    455             ResourceLoader::didReceiveData("", 0, 0, false);
     470            documentLoader()->receivedData(0, 0);
    456471            return;
    457472        }
    458473
    459474        data = blockedData;
    460         encodedDataLength = -1;
    461     }
    462 #endif
    463 
    464     documentLoader()->applicationCacheHost()->mainResourceDataReceived(data, length, encodedDataLength, allAtOnce);
     475    }
     476#endif
     477
     478    documentLoader()->applicationCacheHost()->mainResourceDataReceived(data, length, -1, false);
    465479
    466480    // The additional processing can do anything including possibly removing the last
     
    470484    m_timeOfLastDataReceived = monotonicallyIncreasingTime();
    471485
    472     ResourceLoader::didReceiveData(data, length, encodedDataLength, allAtOnce);
     486    documentLoader()->receivedData(data, length);
    473487
    474488#if PLATFORM(MAC) && !PLATFORM(IOS) && __MAC_OS_X_VERSION_MIN_REQUIRED >= 1080
     
    491505    // See <rdar://problem/6304600> for more details.
    492506#if !USE(CF)
    493     ASSERT(!defersLoading() || InspectorInstrumentation::isDebuggerPaused(m_frame.get()));
     507    ASSERT(!defersLoading() || InspectorInstrumentation::isDebuggerPaused(m_documentLoader->frame()));
    494508#endif
    495509
     
    507521        m_filter = 0;
    508522        if (data)
    509             didReceiveData(data, length, -1, false);
     523            dataReceived(m_resource.get(), data, length);
    510524        wkFilterRelease(filter);
    511525    }
     
    517531    documentLoader()->timing()->setResponseEnd(finishTime ? finishTime : (m_timeOfLastDataReceived ? m_timeOfLastDataReceived : monotonicallyIncreasingTime()));
    518532    documentLoader()->finishedLoading();
    519     ResourceLoader::didFinishLoading(finishTime);
    520533
    521534    dl->applicationCacheHost()->finishedLoadingMainResource();
    522535}
    523536
    524 void MainResourceLoader::didFail(const ResourceError& error)
    525 {
     537void MainResourceLoader::notifyFinished(CachedResource* resource)
     538{
     539    ASSERT_UNUSED(resource, m_resource == resource);
     540    if (!m_resource || (!m_resource->errorOccurred() && !m_resource->wasCanceled())) {
     541        didFinishLoading(m_resource->loadFinishTime());
     542        return;
     543    }
     544
    526545#if PLATFORM(MAC) && !PLATFORM(IOS) && __MAC_OS_X_VERSION_MIN_REQUIRED >= 1080
    527546    if (m_filter) {
     
    531550#endif
    532551
     552    const ResourceError& error = m_resource->resourceError();
    533553    if (documentLoader()->applicationCacheHost()->maybeLoadFallbackForMainError(request(), error))
    534554        return;
     
    546566{
    547567    MemoryClassInfo info(memoryObjectInfo, this, WebCoreMemoryTypes::Loader);
    548     ResourceLoader::reportMemoryUsage(memoryObjectInfo);
    549568    info.addMember(m_initialRequest);
    550569    info.addMember(m_substituteData);
     
    565584       
    566585    ResourceResponse response(url, m_substituteData.mimeType(), m_substituteData.content()->size(), m_substituteData.textEncoding(), "");
    567     didReceiveResponse(response);
     586    responseReceived(0, response);
    568587}
    569588
     
    588607}
    589608
    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 
     609void MainResourceLoader::load(const ResourceRequest& initialRequest, const SubstituteData& substituteData)
     610{
    613611    // It appears that it is possible for this load to be cancelled and derefenced by the DocumentLoader
    614612    // in willSendRequest() if loadNow() is called.
     
    620618    ASSERT(!documentLoader()->timing()->fetchStart());
    621619    documentLoader()->timing()->markFetchStart();
    622     ResourceRequest request(r);
     620    ResourceRequest request(initialRequest);
    623621
    624622    // Send this synthetic delegate callback since clients expect it, and
     
    628626    ASSERT(!deletionHasBegun());
    629627
    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     }
     628    // willSendRequest() may lead to our DocumentLoader being detached or cancelling the load via nulling the ResourceRequest.
     629    if (!documentLoader()->frame() || request.isNull())
     630        return;
    637631
    638632    documentLoader()->applicationCacheHost()->maybeLoadMainResource(request, m_substituteData);
    639633
    640     if (defersLoading())
    641         m_initialRequest = request;
    642     else
    643         loadNow(request);
     634    if (m_substituteData.isValid()) {
     635        handleSubstituteDataLoadSoon(request);
     636        return;
     637    }
     638
     639    DEFINE_STATIC_LOCAL(ResourceLoaderOptions, mainResourceLoadOptions,
     640        (SendCallbacks, SniffContent, BufferData, AllowStoredCredentials, AskClientForCrossOriginCredentials, SkipSecurityCheck));
     641    CachedResourceRequest cachedResourceRequest(request, mainResourceLoadOptions);
     642    m_resource = documentLoader()->cachedResourceLoader()->requestMainResource(cachedResourceRequest);
     643    if (!m_resource) {
     644        documentLoader()->setRequest(ResourceRequest());
     645        return;
     646    }
     647    m_resource->addClient(this);
     648
     649    // We need to wait until after requestMainResource() is called to setRequest(), because there are a bunch of headers set when
     650    // the underlying ResourceLoader is created, and DocumentLoader::m_request needs to include those. However, the cache will
     651    // strip the fragment identifier (which DocumentLoader::m_request should also include), so add that back in.
     652    if (loader())
     653        request = loader()->originalRequest();
     654    if (initialRequest.url() != request.url()) {
     655        ASSERT(equalIgnoringFragmentIdentifier(initialRequest.url(), request.url()));
     656        request.setURL(initialRequest.url());
     657    }
     658    documentLoader()->setRequest(request);
    644659}
    645660
    646661void MainResourceLoader::setDefersLoading(bool defers)
    647662{
    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 }
     663    if (loader())
     664        loader()->setDefersLoading(defers);
     665}
     666
     667bool MainResourceLoader::defersLoading() const
     668{
     669    return loader() ? loader()->defersLoading() : false;
     670}
     671
     672void MainResourceLoader::setShouldBufferData(DataBufferingPolicy shouldBufferData)
     673{
     674    ASSERT(m_resource);
     675    m_resource->setShouldBufferData(shouldBufferData);
     676}
     677
     678ResourceLoader* MainResourceLoader::loader() const
     679{
     680    return m_resource ? m_resource->loader() : 0;
     681}
     682
     683unsigned long MainResourceLoader::identifier() const
     684{
     685    if (ResourceLoader* resourceLoader = loader())
     686        return resourceLoader->identifier();
     687    return 0;
     688}
     689
     690}
  • trunk/Source/WebCore/loader/MainResourceLoader.h

    r136412 r137333  
    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

    r136998 r137333  
    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

    r136998 r137333  
    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

    r130612 r137333  
    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

    r132520 r137333  
    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

    r137318 r137333  
    707707
    708708#if ENABLE(RESOURCE_TIMING)
    709     if (resource) {
     709    // FIXME: Add resource timing support for main resources.
     710    if (resource && resource->type() != CachedResource::MainResource) {
    710711        HashMap<CachedResource*, InitiatorInfo>::iterator initiatorIt = m_initiatorMap.find(resource);
    711712        if (initiatorIt != m_initiatorMap.end()) {
  • trunk/Source/WebCore/loader/mac/DocumentLoaderMac.cpp

    r95901 r137333  
    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.