Beispiel #1
0
FetchRequest PreloadRequest::resourceRequest(Document* document)
{
    ASSERT(isMainThread());
    FetchInitiatorInfo initiatorInfo;
    initiatorInfo.name = AtomicString(m_initiatorName);
    initiatorInfo.position = m_initiatorPosition;
    ResourceRequest resourceRequest(completeURL(document));
    resourceRequest.setHTTPReferrer(SecurityPolicy::generateReferrer(m_referrerPolicy, resourceRequest.url(), document->outgoingReferrer()));
    FetchRequest request(resourceRequest, initiatorInfo);

    if (m_resourceType == Resource::ImportResource) {
        SecurityOrigin* securityOrigin = document->contextDocument()->securityOrigin();
        bool sameOrigin = securityOrigin->canRequest(request.url());
        request.setCrossOriginAccessControl(securityOrigin,
            sameOrigin ? AllowStoredCredentials : DoNotAllowStoredCredentials,
            ClientDidNotRequestCredentials);
    }

    if (m_isCORSEnabled)
        request.setCrossOriginAccessControl(document->securityOrigin(), m_allowCredentials);

    request.setDefer(m_defer);
    request.setResourceWidth(m_resourceWidth);
    request.clientHintsPreferences().updateFrom(m_clientHintsPreferences);

    return request;
}
Beispiel #2
0
void Loader::Host::servePendingRequests(RequestQueue& requestsPending, bool& serveLowerPriority)
{
    while (!requestsPending.isEmpty()) {        
        Request* request = requestsPending.first();
        DocLoader* docLoader = request->docLoader();
        bool resourceIsCacheValidator = request->cachedResource()->isCacheValidator();

        // For named hosts - which are only http(s) hosts - we should always enforce the connection limit.
        // For non-named hosts - everything but http(s) - we should only enforce the limit if the document isn't done parsing 
        // and we don't know all stylesheets yet.
        bool shouldLimitRequests = !m_name.isNull() || docLoader->doc()->parsing() || !docLoader->doc()->haveStylesheetsLoaded();
        if (shouldLimitRequests && m_requestsLoading.size() + m_nonCachedRequestsInFlight >= m_maxRequestsInFlight) {
            serveLowerPriority = false;
            cache()->loader()->scheduleServePendingRequests();
            return;
        }
        requestsPending.removeFirst();
        
        ResourceRequest resourceRequest(request->cachedResource()->url());
        resourceRequest.setTargetType(cachedResourceTypeToTargetType(request->cachedResource()->type()));
        
        if (!request->cachedResource()->accept().isEmpty())
            resourceRequest.setHTTPAccept(request->cachedResource()->accept());
        
         // Do not set the referrer or HTTP origin here. That's handled by SubresourceLoader::create.
        
        if (resourceIsCacheValidator) {
            CachedResource* resourceToRevalidate = request->cachedResource()->resourceToRevalidate();
            ASSERT(resourceToRevalidate->canUseCacheValidator());
            ASSERT(resourceToRevalidate->isLoaded());
            const String& lastModified = resourceToRevalidate->response().httpHeaderField("Last-Modified");
            const String& eTag = resourceToRevalidate->response().httpHeaderField("ETag");
            if (!lastModified.isEmpty() || !eTag.isEmpty()) {
                ASSERT(docLoader->cachePolicy() != CachePolicyReload);
                if (docLoader->cachePolicy() == CachePolicyRevalidate)
                    resourceRequest.setHTTPHeaderField("Cache-Control", "max-age=0");
                if (!lastModified.isEmpty())
                    resourceRequest.setHTTPHeaderField("If-Modified-Since", lastModified);
                if (!eTag.isEmpty())
                    resourceRequest.setHTTPHeaderField("If-None-Match", eTag);
            }
        }

        RefPtr<SubresourceLoader> loader = SubresourceLoader::create(docLoader->doc()->frame(),
            this, resourceRequest, request->shouldDoSecurityCheck(), request->sendResourceLoadCallbacks());
        if (loader) {
            m_requestsLoading.add(loader.release(), request);
            request->cachedResource()->setRequestedFromNetworkingLayer();
#if REQUEST_DEBUG
            printf("HOST %s COUNT %d LOADING %s\n", resourceRequest.url().host().latin1().data(), m_requestsLoading.size(), request->cachedResource()->url().latin1().data());
#endif
        } else {            
            docLoader->decrementRequestCount();
            docLoader->setLoadInProgress(true);
            request->cachedResource()->error();
            docLoader->setLoadInProgress(false);
            delete request;
        }
    }
}
TEST_F(ResourceFetcherTest, VaryOnBack) {
    ResourceFetcherTestMockFetchContext* context =
        ResourceFetcherTestMockFetchContext::create();
    context->setCachePolicy(CachePolicyHistoryBuffer);
    ResourceFetcher* fetcher = ResourceFetcher::create(context);

    KURL url(ParsedURLString, "http://127.0.0.1:8000/foo.html");
    Resource* resource = RawResource::create(url, Resource::Raw);
    memoryCache()->add(resource);
    ResourceResponse response;
    response.setURL(url);
    response.setHTTPStatusCode(200);
    response.setHTTPHeaderField(HTTPNames::Cache_Control, "max-age=3600");
    response.setHTTPHeaderField(HTTPNames::Vary, "*");
    resource->responseReceived(response, nullptr);
    resource->finish();
    ASSERT_TRUE(resource->hasVaryHeader());

    ResourceRequest resourceRequest(url);
    resourceRequest.setRequestContext(WebURLRequest::RequestContextInternal);
    FetchRequest fetchRequest =
        FetchRequest(resourceRequest, FetchInitiatorInfo());
    Resource* newResource = RawResource::fetch(fetchRequest, fetcher);
    EXPECT_EQ(resource, newResource);

    memoryCache()->remove(newResource);
}
Beispiel #4
0
void Loader::Host::servePendingRequests(RequestQueue& requestsPending)
{
    while (m_requestsLoading.size() < m_maxRequestsInFlight && !requestsPending.isEmpty()) {        
        Request* request = requestsPending.first();
        requestsPending.removeFirst();

        DocLoader* docLoader = request->docLoader();
        
        ResourceRequest resourceRequest(request->cachedResource()->url());
        
        if (!request->cachedResource()->accept().isEmpty())
            resourceRequest.setHTTPAccept(request->cachedResource()->accept());
        
        KURL referrer = docLoader->doc()->url();
        if ((referrer.protocolIs("http") || referrer.protocolIs("https")) && referrer.path().isEmpty())
            referrer.setPath("/");
        resourceRequest.setHTTPReferrer(referrer.string());

        RefPtr<SubresourceLoader> loader = SubresourceLoader::create(docLoader->doc()->frame(),
                                                                     this, resourceRequest, request->shouldSkipCanLoadCheck(), request->sendResourceLoadCallbacks());
        if (loader) {
            m_requestsLoading.add(loader.release(), request);
            request->cachedResource()->setRequestedFromNetworkingLayer();
#if REQUEST_DEBUG
            printf("HOST %s COUNT %d LOADING %s\n", resourceRequest.url().host().latin1().data(), m_requestsLoading.size(), request->cachedResource()->url().latin1().data());
#endif
        } else {            
            docLoader->decrementRequestCount();
            docLoader->setLoadInProgress(true);
            request->cachedResource()->error();
            docLoader->setLoadInProgress(false);
            delete request;
        }
    }
}
Beispiel #5
0
void IconLoader::startLoading()
{    
    if (m_resourceLoader)
        return;

    // Set flag so we can detect the case where the load completes before
    // SubresourceLoader::create returns.
    m_loadIsInProgress = true;

    ResourceRequest resourceRequest(m_frame->loader()->iconURL());
    resourceRequest.setPriority(ResourceLoadPriorityLow);

// SAMSUNG CHANGE : not sending favicon request once 404 not found error received for the favicon.
    m_iconUrl = m_frame->loader()->iconURL();
// SAMSUNG CHANGE

    RefPtr<SubresourceLoader> loader = resourceLoadScheduler()->scheduleSubresourceLoad(m_frame, this, resourceRequest);
    if (!loader)
        LOG_ERROR("Failed to start load for icon at url %s", m_frame->loader()->iconURL().string().ascii().data());

    // Store the handle so we can cancel the load if stopLoading is called later.
    // But only do it if the load hasn't already completed.
    if (m_loadIsInProgress)
        m_resourceLoader = loader.release();
}
TEST_F(ResourceFetcherTest, Vary) {
    KURL url(ParsedURLString, "http://127.0.0.1:8000/foo.html");
    Resource* resource = RawResource::create(url, Resource::Raw);
    memoryCache()->add(resource);
    ResourceResponse response;
    response.setURL(url);
    response.setHTTPStatusCode(200);
    response.setHTTPHeaderField(HTTPNames::Cache_Control, "max-age=3600");
    response.setHTTPHeaderField(HTTPNames::Vary, "*");
    resource->responseReceived(response, nullptr);
    resource->finish();
    ASSERT_TRUE(resource->hasVaryHeader());

    ResourceFetcher* fetcher =
        ResourceFetcher::create(ResourceFetcherTestMockFetchContext::create());
    ResourceRequest resourceRequest(url);
    resourceRequest.setRequestContext(WebURLRequest::RequestContextInternal);
    FetchRequest fetchRequest =
        FetchRequest(resourceRequest, FetchInitiatorInfo());
    Platform::current()->getURLLoaderMockFactory()->registerURL(
        url, WebURLResponse(), "");
    Resource* newResource = RawResource::fetch(fetchRequest, fetcher);
    EXPECT_NE(resource, newResource);
    newResource->loader()->cancel();
    memoryCache()->remove(newResource);
    Platform::current()->getURLLoaderMockFactory()->unregisterURL(url);

    memoryCache()->remove(resource);
}
Beispiel #7
0
void IconLoader::startLoading()
{
    ASSERT(m_frame || m_documentLoader);

    if (m_resource)
        return;

    if (m_frame && !m_frame->document())
        return;

    if (m_documentLoader && !m_documentLoader->frame())
        return;

    ResourceRequest resourceRequest(m_url);
    resourceRequest.setPriority(ResourceLoadPriority::Low);

    // ContentSecurityPolicyImposition::DoPolicyCheck is a placeholder value. It does not affect the request since Content Security Policy does not apply to raw resources.
    CachedResourceRequest request(WTFMove(resourceRequest), ResourceLoaderOptions(SendCallbacks, SniffContent, BufferData, DoNotAllowStoredCredentials, ClientCredentialPolicy::CannotAskClientForCredentials, FetchOptions::Credentials::Omit, DoSecurityCheck, FetchOptions::Mode::NoCors, DoNotIncludeCertificateInfo, ContentSecurityPolicyImposition::DoPolicyCheck, DefersLoadingPolicy::AllowDefersLoading, CachingPolicy::AllowCaching));

    request.setInitiator(cachedResourceRequestInitiators().icon);

    auto* frame = m_frame ? m_frame : m_documentLoader->frame();
    m_resource = frame->document()->cachedResourceLoader().requestRawResource(WTFMove(request));
    if (m_resource)
        m_resource->addClient(*this);
    else
        LOG_ERROR("Failed to start load for icon at url %s", frame->loader().icon().url().string().ascii().data());
}
void NotificationImageLoader::start(
    ExecutionContext* executionContext,
    const KURL& url,
    std::unique_ptr<ImageCallback> imageCallback) {
  DCHECK(!m_stopped);

  m_startTime = monotonicallyIncreasingTimeMS();
  m_imageCallback = std::move(imageCallback);

  ThreadableLoaderOptions threadableLoaderOptions;
  threadableLoaderOptions.preflightPolicy = PreventPreflight;
  threadableLoaderOptions.crossOriginRequestPolicy = AllowCrossOriginRequests;
  threadableLoaderOptions.timeoutMilliseconds = kImageFetchTimeoutInMs;

  // TODO(mvanouwerkerk): Add an entry for notifications to
  // FetchInitiatorTypeNames and use it.
  ResourceLoaderOptions resourceLoaderOptions;
  resourceLoaderOptions.allowCredentials = AllowStoredCredentials;
  if (executionContext->isWorkerGlobalScope())
    resourceLoaderOptions.requestInitiatorContext = WorkerContext;

  ResourceRequest resourceRequest(url);
  resourceRequest.setRequestContext(WebURLRequest::RequestContextImage);
  resourceRequest.setPriority(ResourceLoadPriorityMedium);
  resourceRequest.setRequestorOrigin(executionContext->getSecurityOrigin());

  m_threadableLoader = ThreadableLoader::create(
      *executionContext, this, threadableLoaderOptions, resourceLoaderOptions);
  m_threadableLoader->start(resourceRequest);
}
void NavigationScheduler::scheduleLocationChange(Document* initiatingDocument, SecurityOrigin* securityOrigin, const URL& url, const String& referrer, LockHistory lockHistory, LockBackForwardList lockBackForwardList)
{
    if (!shouldScheduleNavigation(url))
        return;

    if (lockBackForwardList == LockBackForwardList::No)
        lockBackForwardList = mustLockBackForwardList(m_frame);

    FrameLoader& loader = m_frame.loader();

    // If the URL we're going to navigate to is the same as the current one, except for the
    // fragment part, we don't need to schedule the location change.
    if (url.hasFragmentIdentifier() && equalIgnoringFragmentIdentifier(m_frame.document()->url(), url)) {
        ResourceRequest resourceRequest(m_frame.document()->completeURL(url), referrer, UseProtocolCachePolicy);
        ShouldOpenExternalURLsPolicy shouldOpenExternalURLsPolicy = ShouldOpenExternalURLsPolicy::ShouldNotAllow;
        if (initiatingDocument)
            shouldOpenExternalURLsPolicy = initiatingDocument->shouldOpenExternalURLsPolicyToPropagate();
        FrameLoadRequest frameRequest(securityOrigin, resourceRequest, "_self", lockHistory, lockBackForwardList, MaybeSendReferrer, AllowNavigationToInvalidURL::No, NewFrameOpenerPolicy::Allow, ReplaceDocumentIfJavaScriptURL, shouldOpenExternalURLsPolicy);
        loader.changeLocation(frameRequest);
        return;
    }

    // Handle a location change of a page with no document as a special case.
    // This may happen when a frame changes the location of another frame.
    bool duringLoad = !loader.stateMachine().committedFirstRealDocumentLoad();

    schedule(std::make_unique<ScheduledLocationChange>(initiatingDocument, securityOrigin, url, referrer, lockHistory, lockBackForwardList, duringLoad));
}
Beispiel #10
0
TEST_F(ResourceFetcherTest, Revalidate304) {
    KURL url(ParsedURLString, "http://127.0.0.1:8000/foo.html");
    Resource* resource = RawResource::create(url, Resource::Raw);
    memoryCache()->add(resource);
    ResourceResponse response;
    response.setURL(url);
    response.setHTTPStatusCode(304);
    response.setHTTPHeaderField("etag", "1234567890");
    resource->responseReceived(response, nullptr);
    resource->finish();

    ResourceFetcher* fetcher =
        ResourceFetcher::create(ResourceFetcherTestMockFetchContext::create());
    ResourceRequest resourceRequest(url);
    resourceRequest.setRequestContext(WebURLRequest::RequestContextInternal);
    FetchRequest fetchRequest =
        FetchRequest(resourceRequest, FetchInitiatorInfo());
    Platform::current()->getURLLoaderMockFactory()->registerURL(
        url, WebURLResponse(), "");
    Resource* newResource = RawResource::fetch(fetchRequest, fetcher);
    fetcher->stopFetching();
    Platform::current()->getURLLoaderMockFactory()->unregisterURL(url);

    EXPECT_NE(resource, newResource);
}
FetchRequest PreloadRequest::resourceRequest(Document* document)
{
    ASSERT(isMainThread());
    FetchInitiatorInfo initiatorInfo;
    initiatorInfo.name = AtomicString(m_initiatorName);
    initiatorInfo.position = m_initiatorPosition;
    ResourceRequest resourceRequest(completeURL(document));
    resourceRequest.setHTTPReferrer(SecurityPolicy::generateReferrer(m_referrerPolicy, resourceRequest.url(), document->outgoingReferrer()));
    ResourceFetcher::determineRequestContext(resourceRequest, m_resourceType, false);
    FetchRequest request(resourceRequest, initiatorInfo);

    if (m_resourceType == Resource::ImportResource) {
        SecurityOrigin* securityOrigin = document->contextDocument()->getSecurityOrigin();
        request.setCrossOriginAccessControl(securityOrigin, CrossOriginAttributeAnonymous);
    }
    if (m_crossOrigin != CrossOriginAttributeNotSet)
        request.setCrossOriginAccessControl(document->getSecurityOrigin(), m_crossOrigin);
    request.setDefer(m_defer);
    request.setResourceWidth(m_resourceWidth);
    request.clientHintsPreferences().updateFrom(m_clientHintsPreferences);
    request.setIntegrityMetadata(m_integrityMetadata);
    request.setContentSecurityPolicyNonce(m_nonce);

    if (m_requestType == RequestTypeLinkRelPreload)
        request.setLinkPreload(true);
    return request;
}
TEST_F(FrameFetchContextTest, EnableDataSaver)
{
    Settings* settings = document->frame()->settings();
    settings->setDataSaverEnabled(true);
    ResourceRequest resourceRequest("http://www.example.com");
    fetchContext->addAdditionalRequestHeaders(resourceRequest, FetchMainResource);
    EXPECT_STREQ("on", resourceRequest.httpHeaderField("Save-Data").utf8().data());
}
    virtual void fire(Frame& frame) override
    {
        UserGestureIndicator gestureIndicator(wasUserGesture() ? DefinitelyProcessingUserGesture : DefinitelyNotProcessingUserGesture);

        ResourceRequest resourceRequest(url(), referrer(), ReloadIgnoringCacheData);
        FrameLoadRequest frameRequest(securityOrigin(), resourceRequest, "_self", lockHistory(), lockBackForwardList(), MaybeSendReferrer, AllowNavigationToInvalidURL::Yes, NewFrameOpenerPolicy::Allow, m_shouldOpenExternalURLsPolicy);
        frame.loader().changeLocation(frameRequest);
    }
    void fire(Frame& frame) override
    {
        UserGestureIndicator gestureIndicator(wasUserGesture() ? DefinitelyProcessingUserGesture : DefinitelyNotProcessingUserGesture);
        bool refresh = equalIgnoringFragmentIdentifier(frame.document()->url(), url());
        ResourceRequest resourceRequest(url(), referrer(), refresh ? ReloadIgnoringCacheData : UseProtocolCachePolicy);
        FrameLoadRequest frameRequest(securityOrigin(), resourceRequest, "_self", lockHistory(), lockBackForwardList(), MaybeSendReferrer, AllowNavigationToInvalidURL::No, NewFrameOpenerPolicy::Allow, m_shouldOpenExternalURLsPolicy);

        frame.loader().changeLocation(frameRequest);
    }
