TEST(ImageResourceTest, CancelOnDetach)
{
    KURL testURL(ParsedURLString, "http://www.test.com/cancelTest.html");
    URLTestHelpers::registerMockedURLLoad(testURL, "cancelTest.html", "text/html");

    ResourceFetcher* fetcher = ResourceFetcher::create(nullptr);

    // Emulate starting a real load.
    ResourcePtr<ImageResource> cachedImage = new ImageResource(ResourceRequest(testURL), nullptr);
    cachedImage->setIdentifier(createUniqueIdentifier());

    cachedImage->load(fetcher, ResourceLoaderOptions());
    memoryCache()->add(cachedImage.get());

    MockImageResourceClient client(cachedImage);
    EXPECT_EQ(Resource::Pending, cachedImage->status());

    // The load should still be alive, but a timer should be started to cancel the load inside removeClient().
    client.removeAsClient();
    EXPECT_EQ(Resource::Pending, cachedImage->status());
    EXPECT_NE(reinterpret_cast<Resource*>(0), memoryCache()->resourceForURL(testURL));

    // Trigger the cancel timer, ensure the load was cancelled and the resource was evicted from the cache.
    blink::testing::runPendingTasks();
    EXPECT_EQ(Resource::LoadError, cachedImage->status());
    EXPECT_EQ(reinterpret_cast<Resource*>(0), memoryCache()->resourceForURL(testURL));

    Platform::current()->unitTestSupport()->unregisterMockedURL(testURL);
}
Example #2
0
CachedCSSStyleSheet* CachedResourceLoader::requestUserCSSStyleSheet(ResourceRequest& request, const String& charset)
{
    KURL url = MemoryCache::removeFragmentIdentifierIfNeeded(request.url());

    if (CachedResource* existing = memoryCache()->resourceForURL(url)) {
        if (existing->type() == CachedResource::CSSStyleSheet)
            return static_cast<CachedCSSStyleSheet*>(existing);
        memoryCache()->remove(existing);
    }
    if (url.string() != request.url())
        request.setURL(url);

    CachedCSSStyleSheet* userSheet = new CachedCSSStyleSheet(request, charset);

    bool inCache = memoryCache()->add(userSheet);
    if (!inCache)
        userSheet->setInCache(true);

    userSheet->load(this, ResourceLoaderOptions(DoNotSendCallbacks, SniffContent, BufferData, AllowStoredCredentials, AskClientForCrossOriginCredentials, SkipSecurityCheck));

    if (!inCache)
        userSheet->setInCache(false);

    return userSheet;
}
RefPtr<PlatformMediaResource> MediaResourceLoader::requestResource(const ResourceRequest& request, LoadOptions options)
{
    if (!m_document)
        return nullptr;

    DataBufferingPolicy bufferingPolicy = options & LoadOption::BufferData ? WebCore::BufferData : WebCore::DoNotBufferData;
    RequestOriginPolicy corsPolicy = !m_crossOriginMode.isNull() ? PotentiallyCrossOriginEnabled : UseDefaultOriginRestrictionsForType;
    StoredCredentials allowCredentials = m_crossOriginMode.isNull() || equalLettersIgnoringASCIICase(m_crossOriginMode, "use-credentials") ? AllowStoredCredentials : DoNotAllowStoredCredentials;

    // FIXME: Skip Content Security Policy check if the element that inititated this request
    // is in a user-agent shadow tree. See <https://bugs.webkit.org/show_bug.cgi?id=155505>.
    CachedResourceRequest cacheRequest(request, ResourceLoaderOptions(SendCallbacks, DoNotSniffContent, bufferingPolicy, allowCredentials, DoNotAskClientForCrossOriginCredentials, ClientDidNotRequestCredentials, DoSecurityCheck, corsPolicy, DoNotIncludeCertificateInfo, ContentSecurityPolicyImposition::DoPolicyCheck, DefersLoadingPolicy::AllowDefersLoading, CachingPolicy::AllowCaching));

    if (!m_crossOriginMode.isNull())
        updateRequestForAccessControl(cacheRequest.mutableResourceRequest(), m_document->securityOrigin(), allowCredentials);

    CachedResourceHandle<CachedRawResource> resource = m_document->cachedResourceLoader().requestMedia(cacheRequest);
    if (!resource)
        return nullptr;

    Ref<MediaResource> mediaResource = MediaResource::create(*this, resource);
    m_resources.add(mediaResource.ptr());

    return WTFMove(mediaResource);
}
Example #4
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());
}
Example #5
0
CachedResourceHandle<CachedCSSStyleSheet> CachedResourceLoader::requestUserCSSStyleSheet(CachedResourceRequest& request)
{
    KURL url = MemoryCache::removeFragmentIdentifierIfNeeded(request.resourceRequest().url());

#if ENABLE(CACHE_PARTITIONING)
    request.mutableResourceRequest().setCachePartition(document()->topOrigin()->cachePartition());
#endif

    if (CachedResource* existing = memoryCache()->resourceForRequest(request.resourceRequest())) {
        if (existing->type() == CachedResource::CSSStyleSheet)
            return static_cast<CachedCSSStyleSheet*>(existing);
        memoryCache()->remove(existing);
    }
    if (url.string() != request.resourceRequest().url())
        request.mutableResourceRequest().setURL(url);

    CachedResourceHandle<CachedCSSStyleSheet> userSheet = new CachedCSSStyleSheet(request.resourceRequest(), request.charset());

    memoryCache()->add(userSheet.get());
    // FIXME: loadResource calls setOwningCachedResourceLoader() if the resource couldn't be added to cache. Does this function need to call it, too?

    userSheet->load(this, ResourceLoaderOptions(DoNotSendCallbacks, SniffContent, BufferData, AllowStoredCredentials, AskClientForCrossOriginCredentials, SkipSecurityCheck));
    
    return userSheet;
}
MainResourceLoader::MainResourceLoader(Frame* frame)
    : ResourceLoader(frame, ResourceLoaderOptions(SendCallbacks, SniffContent, BufferData, AllowStoredCredentials, AskClientForCrossOriginCredentials, SkipSecurityCheck))
    , m_dataLoadTimer(this, &MainResourceLoader::handleDataLoadNow)
    , m_loadingMultipartContent(false)
    , m_waitingForContentPolicy(false)
    , m_timeOfLastDataReceived(0.0)
{
}
// FIXME: Skip Content Security Policy check when associated plugin element is in a user agent shadow tree.
// See <https://bugs.webkit.org/show_bug.cgi?id=146663>.
NetscapePlugInStreamLoader::NetscapePlugInStreamLoader(Frame* frame, NetscapePlugInStreamLoaderClient* client)
    : ResourceLoader(frame, ResourceLoaderOptions(SendCallbacks, SniffContent, DoNotBufferData, AllowStoredCredentials, AskClientForAllCredentials, SkipSecurityCheck, UseDefaultOriginRestrictionsForType, DoNotIncludeCertificateInfo, ContentSecurityPolicyImposition::DoPolicyCheck, DefersLoadingPolicy::AllowDefersLoading))
    , m_client(client)
{
#if ENABLE(CONTENT_EXTENSIONS)
    m_resourceType = ResourceType::PlugInStream;
#endif
}
Example #8
0
MainResourceLoader::MainResourceLoader(Frame* frame)
    : ResourceLoader(frame, ResourceLoaderOptions(SendCallbacks, SniffContent, BufferData, AllowStoredCredentials, AskClientForCrossOriginCredentials, SkipSecurityCheck))
    , m_dataLoadTimer(this, &MainResourceLoader::handleSubstituteDataLoadNow)
    , m_loadingMultipartContent(false)
    , m_waitingForContentPolicy(false)
    , m_timeOfLastDataReceived(0.0)
