Пример #1
0
void ResourceLoader::didReceiveResponse(const ResourceResponse& r)
{
    if (!fastMallocSize(documentLoader()->applicationCacheHost()))
        CRASH();
    if (!fastMallocSize(documentLoader()->frame()))
        CRASH();
    ASSERT(!m_reachedTerminalState);

    // Protect this in this delegate method since the additional processing can do
    // anything including possibly derefing this; one example of this is Radar 3266216.
    RefPtr<ResourceLoader> protector(this);

    m_response = r;

    if (FormData* data = m_request.httpBody())
        data->removeGeneratedFilesIfNeeded();
        
    if (m_options.sendLoadCallbacks == SendCallbacks)
        frameLoader()->notifier()->didReceiveResponse(this, m_response);
}
Пример #2
0
void MainResourceLoader::receivedError(const ResourceError& error)
{
    // Calling receivedMainResourceError will likely result in the last reference to this object to go away.
    RefPtr<MainResourceLoader> protect(this);
    RefPtr<Frame> protectFrame(m_documentLoader->frame());

    // It is important that we call DocumentLoader::mainReceivedError before calling 
    // ResourceLoadNotifier::didFailToLoad because mainReceivedError clears out the relevant
    // document loaders. Also, mainReceivedError ends up calling a FrameLoadDelegate method
    // and didFailToLoad calls a ResourceLoadDelegate method and they need to be in the correct order.
    documentLoader()->mainReceivedError(error);
}
Пример #3
0
void MainResourceLoader::continueAfterNavigationPolicy(const ResourceRequest& request, bool shouldContinue)
{
    if (!shouldContinue)
        stopLoadingForPolicyChange();
    else if (m_substituteData.isValid()) {
        // A redirect resulted in loading substitute data.
        ASSERT(documentLoader()->timing()->redirectCount());
        handle()->cancel();
        handleSubstituteDataLoadSoon(request);
    }

    deref(); // balances ref in willSendRequest
}
Пример #4
0
void MainResourceLoader::didFinishLoading(double finishTime)
{
    // There is a bug in CFNetwork where callbacks can be dispatched even when loads are deferred.
    // See <rdar://problem/6304600> for more details.
#if !USE(CF)
    ASSERT(shouldLoadAsEmptyDocument(frameLoader()->activeDocumentLoader()->url()) || !defersLoading());
#endif

    // The additional processing can do anything including possibly removing the last
    // reference to this object.
    RefPtr<MainResourceLoader> protect(this);
    RefPtr<DocumentLoader> dl = documentLoader();

    if (m_loadingMultipartContent)
        dl->maybeFinishLoadingMultipartContent();

    documentLoader()->timing()->setResponseEnd(finishTime ? finishTime : (m_timeOfLastDataReceived ? m_timeOfLastDataReceived : monotonicallyIncreasingTime()));
    frameLoader()->finishedLoading();
    ResourceLoader::didFinishLoading(finishTime);

    dl->applicationCacheHost()->finishedLoadingMainResource();
}
Пример #5
0
bool ApplicationCacheHost::maybeLoadFallbackForMainError(const ResourceRequest& request, const ResourceError& error)
{
    if (!error.isCancellation()) {
        ASSERT(!m_mainResourceApplicationCache);
        if (isApplicationCacheEnabled() && !isApplicationCacheBlockedForRequest(request)) {
            m_mainResourceApplicationCache = ApplicationCacheGroup::fallbackCacheForMainRequest(request, m_documentLoader);

            if (scheduleLoadFallbackResourceFromApplicationCache(documentLoader()->mainResourceLoader(), m_mainResourceApplicationCache.get()))
                return true;
        }
    }
    return false;
}
Пример #6
0
void MainResourceLoader::didCancel(const ResourceError& error)
{
    // We should notify the frame loader after fully canceling the load, because it can do complicated work
    // like calling DOMWindow::print(), during which a half-canceled load could try to finish.
    documentLoader()->mainReceivedError(error);

#if PLATFORM(MAC) && !PLATFORM(IOS) && __MAC_OS_X_VERSION_MIN_REQUIRED >= 1080
    if (m_filter) {
        wkFilterRelease(m_filter);
        m_filter = 0;
    }
#endif
}
Пример #7
0
void MainResourceLoader::didFail(const ResourceError& error)
{
    if (documentLoader()->applicationCacheHost()->maybeLoadFallbackForMainError(request(), error))
        return;

    // There is a bug in CFNetwork where callbacks can be dispatched even when loads are deferred.
    // See <rdar://problem/6304600> for more details.
#if !USE(CF)
    ASSERT(!defersLoading());
#endif
    
    receivedError(error);
}
Пример #8
0
unsigned long long PerformanceTiming::secureConnectionStart() const
{
    DocumentLoader* loader = documentLoader();
    if (!loader)
        return 0;

    const ResourceLoadTiming& timing = loader->response().resourceLoadTiming();
    
    if (timing.secureConnectionStart < 0)
        return 0;

    return resourceLoadTimeRelativeToAbsolute(timing.secureConnectionStart);
}
Пример #9
0
bool ApplicationCacheHost::maybeLoadFallbackForMainResponse(const ResourceRequest& request, const ResourceResponse& r)
{
    if (r.httpStatusCode() / 100 == 4 || r.httpStatusCode() / 100 == 5) {
        ASSERT(!m_mainResourceApplicationCache);
        if (isApplicationCacheEnabled() && !isApplicationCacheBlockedForRequest(request)) {
            m_mainResourceApplicationCache = ApplicationCacheGroup::fallbackCacheForMainRequest(request, documentLoader());

            if (scheduleLoadFallbackResourceFromApplicationCache(documentLoader()->mainResourceLoader(), m_mainResourceApplicationCache.get()))
                return true;
        }
    }
    return false;
}
Пример #10
0
void MainResourceLoader::didFinishLoading(double finishTime)
{
    // There is a bug in CFNetwork where callbacks can be dispatched even when loads are deferred.
    // See <rdar://problem/6304600> for more details.
#if !USE(CF)
    ASSERT(!defersLoading() || InspectorInstrumentation::isDebuggerPaused(m_documentLoader->frame()));
#endif

    // The additional processing can do anything including possibly removing the last
    // reference to this object.
    RefPtr<MainResourceLoader> protect(this);
    RefPtr<DocumentLoader> dl = documentLoader();

    if (!loader()) {
        frameLoader()->notifier()->dispatchDidFinishLoading(documentLoader(), identifier(), finishTime);
        m_substituteDataLoadIdentifier = 0;
    }

#if USE(CONTENT_FILTERING)
    if (m_filter) {
        int length;
        const char* data = wkFilterDataComplete(m_filter, &length);
        WebFilterEvaluator *filter = m_filter;
        // Remove this->m_filter early so didReceiveData doesn't see it.
        m_filter = 0;
        if (data)
            dataReceived(m_resource.get(), data, length);
        wkFilterRelease(filter);
    }
#endif

    if (m_loadingMultipartContent)
        dl->maybeFinishLoadingMultipartContent();

    documentLoader()->timing()->setResponseEnd(finishTime ? finishTime : (m_timeOfLastDataReceived ? m_timeOfLastDataReceived : monotonicallyIncreasingTime()));
    documentLoader()->finishedLoading();

    dl->applicationCacheHost()->finishedLoadingMainResource();
}
bool ResourceLoader::isInclusionRequest()
{
    DocumentLoader* loader = documentLoader();
    if (loader->frameLoader()->isLoadingMainFrame() && !loader->isLoadingSubresources())
        return false;
    else
        return true;

// for debug
// NF4_DP(("  => isLoadingMainResource(): %s", ((loader->isLoadingMainResource())?"true":"false")));
// NF4_DP(("  => isLoadingSubresources(): %s", ((loader->isLoadingSubresources())?"true":"false")));
// NF4_DP(("  => isLoadingMainFrame(): %s", ((loader->frameLoader()->isLoadingMainFrame())?"true":"false")));
// NF4_DP(("  => subframeIsLoading() : %s", ((loader->frameLoader()->subframeIsLoading())?"true":"false")));
}
Пример #12
0
bool ApplicationCacheHost::maybeLoadSynchronously(ResourceRequest& request, ResourceError& error, ResourceResponse& response, Vector<char>& data)
{
    ApplicationCacheResource* resource;
    if (shouldLoadResourceFromApplicationCache(request, resource)) {
        if (resource) {
            response = resource->response();
            data.append(resource->data()->data(), resource->data()->size());
        } else {
            error = documentLoader()->frameLoader()->client().cannotShowURLError(request);
        }
        return true;
    }
    return false;
}
Пример #13
0
void ResourceLoader::willSendRequest(ResourceRequest& request, const ResourceResponse& redirectResponse)
{
    // Protect this in this delegate method since the additional processing can do
    // anything including possibly derefing this; one example of this is Radar 3266216.
    Ref<ResourceLoader> protect(*this);

    ASSERT(!m_reachedTerminalState);

#if ENABLE(CONTENT_EXTENSIONS)
    ASSERT(m_resourceType != ResourceType::Invalid);

    if (frameLoader() && frameLoader()->frame().page() && frameLoader()->frame().page()->userContentController() && m_documentLoader)
        frameLoader()->frame().page()->userContentController()->processContentExtensionRulesForLoad(request, m_resourceType, *m_documentLoader);

    if (request.isNull()) {
        didFail(cannotShowURLError());
        return;
    }
#endif

    // We need a resource identifier for all requests, even if FrameLoader is never going to see it (such as with CORS preflight requests).
    bool createdResourceIdentifier = false;
    if (!m_identifier) {
        m_identifier = m_frame->page()->progress().createUniqueIdentifier();
        createdResourceIdentifier = true;
    }

    if (m_options.sendLoadCallbacks() == SendCallbacks) {
        if (createdResourceIdentifier)
            frameLoader()->notifier().assignIdentifierToInitialRequest(m_identifier, documentLoader(), request);

#if PLATFORM(IOS)
        // If this ResourceLoader was stopped as a result of assignIdentifierToInitialRequest, bail out
        if (m_reachedTerminalState)
            return;
#endif

        frameLoader()->notifier().willSendRequest(this, request, redirectResponse);
    }
    else
        InspectorInstrumentation::willSendRequest(m_frame.get(), m_identifier, m_frame->loader().documentLoader(), request, redirectResponse);

    if (!redirectResponse.isNull())
        platformStrategies()->loaderStrategy()->resourceLoadScheduler()->crossOriginRedirectReceived(this, request.url());

    m_request = request;

    if (!redirectResponse.isNull() && !m_documentLoader->isCommitted())
        frameLoader()->client().dispatchDidReceiveServerRedirectForProvisionalLoad();
}
Пример #14
0
void ResourceLoader::didReceiveData(const char* data, int length, long long encodedDataLength, bool allAtOnce)
{
    if (!m_cancelled && !fastMallocSize(documentLoader()->applicationCacheHost()))
        CRASH();
    if (!m_cancelled && !fastMallocSize(documentLoader()->frame()))
        CRASH();
    // The following assertions are not quite valid here, since a subclass
    // might override didReceiveData in a way that invalidates them. This
    // happens with the steps listed in 3266216
    // ASSERT(con == connection);
    // ASSERT(!m_reachedTerminalState);

    // Protect this in this delegate method since the additional processing can do
    // anything including possibly derefing this; one example of this is Radar 3266216.
    RefPtr<ResourceLoader> protector(this);

    addData(data, length, allAtOnce);
    // FIXME: If we get a resource with more than 2B bytes, this code won't do the right thing.
    // However, with today's computers and networking speeds, this won't happen in practice.
    // Could be an issue with a giant local file.
    if (m_options.sendLoadCallbacks == SendCallbacks && m_frame)
        frameLoader()->notifier()->didReceiveData(this, data, length, static_cast<int>(encodedDataLength));
}
void ApplicationCacheHost::stopDeferringEvents()
{
    RefPtr<DocumentLoader> protect(documentLoader());
    for (unsigned i = 0; i < m_deferredEvents.size(); ++i) {
        EventID id = m_deferredEvents[i];
        if (m_domApplicationCache) {
            ExceptionCode ec = 0;
            m_domApplicationCache->dispatchEvent(Event::create(DOMApplicationCache::toEventType(id), false, false), ec);
            ASSERT(!ec);
        }
    }
    m_deferredEvents.clear();
    m_defersEvents = false;
}
Пример #16
0
void MainResourceLoader::load(const ResourceRequest& initialRequest, const SubstituteData& substituteData)
{
    // It appears that it is possible for this load to be cancelled and derefenced by the DocumentLoader
    // in willSendRequest() if loadNow() is called.
    RefPtr<MainResourceLoader> protect(this);

    m_substituteData = substituteData;

    ASSERT(documentLoader()->timing()->navigationStart());
    ASSERT(!documentLoader()->timing()->fetchStart());
    documentLoader()->timing()->markFetchStart();
    ResourceRequest request(initialRequest);

    // Send this synthetic delegate callback since clients expect it, and
    // we no longer send the callback from within NSURLConnection for
    // initial requests.
    willSendRequest(request, ResourceResponse());
    ASSERT(!deletionHasBegun());

    // willSendRequest() may lead to our DocumentLoader being detached or cancelling the load via nulling the ResourceRequest.
    if (!documentLoader()->frame() || request.isNull())
        return;

    documentLoader()->applicationCacheHost()->maybeLoadMainResource(request, m_substituteData);

    if (m_substituteData.isValid()) {
        handleSubstituteDataLoadSoon(request);
        return;
    }

    DEFINE_STATIC_LOCAL(ResourceLoaderOptions, mainResourceLoadOptions,
        (SendCallbacks, SniffContent, BufferData, AllowStoredCredentials, AskClientForCrossOriginCredentials, SkipSecurityCheck));
    CachedResourceRequest cachedResourceRequest(request, mainResourceLoadOptions);
    m_resource = documentLoader()->cachedResourceLoader()->requestMainResource(cachedResourceRequest);
    if (!m_resource) {
        documentLoader()->setRequest(ResourceRequest());
        return;
    }
    m_resource->addClient(this);

    // We need to wait until after requestMainResource() is called to setRequest(), because there are a bunch of headers set when
    // the underlying ResourceLoader is created, and DocumentLoader::m_request needs to include those. However, the cache will
    // strip the fragment identifier (which DocumentLoader::m_request should also include), so add that back in.
    if (loader())
        request = loader()->originalRequest();
    documentLoader()->setRequest(request);
}
Пример #17
0
void MainResourceLoader::load(const ResourceRequest& r, const SubstituteData& substituteData)
{
    ASSERT(!m_handle);

    // It appears that it is possible for this load to be cancelled and derefenced by the DocumentLoader
    // in willSendRequest() if loadNow() is called.
    RefPtr<MainResourceLoader> protect(this);

    m_substituteData = substituteData;

    ASSERT(documentLoader()->timing()->navigationStart());
    ASSERT(!documentLoader()->timing()->fetchStart());
    documentLoader()->timing()->markFetchStart();
    ResourceRequest request(r);

    // Send this synthetic delegate callback since clients expect it, and
    // we no longer send the callback from within NSURLConnection for
    // initial requests.
    willSendRequest(request, ResourceResponse());
    ASSERT(!deletionHasBegun());

    // <rdar://problem/4801066>
    // willSendRequest() is liable to make the call to frameLoader() return null, so we need to check that here
    if (!frameLoader() || request.isNull()) {
        if (!reachedTerminalState())
            releaseResources();
        return;
    }

    documentLoader()->applicationCacheHost()->maybeLoadMainResource(request, m_substituteData);

    if (defersLoading())
        m_initialRequest = request;
    else
        loadNow(request);
}
Пример #18
0
unsigned long long PerformanceTiming::secureConnectionStart() const {
  DocumentLoader* loader = documentLoader();
  if (!loader)
    return 0;

  ResourceLoadTiming* timing = loader->response().resourceLoadTiming();
  if (!timing)
    return 0;

  double sslStart = timing->sslStart();
  if (sslStart == 0.0)
    return 0;

  return monotonicTimeToIntegerMilliseconds(sslStart);
}
Пример #19
0
unsigned long long PerformanceTiming::domainLookupEnd() const
{
    DocumentLoader* loader = documentLoader();
    if (!loader)
        return domainLookupStart();
    
    const ResourceLoadTiming& timing = loader->response().resourceLoadTiming();
    
    // This will be -1 when a DNS request is not performed.
    // Rather than exposing a special value that indicates no DNS, we "backfill" with domainLookupStart.
    if (timing.domainLookupEnd < 0)
        return domainLookupStart();

    return resourceLoadTimeRelativeToAbsolute(timing.domainLookupEnd);
}
Пример #20
0
unsigned long long PerformanceTiming::connectEnd() const
{
    DocumentLoader* loader = documentLoader();
    if (!loader)
        return connectStart();

    const ResourceLoadTiming& timing = loader->response().resourceLoadTiming();
    
    // connectEnd will be -1 when a network request is not made.
    // Rather than exposing a special value that indicates no new connection, we "backfill" with connectStart.
    if (timing.connectEnd < 0)
        return connectStart();

    return resourceLoadTimeRelativeToAbsolute(timing.connectEnd);
}
unsigned long long PerformanceTiming::secureConnectionStart() const
{
    DocumentLoader* loader = documentLoader();
    if (!loader)
        return 0;

    ResourceLoadTiming* timing = loader->response().resourceLoadTiming();
    if (!timing)
        return 0;

    int sslStart = timing->sslStart;
    if (sslStart < 0)
        return 0;

    return resourceLoadTimeRelativeToAbsolute(sslStart);
}
Пример #22
0
unsigned long long PerformanceTiming::connectEnd() const {
  DocumentLoader* loader = documentLoader();
  if (!loader)
    return connectStart();

  ResourceLoadTiming* timing = loader->response().resourceLoadTiming();
  if (!timing)
    return connectStart();

  // connectEnd will be zero when a network request is not made.  Rather than
  // exposing a special value that indicates no new connection, we "backfill"
  // with connectStart.
  double connectEnd = timing->connectEnd();
  if (connectEnd == 0.0 || loader->response().connectionReused())
    return connectStart();

  return monotonicTimeToIntegerMilliseconds(connectEnd);
}
void MainResourceLoader::didReceiveResponse(const ResourceResponse& r)
{
#if ENABLE(OFFLINE_WEB_APPLICATIONS)
    if (documentLoader()->applicationCacheHost()->maybeLoadFallbackForMainResponse(request(), r))
        return;
#endif

    HTTPHeaderMap::const_iterator it = r.httpHeaderFields().find(AtomicString("x-frame-options"));
    if (it != r.httpHeaderFields().end()) {
        String content = it->second;
        if (m_frame->loader()->shouldInterruptLoadForXFrameOptions(content, r.url())) {
            cancel();
            return;
        }
    }

    // There is a bug in CFNetwork where callbacks can be dispatched even when loads are deferred.
    // See <rdar://problem/6304600> for more details.
#if !PLATFORM(CF)
    ASSERT(shouldLoadAsEmptyDocument(r.url()) || !defersLoading());
#endif

    if (m_loadingMultipartContent) {
        frameLoader()->setupForReplaceByMIMEType(r.mimeType());
        clearResourceData();
    }
    
    if (r.isMultipart())
        m_loadingMultipartContent = true;
        
    // The additional processing can do anything including possibly removing the last
    // reference to this object; one example of this is 3266216.
    RefPtr<MainResourceLoader> protect(this);

    m_documentLoader->setResponse(r);

    m_response = r;

    ASSERT(!m_waitingForContentPolicy);
    m_waitingForContentPolicy = true;
    ref(); // balanced by deref in continueAfterContentPolicy and didCancel
    frameLoader()->checkContentPolicy(m_response.mimeType(), callContinueAfterContentPolicy, this);
}
Пример #24
0
void MainResourceLoader::didFail(const ResourceError& error)
{
#if PLATFORM(MAC) && !PLATFORM(IOS) && __MAC_OS_X_VERSION_MIN_REQUIRED >= 1080
    if (m_filter) {
        wkFilterRelease(m_filter);
        m_filter = 0;
    }
#endif

    if (documentLoader()->applicationCacheHost()->maybeLoadFallbackForMainError(request(), error))
        return;

    // There is a bug in CFNetwork where callbacks can be dispatched even when loads are deferred.
    // See <rdar://problem/6304600> for more details.
#if !USE(CF)
    ASSERT(!defersLoading());
#endif
    
    receivedError(error);
}
Пример #25
0
unsigned long long PerformanceTiming::connectStart() const
{
    DocumentLoader* loader = documentLoader();
    if (!loader)
        return domainLookupEnd();

    const ResourceLoadTiming& timing = loader->response().resourceLoadTiming();
    
    // connectStart will be -1 when a network request is not made.
    // Rather than exposing a special value that indicates no new connection, we "backfill" with domainLookupEnd.
    int connectStart = timing.connectStart;
    if (connectStart < 0)
        return domainLookupEnd();

    // ResourceLoadTiming's connect phase includes DNS, however Navigation Timing's
    // connect phase should not. So if there is DNS time, trim it from the start.
    if (timing.domainLookupEnd >= 0 && timing.domainLookupEnd > connectStart)
        connectStart = timing.domainLookupEnd;

    return resourceLoadTimeRelativeToAbsolute(connectStart);
}
Пример #26
0
void ResourceLoader::didReceiveResponse(ResourceHandle*, const ResourceResponse& response)
{
#if ENABLE(INSPECTOR)
    if (InspectorTimelineAgent::instanceCount()) {
        InspectorTimelineAgent* timelineAgent = m_frame->page() ? m_frame->page()->inspectorTimelineAgent() : 0;
        if (timelineAgent)
            timelineAgent->willReceiveResourceResponse(identifier(), response);
    }
#endif
#if ENABLE(OFFLINE_WEB_APPLICATIONS)
    if (documentLoader()->applicationCacheHost()->maybeLoadFallbackForResponse(this, response))
        return;
#endif
    didReceiveResponse(response);
#if ENABLE(INSPECTOR)
    if (InspectorTimelineAgent::instanceCount()) {
        InspectorTimelineAgent* timelineAgent = m_frame->page() ? m_frame->page()->inspectorTimelineAgent() : 0;
        if (timelineAgent)
            timelineAgent->didReceiveResourceResponse();
    }
#endif
}
unsigned long long PerformanceTiming::connectStart() const
{
    DocumentLoader* loader = documentLoader();
    if (!loader)
        return domainLookupEnd();

    ResourceLoadTiming* timing = loader->response().resourceLoadTiming();
    if (!timing)
        return domainLookupEnd();

    // connectStart will be zero when a network request is not made.
    // Rather than exposing a special value that indicates no new connection, we "backfill" with domainLookupEnd.
    double connectStart = timing->connectStart;
    if (connectStart == 0.0 || loader->response().connectionReused())
        return domainLookupEnd();

    // ResourceLoadTiming's connect phase includes DNS, however Navigation Timing's
    // connect phase should not. So if there is DNS time, trim it from the start.
    if (timing->dnsEnd > 0.0 && timing->dnsEnd > connectStart)
        connectStart = timing->dnsEnd;

    return monotonicTimeToIntegerMilliseconds(connectStart);
}
Пример #28
0
void MainResourceLoader::didFinishLoading()
{
    // There is a bug in CFNetwork where callbacks can be dispatched even when loads are deferred.
    // See <rdar://problem/6304600> for more details.
#if !PLATFORM(CF)
    ASSERT(shouldLoadAsEmptyDocument(frameLoader()->activeDocumentLoader()->url()) || !defersLoading());
#endif
    
    // The additional processing can do anything including possibly removing the last
    // reference to this object.
    RefPtr<MainResourceLoader> protect(this);

#if ENABLE(OFFLINE_WEB_APPLICATIONS)
    RefPtr<DocumentLoader> dl = documentLoader();
#endif

    frameLoader()->finishedLoading();
    ResourceLoader::didFinishLoading();
    
#if ENABLE(OFFLINE_WEB_APPLICATIONS)
    dl->applicationCacheHost()->finishedLoadingMainResource();
#endif
}
Пример #29
0
void MainResourceLoader::continueAfterNavigationPolicy(const ResourceRequest& request, bool shouldContinue)
{
    if (!shouldContinue)
        stopLoadingForPolicyChange();
    else if (m_substituteData.isValid()) {
        // A redirect resulted in loading substitute data.
        ASSERT(documentLoader()->timing()->redirectCount());

        // We need to remove our reference to the CachedResource in favor of a SubstituteData load.
        // This will probably trigger the cancellation of the CachedResource's underlying ResourceLoader, though there is a
        // small chance that the resource is being loaded by a different Frame, preventing the ResourceLoader from being cancelled.
        // If the ResourceLoader is indeed cancelled, it would normally send resource load callbacks.
        // However, from an API perspective, this isn't a cancellation. Therefore, sever our relationship with the network load via clearResource(),
        // but prevent the ResourceLoader from sending ResourceLoadNotifier callbacks.
        RefPtr<ResourceLoader> resourceLoader = loader();
        ASSERT(resourceLoader->shouldSendResourceLoadCallbacks());
        resourceLoader->setSendCallbackPolicy(DoNotSendCallbacks);
        clearResource();
        resourceLoader->setSendCallbackPolicy(SendCallbacks);
        handleSubstituteDataLoadSoon(request);
    }

    deref(); // balances ref in willSendRequest
}
Пример #30
0
void MainResourceLoader::didReceiveData(const char* data, int length, long long encodedDataLength, bool allAtOnce)
{
    ASSERT(data);
    ASSERT(length != 0);

    ASSERT(!m_response.isNull());

#if USE(CFNETWORK) || PLATFORM(MAC)
    // Workaround for <rdar://problem/6060782>
    if (m_response.isNull()) {
        m_response = ResourceResponse(KURL(), "text/html", 0, String(), String());
        if (DocumentLoader* documentLoader = frameLoader()->activeDocumentLoader())
            documentLoader->setResponse(m_response);
    }
#endif

    // There is a bug in CFNetwork where callbacks can be dispatched even when loads are deferred.
    // See <rdar://problem/6304600> for more details.
#if !USE(CF)
    ASSERT(!defersLoading());
#endif

#if PLATFORM(MAC) && !PLATFORM(IOS) && __MAC_OS_X_VERSION_MIN_REQUIRED >= 1080
    if (m_filter) {
        ASSERT(!wkFilterWasBlocked(m_filter));
        const char* blockedData = wkFilterAddData(m_filter, data, &length);
        // If we don't have blockedData, that means we're still accumulating data
        if (!blockedData) {
            // Transition to committed state.
            ResourceLoader::didReceiveData("", 0, 0, false);
            return;
        }

        data = blockedData;
        encodedDataLength = -1;
    }
#endif

    documentLoader()->applicationCacheHost()->mainResourceDataReceived(data, length, encodedDataLength, allAtOnce);

    // The additional processing can do anything including possibly removing the last
    // reference to this object; one example of this is 3266216.
    RefPtr<MainResourceLoader> protect(this);

    m_timeOfLastDataReceived = monotonicallyIncreasingTime();

    ResourceLoader::didReceiveData(data, length, encodedDataLength, allAtOnce);

#if PLATFORM(MAC) && !PLATFORM(IOS) && __MAC_OS_X_VERSION_MIN_REQUIRED >= 1080
    if (WebFilterEvaluator *filter = m_filter) {
        // If we got here, it means we know if we were blocked or not. If we were blocked, we're
        // done loading the page altogether. Either way, we don't need the filter anymore.

        // Remove this->m_filter early so didFinishLoading doesn't see it.
        m_filter = 0;
        if (wkFilterWasBlocked(filter))
            cancel();
        wkFilterRelease(filter);
    }
#endif
}