// Tests that when a resource with certificate errors is loaded from the
// memory cache, the embedder is notified.
TEST_F(FrameFetchContextDisplayedCertificateErrorsTest, MemoryCacheCertificateError)
{
    ResourceRequest resourceRequest(url);
    ResourceResponse response;
    response.setURL(url);
    response.setSecurityInfo(securityInfo);
    response.setHasMajorCertificateErrors(true);
    Resource* resource = Resource::create(resourceRequest, Resource::Image);
    resource->setResponse(response);
    fetchContext->dispatchDidLoadResourceFromMemoryCache(createUniqueIdentifier(), resource, WebURLRequest::FrameTypeNone, WebURLRequest::RequestContextImage);
}
Beispiel #16
0
 void request(const WebString& url) {
     DCHECK(!m_context);
     m_context = ResourceFetcherTestMockFetchContext::create();
     ResourceFetcher* fetcher = ResourceFetcher::create(m_context);
     ResourceRequest resourceRequest(url);
     resourceRequest.setRequestContext(WebURLRequest::RequestContextInternal);
     FetchRequest fetchRequest =
         FetchRequest(resourceRequest, FetchInitiatorInfo());
     RawResource::fetch(fetchRequest, fetcher);
     Platform::current()->getURLLoaderMockFactory()->serveAsynchronousRequests();
 }
    void fire(Frame& frame) override
    {
        UserGestureIndicator gestureIndicator(wasUserGesture() ? DefinitelyProcessingUserGesture : DefinitelyNotProcessingUserGesture);

        ResourceResponse replacementResponse(m_originDocument.url(), ASCIILiteral("text/plain"), 0, ASCIILiteral("UTF-8"));
        SubstituteData replacementData(SharedBuffer::create(), m_originDocument.url(), replacementResponse, SubstituteData::SessionHistoryVisibility::Hidden);

        ResourceRequest resourceRequest(m_originDocument.url(), emptyString(), ReloadIgnoringCacheData);
        FrameLoadRequest frameRequest(m_originDocument.securityOrigin(), resourceRequest, lockHistory(), lockBackForwardList(), MaybeSendReferrer, AllowNavigationToInvalidURL::Yes, NewFrameOpenerPolicy::Allow, m_shouldOpenExternalURLsPolicy);
        frameRequest.setSubstituteData(replacementData);
        frame.loader().load(frameRequest);
    }