#if PLATFORM(MAC) && !PLATFORM(IOS) && __MAC_OS_X_VERSION_MIN_REQUIRED >= 1080
    , m_filter(0)
#endif
{
}
TEST(ImageResourceTest, MultipartImage)
{
    ResourceFetcher* fetcher = ResourceFetcher::create(nullptr);
    KURL testURL(ParsedURLString, "http://www.test.com/cancelTest.html");
    URLTestHelpers::registerMockedURLLoad(testURL, "cancelTest.html", "text/html");

    // Emulate starting a real load, but don't expect any "real" WebURLLoaderClient callbacks.
    ResourcePtr<ImageResource> cachedImage = new ImageResource(ResourceRequest(testURL), nullptr);
    cachedImage->setIdentifier(createUniqueIdentifier());
    cachedImage->load(fetcher, ResourceLoaderOptions());
    Platform::current()->unitTestSupport()->unregisterMockedURL(testURL);

    MockImageResourceClient client(cachedImage);
    EXPECT_EQ(Resource::Pending, cachedImage->status());

    // Send the multipart response. No image or data buffer is created.
    // Note that the response must be routed through ResourceLoader to
    // ensure the load is flagged as multipart.
    ResourceResponse multipartResponse(KURL(), "multipart/x-mixed-replace", 0, nullAtom, String());
    cachedImage->loader()->didReceiveResponse(nullptr, WrappedResourceResponse(multipartResponse), nullptr);
    ASSERT_FALSE(cachedImage->resourceBuffer());
    ASSERT_FALSE(cachedImage->hasImage());
    ASSERT_EQ(client.imageChangedCount(), 0);
    ASSERT_FALSE(client.notifyFinishedCalled());

    // Send the response for the first real part. No image or data buffer is created.
    const char* svgData = "<svg xmlns='http://www.w3.org/2000/svg' width='1' height='1'><rect width='1' height='1' fill='green'/></svg>";
    unsigned svgDataLength = strlen(svgData);
    ResourceResponse payloadResponse(KURL(), "image/svg+xml", svgDataLength, nullAtom, String());
    cachedImage->loader()->didReceiveResponse(nullptr, WrappedResourceResponse(payloadResponse), nullptr);
    ASSERT_FALSE(cachedImage->resourceBuffer());
    ASSERT_FALSE(cachedImage->hasImage());
    ASSERT_EQ(client.imageChangedCount(), 0);
    ASSERT_FALSE(client.notifyFinishedCalled());

    // The first bytes arrive. The data buffer is created, but no image is created.
    cachedImage->appendData(svgData, svgDataLength);
    ASSERT_TRUE(cachedImage->resourceBuffer());
    ASSERT_EQ(cachedImage->resourceBuffer()->size(), svgDataLength);
    ASSERT_FALSE(cachedImage->hasImage());
    ASSERT_EQ(client.imageChangedCount(), 0);
    ASSERT_FALSE(client.notifyFinishedCalled());

    // This part finishes. The image is created, callbacks are sent, and the data buffer is cleared.
    cachedImage->finish();
    ASSERT_FALSE(cachedImage->resourceBuffer());
    ASSERT_FALSE(cachedImage->errorOccurred());
    ASSERT_TRUE(cachedImage->hasImage());
    ASSERT_FALSE(cachedImage->image()->isNull());
    ASSERT_EQ(cachedImage->image()->width(), 1);
    ASSERT_EQ(cachedImage->image()->height(), 1);
    ASSERT_EQ(client.imageChangedCount(), 2);
    ASSERT_TRUE(client.notifyFinishedCalled());
}
void DocumentThreadableLoader::loadActualRequest()
{
    ResourceRequest actualRequest = m_actualRequest;
    ResourceLoaderOptions actualOptions = m_actualOptions;
    m_actualRequest = ResourceRequest();
    m_actualOptions = ResourceLoaderOptions();

    actualRequest.setHTTPOrigin(securityOrigin());

    clearResource();

    loadRequest(actualRequest, actualOptions);
}
Example #11
0
void IconLoader::startLoading()
{
    if (m_resource || !m_frame.document())
        return;

    CachedResourceRequest request(ResourceRequest(m_frame.loader().icon().url()), ResourceLoaderOptions(SendCallbacks, SniffContent, BufferData, DoNotAllowStoredCredentials, DoNotAskClientForAnyCredentials, DoSecurityCheck, UseDefaultOriginRestrictionsForType, DoNotIncludeCertificateInfo));

    request.mutableResourceRequest().setPriority(ResourceLoadPriorityLow);
    request.setInitiator(cachedResourceRequestInitiators().icon);

    m_resource = m_frame.document()->cachedResourceLoader().requestRawResource(request);
    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());
}
Example #12
0
void DocumentThreadableLoader::loadActualRequest() {
  ResourceRequest actualRequest = m_actualRequest;
  ResourceLoaderOptions actualOptions = m_actualOptions;
  m_actualRequest = ResourceRequest();
  m_actualOptions = ResourceLoaderOptions();

  clearResource();

  // Explicitly set the SkipServiceWorker flag here. Even if the page was not
  // controlled by a SW when the preflight request was sent, a new SW may be
  // controlling the page now by calling clients.claim(). We should not send
  // the actual request to the SW. https://crbug.com/604583
  actualRequest.setSkipServiceWorker(WebURLRequest::SkipServiceWorker::All);

  prepareCrossOriginRequest(actualRequest);
  loadRequest(actualRequest, actualOptions);
}
Example #13
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());
}
bool MediaResourceLoader::start(const ResourceRequest& request, LoadOptions options)
{
    if (m_resource)
        return false;

    DataBufferingPolicy bufferingPolicy = options & LoadOption::BufferData ? WebCore::BufferData : WebCore::DoNotBufferData;
    RequestOriginPolicy corsPolicy = !m_crossOriginMode.isNull() ? PotentiallyCrossOriginEnabled : UseDefaultOriginRestrictionsForType;
    StoredCredentials allowCredentials = m_crossOriginMode.isNull() || equalIgnoringCase(m_crossOriginMode, "use-credentials") ? AllowStoredCredentials : DoNotAllowStoredCredentials;

    // ContentSecurityPolicyImposition::DoPolicyCheck is a placeholder value. It does not affect the request since Content Security Policy does not apply to raw resources.
    CachedResourceRequest cacheRequest(request, ResourceLoaderOptions(SendCallbacks, DoNotSniffContent, bufferingPolicy, allowCredentials, DoNotAskClientForCrossOriginCredentials, DoSecurityCheck, corsPolicy, DoNotIncludeCertificateInfo, ContentSecurityPolicyImposition::DoPolicyCheck, DefersLoadingPolicy::AllowDefersLoading));

    if (!m_crossOriginMode.isNull())
        updateRequestForAccessControl(cacheRequest.mutableResourceRequest(), m_document.securityOrigin(), allowCredentials);

    m_didPassAccessControlCheck = false;

    m_resource = m_document.cachedResourceLoader().requestRawResource(cacheRequest);
    if (!m_resource)
        return false;

    m_resource->addClient(this);
    return true;
}
NetscapePlugInStreamLoader::NetscapePlugInStreamLoader(Frame* frame, NetscapePlugInStreamLoaderClient* client)
    : ResourceLoader(frame, ResourceLoaderOptions(SendCallbacks, SniffContent, DoNotBufferData, AllowStoredCredentials, AskClientForAllCredentials, SkipSecurityCheck, UseDefaultOriginRestrictionsForType))
    , m_client(client)
{
}
Example #16
0
CSSStyleSheetResource* CSSStyleSheetResource::createForTest(
    const ResourceRequest& request,
    const String& charset) {
    return new CSSStyleSheetResource(request, ResourceLoaderOptions(), charset);
}
Example #17
0
 static FakeResource* create(const ResourceRequest& request, Type type) {
   return new FakeResource(request, type, ResourceLoaderOptions());
 }