Beispiel #1
0
void SubresourceLoader::didFinishLoading(double finishTime)
{
    if (m_state != Initialized)
        return;
    ASSERT(!reachedTerminalState());
    ASSERT(!m_resource->resourceToRevalidate());
    // FIXME (129394): We should cancel the load when a decode error occurs instead of continuing the load to completion.
    ASSERT(!m_resource->errorOccurred() || m_resource->status() == CachedResource::DecodeError);
    LOG(ResourceLoading, "Received '%s'.", m_resource->url().string().latin1().data());
    logResourceLoaded(m_frame.get(), m_resource->type());

    Ref<SubresourceLoader> protectedThis(*this);
    CachedResourceHandle<CachedResource> protectResource(m_resource);

    m_state = Finishing;
    m_resource->setLoadFinishTime(finishTime);
    m_resource->finishLoading(resourceData());

    if (wasCancelled())
        return;
    m_resource->finish();
    ASSERT(!reachedTerminalState());
    didFinishLoadingOnePart(finishTime);
    notifyDone();
    if (reachedTerminalState())
        return;
    releaseResources();
}
Beispiel #2
0
void SubresourceLoader::didFinishLoading(double finishTime)
{
    if (m_state != Initialized)
        return;
    ASSERT(!reachedTerminalState());
    ASSERT(!m_resource->resourceToRevalidate());
    ASSERT(!m_resource->errorOccurred());
    LOG(ResourceLoading, "Received '%s'.", m_resource->url().string().latin1().data());

    Ref<SubresourceLoader> protect(*this);

#if PLATFORM(IOS)
    if (resourceData())
        resourceData()->setShouldUsePurgeableMemory(true);
#endif
    CachedResourceHandle<CachedResource> protectResource(m_resource);
    m_state = Finishing;
    m_resource->setLoadFinishTime(finishTime);
    m_resource->finishLoading(resourceData());

    if (wasCancelled())
        return;
    m_resource->finish();
    ASSERT(!reachedTerminalState());
    didFinishLoadingOnePart(finishTime);
    notifyDone();
    if (reachedTerminalState())
        return;
    releaseResources();
}
Beispiel #3
0
void SubresourceLoader::didFinishLoading(double finishTime)
{
    if (m_state != Initialized)
        return;
    ASSERT(!reachedTerminalState());
    ASSERT(!m_resource->resourceToRevalidate());
    ASSERT(!m_resource->errorOccurred());
    LOG(ResourceLoading, "Received '%s'.", m_resource->url().string().latin1().data());

    Ref<SubresourceLoader> protect(*this);
    CachedResourceHandle<CachedResource> protectResource(m_resource);
    m_state = Finishing;
    m_activityAssertion.clear();
    m_resource->setLoadFinishTime(finishTime);
    m_resource->finishLoading(resourceData());

    if (wasCancelled())
        return;
    m_resource->finish();
    ASSERT(!reachedTerminalState());
    didFinishLoadingOnePart(finishTime);
    notifyDone();
    if (reachedTerminalState())
        return;
    releaseResources();
}
Beispiel #4
0
void SubresourceLoader::didReceiveResponse(const ResourceResponse& r)
{
    ASSERT(!r.isNull());

    if (r.isMultipart())
        m_loadingMultipartContent = true;

    // Reference the object in this method since the additional processing can do
    // anything including removing the last reference to this object; one example of this is 3266216.
    RefPtr<SubresourceLoader> protect(this);

    if (m_client)
        m_client->didReceiveResponse(this, r);
    
    // The loader can cancel a load if it receives a multipart response for a non-image
    if (reachedTerminalState())
        return;
    ResourceLoader::didReceiveResponse(r);
    
    RefPtr<SharedBuffer> buffer = resourceData();
    if (m_loadingMultipartContent && buffer && buffer->size()) {
        // Since a subresource loader does not load multipart sections progressively,
        // deliver the previously received data to the loader all at once now.
        // Then clear the data to make way for the next multipart section.
        if (m_client)
            m_client->didReceiveData(this, buffer->data(), buffer->size());
        clearResourceData();
        
        // After the first multipart section is complete, signal to delegates that this load is "finished" 
        m_documentLoader->subresourceLoaderFinishedLoadingOnePart(this);
        didFinishLoadingOnePart(0);
    }
}
Beispiel #5
0
void SubresourceLoader::didReceiveResponse(const ResourceResponse& response)
{
    ASSERT(!response.isNull());
    ASSERT(m_state == Initialized);

    // Reference the object in this method since the additional processing can do
    // anything including removing the last reference to this object; one example of this is 3266216.
    Ref<SubresourceLoader> protect(*this);

    if (m_resource->resourceToRevalidate()) {
        if (response.httpStatusCode() == 304) {
            // 304 Not modified / Use local copy
            // Existing resource is ok, just use it updating the expiration time.
            m_resource->setResponse(response);
            memoryCache()->revalidationSucceeded(m_resource, response);
            if (!reachedTerminalState())
                ResourceLoader::didReceiveResponse(response);
            return;
        }
        // Did not get 304 response, continue as a regular resource load.
        memoryCache()->revalidationFailed(m_resource);
    }

    m_resource->responseReceived(response);
    if (reachedTerminalState())
        return;

    ResourceLoader::didReceiveResponse(response);
    if (reachedTerminalState())
        return;

    // FIXME: Main resources have a different set of rules for multipart than images do.
    // Hopefully we can merge those 2 paths.
    if (response.isMultipart() && m_resource->type() != CachedResource::MainResource) {
        m_loadingMultipartContent = true;

        // We don't count multiParts in a CachedResourceLoader's request count
        m_requestCountTracker.clear();
        if (!m_resource->isImage()) {
            cancel();
            return;
        }
    }

    RefPtr<ResourceBuffer> buffer = resourceData();
    if (m_loadingMultipartContent && buffer && buffer->size()) {
        // The resource data will change as the next part is loaded, so we need to make a copy.
        RefPtr<ResourceBuffer> copiedData = ResourceBuffer::create(buffer->data(), buffer->size());
        m_resource->finishLoading(copiedData.get());
        clearResourceData();
        // Since a subresource loader does not load multipart sections progressively, data was delivered to the loader all at once.        
        // After the first multipart section is complete, signal to delegates that this load is "finished" 
        m_documentLoader->subresourceLoaderFinishedLoadingOnePart(this);
        didFinishLoadingOnePart(0);
    }

    checkForHTTPStatusCodeError();
}
Beispiel #6
0
void ResourceLoader::didFinishLoading(double finishTime)
{
    didFinishLoadingOnePart(finishTime);

    // If the load has been cancelled by a delegate in response to didFinishLoad(), do not release
    // the resources a second time, they have been released by cancel.
    if (m_cancelled)
        return;
    releaseResources();
}
Beispiel #7
0
void ResourceLoader::didFinishLoading()
{
    // If load has been cancelled after finishing (which could happen with a 
    // JavaScript that changes the window location), do nothing.
    if (m_cancelled)
        return;
    ASSERT(!m_reachedTerminalState);

    didFinishLoadingOnePart();
    releaseResources();
}
Beispiel #8
0
void ResourceLoader::didReceiveResponse(blink::WebURLLoader*, const blink::WebURLResponse& response)
{
    ASSERT(!response.isNull());
    ASSERT(m_state == Initialized);

    bool isMultipartPayload = response.isMultipartPayload();
    bool isValidStateTransition = (m_connectionState == ConnectionStateStarted || m_connectionState == ConnectionStateReceivedResponse);
    // In the case of multipart loads, calls to didReceiveData & didReceiveResponse can be interleaved.
    RELEASE_ASSERT(isMultipartPayload || isValidStateTransition);
    m_connectionState = ConnectionStateReceivedResponse;

    const ResourceResponse& resourceResponse = response.toResourceResponse();

    // Reference the object in this method since the additional processing can do
    // anything including removing the last reference to this object.
    RefPtr<ResourceLoader> protect(this);
    m_resource->responseReceived(resourceResponse);
    if (m_state == Terminated)
        return;

    m_host->didReceiveResponse(m_resource, resourceResponse);
    if (m_state == Terminated)
        return;

    if (response.toResourceResponse().isMultipart()) {
        // We don't count multiParts in a ResourceFetcher's request count
        m_requestCountTracker.clear();
        if (!m_resource->isImage()) {
            cancel();
            return;
        }
    } else if (isMultipartPayload) {
        // Since a subresource loader does not load multipart sections progressively, data was delivered to the loader all at once.
        // After the first multipart section is complete, signal to delegates that this load is "finished"
        m_host->subresourceLoaderFinishedLoadingOnePart(this);
        ASSERT(m_state != Terminated);
        didFinishLoadingOnePart(0, blink::WebURLLoaderClient::kUnknownEncodedDataLength);
    }
    if (m_state == Terminated)
        return;

    if (m_resource->response().httpStatusCode() < 400 || m_resource->shouldIgnoreHTTPStatusCodeErrors())
        return;
    m_state = Finishing;

    if (!m_notifiedLoadComplete) {
        m_notifiedLoadComplete = true;
        m_host->didFailLoading(m_resource, ResourceError::cancelledError(m_request.url()));
    }

    ASSERT(m_state != Terminated);
    m_resource->error(Resource::LoadError);
    cancel();
}
Beispiel #9
0
void SubresourceLoader::didReceiveResponse(const ResourceResponse& response)
{
    ASSERT(!response.isNull());
    ASSERT(m_state == Initialized);

    // Reference the object in this method since the additional processing can do
    // anything including removing the last reference to this object; one example of this is 3266216.
    RefPtr<SubresourceLoader> protect(this);

    if (m_resource->resourceToRevalidate()) {
        if (response.httpStatusCode() == 304) {
            // 304 Not modified / Use local copy
            // Existing resource is ok, just use it updating the expiration time.
        	// SRL: Create a network response event action.
        	ActionLogFormat(ActionLog::ENTER_SCOPE,
        			"recv_304:%s", m_resource->url().lastPathComponent().ascii().data());
            memoryCache()->revalidationSucceeded(m_resource, response);
            if (!reachedTerminalState())
                ResourceLoader::didReceiveResponse(response);
            ActionLogScopeEnd();
            return;
        }
        // Did not get 304 response, continue as a regular resource load.
        memoryCache()->revalidationFailed(m_resource);
    }

    m_resource->setResponse(response);
    if (reachedTerminalState())
        return;
    ResourceLoader::didReceiveResponse(response);

    if (response.isMultipart()) {
        m_loadingMultipartContent = true;

        // We don't count multiParts in a CachedResourceLoader's request count
        m_requestCountTracker.clear();
        if (!m_resource->isImage()) {
            cancel();
            return;
        }
    }

    RefPtr<SharedBuffer> buffer = resourceData();
    if (m_loadingMultipartContent && buffer && buffer->size()) {
        sendDataToResource(buffer->data(), buffer->size());
        clearResourceData();
        // Since a subresource loader does not load multipart sections progressively, data was delivered to the loader all at once.        
        // After the first multipart section is complete, signal to delegates that this load is "finished" 
        m_documentLoader->subresourceLoaderFinishedLoadingOnePart(this);
        didFinishLoadingOnePart(0);
    }
}
Beispiel #10
0
void ResourceLoader::didFinishLoading(ResourceHandle*, double finishTime)
{
    if (m_state != Initialized)
        return;
    ASSERT(m_state != Terminated);
    LOG(ResourceLoading, "Received '%s'.", m_resource->url().string().latin1().data());

    RefPtr<ResourceLoader> protect(this);
    CachedResourceHandle<CachedResource> protectResource(m_resource);
    m_state = Finishing;
    m_resource->finish(finishTime);
    didFinishLoadingOnePart(finishTime);

    // If the load has been cancelled by a delegate in response to didFinishLoad(), do not release
    // the resources a second time, they have been released by cancel.
    if (m_state == Terminated)
        return;
    releaseResources();
}
Beispiel #11
0
void SubresourceLoader::didFinishLoading(double finishTime)
{
    if (m_state != Initialized)
        return;
    ASSERT(!reachedTerminalState());
    ASSERT(!m_resource->resourceToRevalidate());
    // FIXME (129394): We should cancel the load when a decode error occurs instead of continuing the load to completion.
    ASSERT(!m_resource->errorOccurred() || m_resource->status() == CachedResource::DecodeError);
    LOG(ResourceLoading, "Received '%s'.", m_resource->url().string().latin1().data());
    logResourceLoaded(m_frame.get(), m_resource->type());

    Ref<SubresourceLoader> protectedThis(*this);
    CachedResourceHandle<CachedResource> protectResource(m_resource);

    // FIXME: The finishTime that is passed in is from the NetworkProcess and is more accurate.
    // However, all other load times are generated from the web process or offsets.
    // Mixing times from different processes can cause the finish time to be earlier than
    // the response received time due to inter-process communication lag.
    UNUSED_PARAM(finishTime);
    double responseEndTime = monotonicallyIncreasingTime();
    m_loadTiming.setResponseEnd(responseEndTime);

#if ENABLE(WEB_TIMING)
    if (m_documentLoader->cachedResourceLoader().document() && RuntimeEnabledFeatures::sharedFeatures().resourceTimingEnabled())
        m_documentLoader->cachedResourceLoader().resourceTimingInformation().addResourceTiming(m_resource, *m_documentLoader->cachedResourceLoader().document(), m_resource->loader()->loadTiming());
#endif

    m_state = Finishing;
    m_resource->setLoadFinishTime(responseEndTime); // FIXME: Users of the loadFinishTime should use the LoadTiming struct instead.
    m_resource->finishLoading(resourceData());

    if (wasCancelled())
        return;
    m_resource->finish();
    ASSERT(!reachedTerminalState());
    didFinishLoadingOnePart(responseEndTime);
    notifyDone();
    if (reachedTerminalState())
        return;
    releaseResources();
}
void ResourceLoader::didFinishLoading(WebKit::WebURLLoader*, double finishTime)
{
    RELEASE_ASSERT(m_connectionState == ConnectionStateReceivedResponse || m_connectionState == ConnectionStateReceivingData);
    m_connectionState = ConnectionStateFinishedLoading;
    if (m_state != Initialized)
        return;
    ASSERT(m_state != Terminated);
    LOG(ResourceLoading, "Received '%s'.", m_resource->url().string().latin1().data());

    RefPtr<ResourceLoader> protect(this);
    ResourcePtr<Resource> protectResource(m_resource);
    m_state = Finishing;
    m_resource->finish(finishTime);
    didFinishLoadingOnePart(finishTime);

    // If the load has been cancelled by a delegate in response to didFinishLoad(), do not release
    // the resources a second time, they have been released by cancel.
    if (m_state == Terminated)
        return;
    releaseResources();
}
Beispiel #13
0
void ResourceLoader::didReceiveResponse(ResourceHandle*, const ResourceResponse& response)
{
    ASSERT(!response.isNull());
    ASSERT(m_state == Initialized);

    // Reference the object in this method since the additional processing can do
    // anything including removing the last reference to this object.
    RefPtr<ResourceLoader> protect(this);
    m_resource->responseReceived(response);
    if (m_state == Terminated)
        return;

    if (m_options.sendLoadCallbacks == SendCallbacks)
        frameLoader()->notifier()->dispatchDidReceiveResponse(m_documentLoader.get(), m_resource->identifier(), response);

    if (response.isMultipart()) {
        m_loadingMultipartContent = true;

        // We don't count multiParts in a CachedResourceLoader's request count
        m_requestCountTracker.clear();
        if (!m_resource->isImage()) {
            cancel();
            return;
        }
    } else if (m_loadingMultipartContent) {
        // Since a subresource loader does not load multipart sections progressively, data was delivered to the loader all at once.
        // After the first multipart section is complete, signal to delegates that this load is "finished"
        m_documentLoader->subresourceLoaderFinishedLoadingOnePart(this);
        didFinishLoadingOnePart(0);
    }

    if (m_resource->response().httpStatusCode() < 400 || m_resource->shouldIgnoreHTTPStatusCodeErrors())
        return;
    m_state = Finishing;
    m_resource->error(CachedResource::LoadError);
    cancel();
}
Beispiel #14
0
void ResourceLoader::didFinishLoading()
{
    // If load has been cancelled after finishing (which could happen with a 
    // JavaScript that changes the window location), do nothing.
    if (m_cancelled)
        return;
    ASSERT(!m_reachedTerminalState);

    didFinishLoadingOnePart();

    //Frame* pFrame = getFrame();
    //if(pFrame != NULL)
    //{
    //    EA::WebKit::View* pView = EA::WebKit::GetView(pFrame);  // Get an EA::WebKit::View from a WebKit WebFrame.
    //    if(pView)
    //    {
    //        EA::WebKit::AuthenticationManager& authenticationObj = pView->GetAuthenticationManager();
    //        if(authenticationObj.AuthenticationRequired(m_response))
    //            authenticationObj.CreateAuthenticationObject(m_request);
    //    }
    //}

    releaseResources();
}
Beispiel #15
0
void ResourceLoader::didFinishLoading(double finishTime)
{
    didFinishLoadingOnePart(finishTime);
    releaseResources();
}
Beispiel #16
0
void SubresourceLoader::didReceiveResponse(const ResourceResponse& response)
{
    ASSERT(!response.isNull());
    ASSERT(m_state == Initialized);

    // Reference the object in this method since the additional processing can do
    // anything including removing the last reference to this object; one example of this is 3266216.
    Ref<SubresourceLoader> protectedThis(*this);

    if (shouldIncludeCertificateInfo())
        response.includeCertificateInfo();

    if (response.isHttpVersion0_9()) {
        if (m_frame) {
            String message = "Sandboxing '" + response.url().string() + "' because it is using HTTP/0.9.";
            m_frame->document()->addConsoleMessage(MessageSource::Security, MessageLevel::Error, message, identifier());
            frameLoader()->forceSandboxFlags(SandboxScripts | SandboxPlugins);
        }
    }

    if (m_resource->resourceToRevalidate()) {
        if (response.httpStatusCode() == 304) {
            // 304 Not modified / Use local copy
            // Existing resource is ok, just use it updating the expiration time.
            m_resource->setResponse(response);
            MemoryCache::singleton().revalidationSucceeded(*m_resource, response);
            if (m_frame && m_frame->page())
                m_frame->page()->diagnosticLoggingClient().logDiagnosticMessageWithResult(DiagnosticLoggingKeys::cachedResourceRevalidationKey(), emptyString(), DiagnosticLoggingResultPass, ShouldSample::Yes);
            if (!reachedTerminalState())
                ResourceLoader::didReceiveResponse(response);
            return;
        }
        // Did not get 304 response, continue as a regular resource load.
        MemoryCache::singleton().revalidationFailed(*m_resource);
        if (m_frame && m_frame->page())
            m_frame->page()->diagnosticLoggingClient().logDiagnosticMessageWithResult(DiagnosticLoggingKeys::cachedResourceRevalidationKey(), emptyString(), DiagnosticLoggingResultFail, ShouldSample::Yes);
    }

    m_resource->responseReceived(response);
    if (reachedTerminalState())
        return;

    ResourceLoader::didReceiveResponse(response);
    if (reachedTerminalState())
        return;

    // FIXME: Main resources have a different set of rules for multipart than images do.
    // Hopefully we can merge those 2 paths.
    if (response.isMultipart() && m_resource->type() != CachedResource::MainResource) {
        m_loadingMultipartContent = true;

        // We don't count multiParts in a CachedResourceLoader's request count
        m_requestCountTracker = Nullopt;
        if (!m_resource->isImage()) {
            cancel();
            return;
        }
    }

    auto* buffer = resourceData();
    if (m_loadingMultipartContent && buffer && buffer->size()) {
        // The resource data will change as the next part is loaded, so we need to make a copy.
        m_resource->finishLoading(buffer->copy().ptr());
        clearResourceData();
        // Since a subresource loader does not load multipart sections progressively, data was delivered to the loader all at once.
        // After the first multipart section is complete, signal to delegates that this load is "finished"
        m_documentLoader->subresourceLoaderFinishedLoadingOnePart(this);
        didFinishLoadingOnePart(0);
    }

    checkForHTTPStatusCodeError();
}
void ResourceLoader::didReceiveResponse(WebURLLoader*, const WebURLResponse& response, WebDataConsumerHandle* rawHandle)
{
    ASSERT(!response.isNull());
    ASSERT(m_state == Initialized);
    // |rawHandle|'s ownership is transferred to the callee.
    OwnPtr<WebDataConsumerHandle> handle = adoptPtr(rawHandle);

    bool isMultipartPayload = response.isMultipartPayload();
    bool isValidStateTransition = (m_connectionState == ConnectionStateStarted || m_connectionState == ConnectionStateReceivedResponse);
    // In the case of multipart loads, calls to didReceiveData & didReceiveResponse can be interleaved.
    RELEASE_ASSERT(isMultipartPayload || isValidStateTransition);
    m_connectionState = ConnectionStateReceivedResponse;

    const ResourceResponse& resourceResponse = response.toResourceResponse();

    if (responseNeedsAccessControlCheck()) {
        if (response.wasFetchedViaServiceWorker()) {
            if (response.wasFallbackRequiredByServiceWorker()) {
                m_loader->cancel();
                m_loader.clear();
                m_connectionState = ConnectionStateStarted;
                m_loader = adoptPtr(Platform::current()->createURLLoader());
                ASSERT(m_loader);
                ASSERT(!m_request.skipServiceWorker());
                m_request.setSkipServiceWorker(true);
                WrappedResourceRequest wrappedRequest(m_request);
                m_loader->loadAsynchronously(wrappedRequest, this);
                return;
            }
        } else {
            // If the response successfully validated a cached resource, perform
            // the access control with respect to it. Need to do this right here
            // before the resource switches clients over to that validated resource.
            Resource* resource = m_resource;
            if (!resource->isCacheValidator() || resourceResponse.httpStatusCode() != 304)
                m_resource->setResponse(resourceResponse);
            if (!m_fetcher->canAccessResource(resource, m_options.securityOrigin.get(), response.url(), ResourceFetcher::ShouldLogAccessControlErrors)) {
                m_fetcher->didReceiveResponse(m_resource, resourceResponse);
                cancel(ResourceError::cancelledDueToAccessCheckError(KURL(response.url())));
                return;
            }
        }
    }

    m_resource->responseReceived(resourceResponse, handle.release());
    if (m_state == Terminated)
        return;

    m_fetcher->didReceiveResponse(m_resource, resourceResponse);
    if (m_state == Terminated)
        return;

    if (response.toResourceResponse().isMultipart()) {
        // We only support multipart for images, though the image may be loaded
        // as a main resource that we end up displaying through an ImageDocument.
        if (!m_resource->isImage() && m_resource->type() != Resource::MainResource) {
            cancel();
            return;
        }
        m_loadingMultipartContent = true;
    } else if (isMultipartPayload) {
        // Since a subresource loader does not load multipart sections progressively, data was delivered to the loader all at once.
        // After the first multipart section is complete, signal to delegates that this load is "finished"
        m_fetcher->subresourceLoaderFinishedLoadingOnePart(this);
        didFinishLoadingOnePart(0, WebURLLoaderClient::kUnknownEncodedDataLength);
    }
    if (m_state == Terminated)
        return;

    if (m_resource->response().httpStatusCode() < 400 || m_resource->shouldIgnoreHTTPStatusCodeErrors())
        return;
    m_state = Finishing;

    if (!m_notifiedLoadComplete) {
        m_notifiedLoadComplete = true;
        m_fetcher->didFailLoading(m_resource, ResourceError::cancelledError(m_request.url()));
    }

    ASSERT(m_state != Terminated);
    m_resource->error(Resource::LoadError);
    cancel();
}