static Resource* preloadIfNeeded(const LinkRelAttribute& relAttribute, const KURL& href, Document& document, const String& as, const String& mimeType,
    const String& media, CrossOriginAttributeValue crossOrigin, LinkCaller caller, bool& errorOccurred, ViewportDescription* viewportDescription)
{
    if (!document.loader() || !relAttribute.isLinkPreload())
        return nullptr;

    UseCounter::count(document, UseCounter::LinkRelPreload);
    ASSERT(RuntimeEnabledFeatures::linkPreloadEnabled());
    if (!href.isValid() || href.isEmpty()) {
        document.addConsoleMessage(ConsoleMessage::create(OtherMessageSource, WarningMessageLevel, String("<link rel=preload> has an invalid `href` value")));
        return nullptr;
    }

    if (!media.isEmpty()) {
        MediaValues* mediaValues = MediaValues::createDynamicIfFrameExists(document.frame());
        if (viewportDescription)
            mediaValues->overrideViewportDimensions(viewportDescription->maxWidth.getFloatValue(), viewportDescription->maxHeight.getFloatValue());

        // Preload only if media matches
        MediaQuerySet* mediaQueries = MediaQuerySet::create(media);
        MediaQueryEvaluator evaluator(*mediaValues);
        if (!evaluator.eval(mediaQueries))
            return nullptr;
    }
    if (caller == LinkCalledFromHeader)
        UseCounter::count(document, UseCounter::LinkHeaderPreload);
    Resource::Type resourceType;
    if (!LinkLoader::getResourceTypeFromAsAttribute(as, resourceType)) {
        document.addConsoleMessage(ConsoleMessage::create(OtherMessageSource, WarningMessageLevel, String("<link rel=preload> must have a valid `as` value")));
        errorOccurred = true;
        return nullptr;
    }

    if (!isSupportedType(resourceType, mimeType)) {
        document.addConsoleMessage(ConsoleMessage::create(OtherMessageSource, WarningMessageLevel, String("<link rel=preload> has an unsupported `type` value")));
        return nullptr;
    }
    ResourceRequest resourceRequest(document.completeURL(href));
    ResourceFetcher::determineRequestContext(resourceRequest, resourceType, false);
    FetchRequest linkRequest(resourceRequest, FetchInitiatorTypeNames::link, document.encodingName());

    if (crossOrigin != CrossOriginAttributeNotSet)
        linkRequest.setCrossOriginAccessControl(document.getSecurityOrigin(), crossOrigin);
    Settings* settings = document.settings();
    if (settings && settings->logPreload())
        document.addConsoleMessage(ConsoleMessage::create(OtherMessageSource, DebugMessageLevel, String("Preload triggered for " + href.host() + href.path())));
    linkRequest.setForPreload(true, monotonicallyIncreasingTime());
    linkRequest.setLinkPreload(true);
    linkRequest.setPriority(document.fetcher()->loadPriority(resourceType, linkRequest));
    return document.loader()->startPreload(resourceType, linkRequest);
}
Beispiel #19
0
PassRefPtr<CachedResourceRequest> CachedResourceRequest::load(CachedResourceLoader* cachedResourceLoader, CachedResource* resource, bool incremental, SecurityCheckPolicy securityCheck, bool sendResourceLoadCallbacks)
{
    RefPtr<CachedResourceRequest> request = adoptRef(new CachedResourceRequest(cachedResourceLoader, resource, incremental));

    ResourceRequest resourceRequest(resource->url());
    resourceRequest.setTargetType(cachedResourceTypeToTargetType(resource->type(), resource->loadPriority()));

    if (!resource->accept().isEmpty())
        resourceRequest.setHTTPAccept(resource->accept());

    if (resource->isCacheValidator()) {
        CachedResource* resourceToRevalidate = resource->resourceToRevalidate();
        ASSERT(resourceToRevalidate->canUseCacheValidator());
        ASSERT(resourceToRevalidate->isLoaded());
        const String& lastModified = resourceToRevalidate->response().httpHeaderField("Last-Modified");
        const String& eTag = resourceToRevalidate->response().httpHeaderField("ETag");
        if (!lastModified.isEmpty() || !eTag.isEmpty()) {
            ASSERT(cachedResourceLoader->cachePolicy() != CachePolicyReload);
            if (cachedResourceLoader->cachePolicy() == CachePolicyRevalidate)
                resourceRequest.setHTTPHeaderField("Cache-Control", "max-age=0");
            if (!lastModified.isEmpty())
                resourceRequest.setHTTPHeaderField("If-Modified-Since", lastModified);
            if (!eTag.isEmpty())
                resourceRequest.setHTTPHeaderField("If-None-Match", eTag);
        }
    }
    
#if ENABLE(LINK_PREFETCH)
    if (resource->type() == CachedResource::LinkResource)
        resourceRequest.setHTTPHeaderField("Purpose", "prefetch");
#endif

    ResourceLoadPriority priority = resource->loadPriority();
    resourceRequest.setPriority(priority);

    RefPtr<SubresourceLoader> loader = resourceLoadScheduler()->scheduleSubresourceLoad(cachedResourceLoader->document()->frame(),
        request.get(), resourceRequest, priority, securityCheck, sendResourceLoadCallbacks);
    if (!loader || loader->reachedTerminalState()) {
        // FIXME: What if resources in other frames were waiting for this revalidation?
        LOG(ResourceLoading, "Cannot start loading '%s'", resource->url().latin1().data());
        cachedResourceLoader->decrementRequestCount(resource);
        cachedResourceLoader->loadFinishing();
        if (resource->resourceToRevalidate()) 
            memoryCache()->revalidationFailed(resource); 
        resource->error(CachedResource::LoadError);
        cachedResourceLoader->loadDone(0);
        return 0;
    }
    request->m_loader = loader;
    return request.release();
}
Beispiel #20
0
CachedResource::~CachedResource()
{
    ASSERT(!m_resourceToRevalidate); // Should be true because canDelete() checks this.
    ASSERT(canDelete());
    ASSERT(!inCache());
    ASSERT(!m_deleted);
    ASSERT(url().isNull() || memoryCache()->resourceForRequest(resourceRequest(), sessionID()) != this);

#ifndef NDEBUG
    m_deleted = true;
    cachedResourceLeakCounter.decrement();
#endif

    if (m_owningCachedResourceLoader)
        m_owningCachedResourceLoader->removeCachedResource(this);
}
Beispiel #21
0
void CSSStyleSheetResource::didAddClient(ResourceClient* c) {
    DCHECK(StyleSheetResourceClient::isExpectedType(c));
    // Resource::didAddClient() must be before setCSSStyleSheet(), because
    // setCSSStyleSheet() may cause scripts to be executed, which could destroy
    // 'c' if it is an instance of HTMLLinkElement. see the comment of
    // HTMLLinkElement::setCSSStyleSheet.
    Resource::didAddClient(c);

    if (hasClient(c) && m_didNotifyFirstData)
        static_cast<StyleSheetResourceClient*>(c)->didAppendFirstData(this);

    // |c| might be removed in didAppendFirstData, so ensure it is still a client.
    if (hasClient(c) && !isLoading()) {
        static_cast<StyleSheetResourceClient*>(c)->setCSSStyleSheet(
            resourceRequest().url(), response().url(), encoding(), this);
    }
}
Beispiel #22
0
TEST_F(ResourceFetcherTest, SynchronousRequest) {
    KURL url(ParsedURLString, "http://127.0.0.1:8000/foo.png");
    URLTestHelpers::registerMockedURLLoad(url, testImageFilename, "image/png");

    ResourceFetcher* fetcher =
        ResourceFetcher::create(ResourceFetcherTestMockFetchContext::create());
    ResourceRequest resourceRequest(url);
    resourceRequest.setRequestContext(WebURLRequest::RequestContextInternal);
    FetchRequest fetchRequest(resourceRequest, FetchInitiatorInfo());
    fetchRequest.makeSynchronous();
    Resource* resource = RawResource::fetch(fetchRequest, fetcher);
    EXPECT_TRUE(resource->isLoaded());
    EXPECT_EQ(ResourceLoadPriorityHighest,
              resource->resourceRequest().priority());

    Platform::current()->getURLLoaderMockFactory()->unregisterURL(url);
    memoryCache()->remove(resource);
}
Beispiel #23
0
void IconLoader::startLoading()
{
    if (m_resource || !m_frame->document())
        return;

    ResourceRequest resourceRequest(m_frame->loader()->icon()->url());
#if PLATFORM(BLACKBERRY)
    resourceRequest.setTargetType(ResourceRequest::TargetIsFavicon);
#endif
    resourceRequest.setPriority(ResourceLoadPriorityLow);

    m_resource = m_frame->document()->cachedResourceLoader()->requestRawResource(resourceRequest,
        ResourceLoaderOptions(SendCallbacks, SniffContent, BufferData, DoNotAllowStoredCredentials, DoNotAskClientForCrossOriginCredentials, DoSecurityCheck));
    if (m_resource)
        m_resource->addClient(this);
    else
        LOG_ERROR("Failed to start load for icon at url %s", m_frame->loader()->icon()->url().string().ascii().data());
}
Beispiel #24
0
// Regression test for http://crbug.com/594072.
// This emulates a modal dialog triggering a nested run loop inside
// ResourceLoader::cancel(). If the ResourceLoader doesn't promptly cancel its
// WebURLLoader before notifying its clients, a nested run loop  may send a
// network response, leading to an invalid state transition in ResourceLoader.
TEST_F(ResourceFetcherTest, ResponseOnCancel) {
    KURL url(ParsedURLString, "http://127.0.0.1:8000/foo.png");
    URLTestHelpers::registerMockedURLLoad(url, testImageFilename, "image/png");

    ResourceFetcher* fetcher =
        ResourceFetcher::create(ResourceFetcherTestMockFetchContext::create());
    ResourceRequest resourceRequest(url);
    resourceRequest.setRequestContext(WebURLRequest::RequestContextInternal);
    FetchRequest fetchRequest =
        FetchRequest(resourceRequest, FetchInitiatorInfo());
    Resource* resource = RawResource::fetch(fetchRequest, fetcher);
    Persistent<ServeRequestsOnCompleteClient> client =
        new ServeRequestsOnCompleteClient();
    resource->addClient(client);
    resource->loader()->cancel();
    resource->removeClient(client);
    Platform::current()->getURLLoaderMockFactory()->unregisterURL(url);
}
Beispiel #25
0
void CSSStyleSheetResource::checkNotify() {
    // Decode the data to find out the encoding and cache the decoded sheet text.
    if (data())
        setDecodedSheetText(decodedText());

    ResourceClientWalker<StyleSheetResourceClient> w(clients());
    while (StyleSheetResourceClient* c = w.next()) {
        markClientFinished(c);
        c->setCSSStyleSheet(resourceRequest().url(), response().url(), encoding(),
                            this);
    }

    // Clear raw bytes as now we have the full decoded sheet text.
    // We wait for all LinkStyle::setCSSStyleSheet to run (at least once)
    // as SubresourceIntegrity checks require raw bytes.
    // Note that LinkStyle::setCSSStyleSheet can be called from didAddClient too,
    // but is safe as we should have a cached ResourceIntegrityDisposition.
    clearData();
}
Beispiel #26
0
TEST_F(ResourceFetcherTest, StartLoadAfterFrameDetach) {
    KURL secureURL(ParsedURLString, "https://secureorigin.test/image.png");
    // Try to request a url. The request should fail, and a resource in an error
    // state should be returned, and no resource should be present in the cache.
    ResourceFetcher* fetcher = ResourceFetcher::create(nullptr);
    ResourceRequest resourceRequest(secureURL);
    resourceRequest.setRequestContext(WebURLRequest::RequestContextInternal);
    FetchRequest fetchRequest =
        FetchRequest(resourceRequest, FetchInitiatorInfo());
    Resource* resource = RawResource::fetch(fetchRequest, fetcher);
    ASSERT_TRUE(resource);
    EXPECT_TRUE(resource->errorOccurred());
    EXPECT_TRUE(resource->resourceError().isAccessCheck());
    EXPECT_FALSE(memoryCache()->resourceForURL(secureURL));

    // Start by calling startLoad() directly, rather than via requestResource().
    // This shouldn't crash.
    fetcher->startLoad(RawResource::create(secureURL, Resource::Raw));
}
void InspectorFrontendClientLocal::openInNewTab(const String& url)
{
    UserGestureIndicator indicator(DefinitelyProcessingUserGesture);
    Frame& mainFrame = m_inspectedPageController->inspectedPage().mainFrame();
    FrameLoadRequest request(mainFrame.document()->securityOrigin(), ResourceRequest(), "_blank", LockHistory::No, LockBackForwardList::No, MaybeSendReferrer, AllowNavigationToInvalidURL::Yes, NewFrameOpenerPolicy::Allow, ReplaceDocumentIfJavaScriptURL, ShouldOpenExternalURLsPolicy::ShouldNotAllow);

    bool created;
    WindowFeatures windowFeatures;
    RefPtr<Frame> frame = WebCore::createWindow(mainFrame, mainFrame, request, windowFeatures, created);
    if (!frame)
        return;

    frame->loader().setOpener(&mainFrame);
    frame->page()->setOpenedByDOM();

    // FIXME: Why does one use mainFrame and the other frame?
    ResourceRequest resourceRequest(frame->document()->completeURL(url));
    FrameLoadRequest frameRequest(mainFrame.document()->securityOrigin(), resourceRequest, "_self", LockHistory::No, LockBackForwardList::No, MaybeSendReferrer, AllowNavigationToInvalidURL::Yes, NewFrameOpenerPolicy::Allow, ReplaceDocumentIfJavaScriptURL, ShouldOpenExternalURLsPolicy::ShouldNotAllow);
    frame->loader().changeLocation(frameRequest);
}
void WebUrlLoaderClient::willSendRequest(PassOwnPtr<WebResponse> webResponse)
{
    if (!isActive())
        return;

    KURL url = webResponse->createKurl();
    OwnPtr<WebCore::ResourceRequest> resourceRequest(new WebCore::ResourceRequest(url));
    m_resourceHandle->client()->willSendRequest(m_resourceHandle.get(), *resourceRequest, webResponse->createResourceResponse());

    // WebKit may have killed the request.
    if (!isActive())
        return;

    // Like Chrome, we only follow the redirect if WebKit left the URL unmodified.
    if (url == resourceRequest->url()) {
        ioThread()->message_loop()->PostTask(FROM_HERE, NewRunnableMethod(m_request.get(), &WebRequest::followDeferredRedirect));
    } else {
        cancel();
    }
}
static Resource* preloadIfNeeded(const LinkRelAttribute& relAttribute, const KURL& href, Document& document, const String& as, const String& mimeType,
    CrossOriginAttributeValue crossOrigin, LinkCaller caller, bool& errorOccurred)
{
    if (!document.loader() || !relAttribute.isLinkPreload())
        return nullptr;

    UseCounter::count(document, UseCounter::LinkRelPreload);
    ASSERT(RuntimeEnabledFeatures::linkPreloadEnabled());
    if (!href.isValid() || href.isEmpty()) {
        document.addConsoleMessage(ConsoleMessage::create(OtherMessageSource, WarningMessageLevel, String("<link rel=preload> has an invalid `href` value")));
        return nullptr;
    }

    if (caller == LinkCalledFromHeader)
        UseCounter::count(document, UseCounter::LinkHeaderPreload);
    Resource::Type resourceType;
    if (!LinkLoader::getResourceTypeFromAsAttribute(as, resourceType)) {
        document.addConsoleMessage(ConsoleMessage::create(OtherMessageSource, WarningMessageLevel, String("<link rel=preload> must have a valid `as` value")));
        errorOccurred = true;
        return nullptr;
    }

    if (!isSupportedType(resourceType, mimeType)) {
        document.addConsoleMessage(ConsoleMessage::create(OtherMessageSource, WarningMessageLevel, String("<link rel=preload> has an unsupported `type` value")));
        return nullptr;
    }
    ResourceRequest resourceRequest(document.completeURL(href));
    ResourceFetcher::determineRequestContext(resourceRequest, resourceType, false);
    FetchRequest linkRequest(resourceRequest, FetchInitiatorTypeNames::link);

    linkRequest.setPriority(document.fetcher()->loadPriority(resourceType, linkRequest));
    if (crossOrigin != CrossOriginAttributeNotSet)
        linkRequest.setCrossOriginAccessControl(document.securityOrigin(), crossOrigin);
    Settings* settings = document.settings();
    if (settings && settings->logPreload())
        document.addConsoleMessage(ConsoleMessage::create(OtherMessageSource, DebugMessageLevel, String("Preload triggered for " + href.host() + href.path())));
    linkRequest.setForPreload(true);
    linkRequest.setLinkPreload(true);
    return document.loader()->startPreload(resourceType, linkRequest);
}
Beispiel #30
0
Resource* MemoryCacheCorrectnessTestHelper::fetch() {
  ResourceRequest resourceRequest(KURL(ParsedURLString, kResourceURL));
  resourceRequest.setRequestContext(WebURLRequest::RequestContextInternal);
  FetchRequest fetchRequest(resourceRequest, FetchInitiatorInfo());
  return RawResource::fetch(fetchRequest, fetcher());
}