bool ArgumentCoder<ResourceResponse>::decode(ArgumentDecoder* decoder, ResourceResponse& resourceResponse)
{
#if USE(CFNETWORK)
    bool responseIsPresent;
    if (!decoder->decode(responseIsPresent))
        return false;

    if (!responseIsPresent) {
        resourceResponse = ResourceResponse();
        return true;
    }

    RetainPtr<CFDictionaryRef> dictionary;
    if (!CoreIPC::decode(decoder, dictionary))
        return false;

    RetainPtr<CFURLResponseRef> cfURLResponse(AdoptCF, wkCFURLResponseCreateFromSerializableRepresentation(dictionary.get(), CoreIPC::tokenNullTypeRef()));
    if (!cfURLResponse)
        return false;

    resourceResponse = ResourceResponse(cfURLResponse.get());
    return true;
#else
    return false;
#endif
}
TEST(ImageResourceTest, DecodedDataRemainsWhileHasClients)
{
    ResourcePtr<ImageResource> cachedImage = new ImageResource(ResourceRequest(), nullptr);
    cachedImage->setLoading(true);

    MockImageResourceClient client(cachedImage);

    // Send the image response.
    cachedImage->responseReceived(ResourceResponse(KURL(), "multipart/x-mixed-replace", 0, nullAtom, String()), nullptr);

    Vector<unsigned char> jpeg = jpegImage();
    cachedImage->responseReceived(ResourceResponse(KURL(), "image/jpeg", jpeg.size(), nullAtom, String()), nullptr);
    cachedImage->appendData(reinterpret_cast<const char*>(jpeg.data()), jpeg.size());
    cachedImage->finish();
    ASSERT_FALSE(cachedImage->errorOccurred());
    ASSERT_TRUE(cachedImage->hasImage());
    ASSERT_FALSE(cachedImage->image()->isNull());
    ASSERT_TRUE(client.notifyFinishedCalled());

    // The prune comes when the ImageResource still has clients. The image should not be deleted.
    cachedImage->prune();
    ASSERT_TRUE(cachedImage->hasClients());
    ASSERT_TRUE(cachedImage->hasImage());
    ASSERT_FALSE(cachedImage->image()->isNull());

    // The ImageResource no longer has clients. The image should be deleted by prune.
    client.removeAsClient();
    cachedImage->prune();
    ASSERT_FALSE(cachedImage->hasClients());
    ASSERT_FALSE(cachedImage->hasImage());
    ASSERT_TRUE(cachedImage->image()->isNull());
}
Exemple #3
0
WebCore::ResourceResponse core(WebKitNetworkResponse* response)
{
    SoupMessage* soupMessage = webkit_network_response_get_message(response);
    if (soupMessage)
        return ResourceResponse(soupMessage);

    return ResourceResponse();
}
PassOwnPtr<ResourceTimingInfo> ResourceTimingInfo::adopt(PassOwnPtr<CrossThreadResourceTimingInfoData> data)
{
    OwnPtr<ResourceTimingInfo> info = ResourceTimingInfo::create(AtomicString(data->m_type), data->m_initialTime, data->m_isMainResource);
    info->m_originalTimingAllowOrigin = AtomicString(data->m_originalTimingAllowOrigin);
    info->m_loadFinishTime = data->m_loadFinishTime;
    info->m_initialRequest = ResourceRequest(data->m_initialRequest.get());
    info->m_finalResponse = ResourceResponse(data->m_finalResponse.get());
    for (auto& responseData : data->m_redirectChain)
        info->m_redirectChain.append(ResourceResponse(responseData.get()));
    return info.release();
}
static ResourceResponse createResourceResponseFromPropertyListData(CFDataRef data, CFStringRef responseDataType)
{
    ASSERT(data);
    if (!data)
        return ResourceResponse();
    
    // If the ResourceResponseVersion (passed in as responseDataType) exists at all, this is a "new" webarchive that we can parse well in a cross platform manner
    // If it doesn't exist, we will assume this is an "old" Cocoa-based WebArchive, and parse the ResourceResponse as such
    if (!responseDataType)
        return createResourceResponseFromMacArchivedData(data);
        
    // FIXME: Parse the "new" format that the above comment references here
    return ResourceResponse();
}
ResourceResponse LegacyWebArchive::createResourceResponseFromPropertyListData(CFDataRef data, CFStringRef responseDataType)
{
    ASSERT(data);
    if (!data)
        return ResourceResponse();
    
    // If the ResourceResponseVersion (passed in as responseDataType) exists at all, this is a "new" web archive that we
    // can parse well in a cross platform manner If it doesn't exist, we will assume this is an "old" web archive with,
    // NSURLResponse objects in it and parse the ResourceResponse as such.
    if (!responseDataType)
        return createResourceResponseFromMacArchivedData(data);
        
    // FIXME: Parse the "new" format that the above comment references here. This format doesn't exist yet.
    return ResourceResponse();
}
void WebLoaderStrategy::loadResourceSynchronously(NetworkingContext* context, unsigned long resourceLoadIdentifier, const ResourceRequest& request, StoredCredentials storedCredentials, ClientCredentialPolicy clientCredentialPolicy, ResourceError& error, ResourceResponse& response, Vector<char>& data)
{
    WebFrameNetworkingContext* webContext = static_cast<WebFrameNetworkingContext*>(context);
    // FIXME: Some entities in WebCore use WebCore's "EmptyFrameLoaderClient" instead of having a proper WebFrameLoaderClient.
    // EmptyFrameLoaderClient shouldn't exist and everything should be using a WebFrameLoaderClient,
    // but in the meantime we have to make sure not to mis-cast.
    WebFrameLoaderClient* webFrameLoaderClient = webContext->webFrameLoaderClient();
    WebFrame* webFrame = webFrameLoaderClient ? webFrameLoaderClient->webFrame() : 0;
    WebPage* webPage = webFrame ? webFrame->page() : 0;

    NetworkResourceLoadParameters loadParameters;
    loadParameters.identifier = resourceLoadIdentifier;
    loadParameters.webPageID = webPage ? webPage->pageID() : 0;
    loadParameters.webFrameID = webFrame ? webFrame->frameID() : 0;
    loadParameters.sessionID = webPage ? webPage->sessionID() : SessionID::defaultSessionID();
    loadParameters.request = request;
    loadParameters.contentSniffingPolicy = SniffContent;
    loadParameters.allowStoredCredentials = storedCredentials;
    loadParameters.clientCredentialPolicy = clientCredentialPolicy;
    loadParameters.shouldClearReferrerOnHTTPSToHTTPRedirect = context->shouldClearReferrerOnHTTPSToHTTPRedirect();

    data.resize(0);

    HangDetectionDisabler hangDetectionDisabler;

    if (!WebProcess::singleton().networkConnection()->connection()->sendSync(Messages::NetworkConnectionToWebProcess::PerformSynchronousLoad(loadParameters), Messages::NetworkConnectionToWebProcess::PerformSynchronousLoad::Reply(error, response, data), 0)) {
        response = ResourceResponse();
        error = internalError(request.url());
    }
}
bool ResourceLoader::load(const ResourceRequest& r)
{
    ASSERT(!m_handle);
    ASSERT(m_deferredRequest.isNull());
    ASSERT(!m_documentLoader->isSubstituteLoadPending(this));
    
    ResourceRequest clientRequest(r);
    willSendRequest(clientRequest, ResourceResponse());
    if (clientRequest.isNull()) {
        didFail(frameLoader()->cancelledError(r));
        return false;
    }
    
    if (m_documentLoader->scheduleArchiveLoad(this, clientRequest, r.url()))
        return true;
    
#if ENABLE(OFFLINE_WEB_APPLICATIONS)
    if (m_documentLoader->applicationCacheHost()->maybeLoadResource(this, clientRequest, r.url()))
        return true;
#endif

    if (m_defersLoading) {
        m_deferredRequest = clientRequest;
        return true;
    }
    
    m_handle = ResourceHandle::create(clientRequest, this, m_frame.get(), m_defersLoading, m_shouldContentSniff, true);

    return true;
}
Exemple #9
0
void MainResourceLoader::dataReceived(CachedResource* resource, const char* data, int length)
{
    ASSERT(data);
    ASSERT(length != 0);
    ASSERT_UNUSED(resource, resource == m_resource);
    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 = m_documentLoader.get())
            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.
            documentLoader()->receivedData(0, 0);
            return;
        }

        data = blockedData;
    }
#endif

    documentLoader()->applicationCacheHost()->mainResourceDataReceived(data, length, -1, false);

    // 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();

    documentLoader()->receivedData(data, length);

#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
}
void ResourceHandle::loadResourceSynchronously(const ResourceRequest& request, ResourceError& error, ResourceResponse& response, Vector<char>& vector, Frame*)
{
    ASSERT(!request.isEmpty());
    CFURLResponseRef cfResponse = 0;
    CFErrorRef cfError = 0;
    RetainPtr<CFURLRequestRef> cfRequest(AdoptCF, makeFinalRequest(request, true));

    CFDataRef data = CFURLConnectionSendSynchronousRequest(cfRequest.get(), &cfResponse, &cfError, request.timeoutInterval());

    if (cfError) {
        error = cfError;
        CFRelease(cfError);

        response = ResourceResponse(request.url(), String(), 0, String(), String());
        response.setHTTPStatusCode(404);
    } else {
        response = cfResponse;
        if (cfResponse)
            CFRelease(cfResponse);
    }

    if (data) {
        ASSERT(vector.isEmpty());
        vector.append(CFDataGetBytePtr(data), CFDataGetLength(data));
        CFRelease(data);
    }
}
Exemple #11
0
void WebResourceLoader::didReceiveResponseWithCertificateInfo(const ResourceResponse& response, const CertificateInfo& certificateInfo, bool needsContinueDidReceiveResponseMessage)
{
    LOG(Network, "(WebProcess) WebResourceLoader::didReceiveResponseWithCertificateInfo for '%s'. Status %d.", m_coreLoader->url().string().utf8().data(), response.httpStatusCode());

    Ref<WebResourceLoader> protect(*this);

    ResourceResponse responseCopy(response);

#if USE(QUICK_LOOK)
    m_quickLookHandle = QuickLookHandle::create(resourceLoader(), response.nsURLResponse());
    if (m_quickLookHandle)
        responseCopy = ResourceResponse(m_quickLookHandle->nsResponse());
#endif

    // FIXME: This should use CertificateInfo to avoid the platform ifdefs. See https://bugs.webkit.org/show_bug.cgi?id=124724.
#if PLATFORM(COCOA)
    responseCopy.setCertificateChain(certificateInfo.certificateChain());
#elif USE(SOUP)
    responseCopy.setSoupMessageCertificate(certificateInfo.certificate());
    responseCopy.setSoupMessageTLSErrors(certificateInfo.tlsErrors());
#endif
    if (m_coreLoader->documentLoader()->applicationCacheHost()->maybeLoadFallbackForResponse(m_coreLoader.get(), responseCopy))
        return;
    m_coreLoader->didReceiveResponse(responseCopy);

    // If m_coreLoader becomes null as a result of the didReceiveResponse callback, we can't use the send function(). 
    if (!m_coreLoader)
        return;

    if (needsContinueDidReceiveResponseMessage)
        send(Messages::NetworkResourceLoader::ContinueDidReceiveResponse());
}
bool ResourceLoader::load(const ResourceRequest& r)
{
    ASSERT(!m_handle);
    ASSERT(m_deferredRequest.isNull());
    ASSERT(!frameLoader()->isArchiveLoadPending(this));
    
    m_originalURL = r.url();
    
    ResourceRequest clientRequest(r);
    willSendRequest(clientRequest, ResourceResponse());
    if (clientRequest.isNull()) {
        didFail(frameLoader()->cancelledError(r));
        return false;
    }
    
    if (frameLoader()->willUseArchive(this, clientRequest, m_originalURL))
        return true;
    
    if (m_defersLoading) {
        m_deferredRequest = clientRequest;
        return true;
    }
    
    m_handle = ResourceHandle::create(clientRequest, this, m_frame.get(), m_defersLoading, m_shouldContentSniff, true);

    return true;
}
Exemple #13
0
bool ResourceLoader::init(const ResourceRequest& r)
{
    ASSERT(!m_handle);
    ASSERT(m_request.isNull());
    ASSERT(m_deferredRequest.isNull());
    ASSERT(!m_documentLoader->isSubstituteLoadPending(this));

    ResourceRequest clientRequest(r);

    // https://bugs.webkit.org/show_bug.cgi?id=26391
    // The various plug-in implementations call directly to ResourceLoader::load() instead of piping requests
    // through FrameLoader. As a result, they miss the FrameLoader::addExtraFieldsToRequest() step which sets
    // up the 1st party for cookies URL. Until plug-in implementations can be reigned in to pipe through that
    // method, we need to make sure there is always a 1st party for cookies set.
    if (clientRequest.firstPartyForCookies().isNull()) {
        if (Document* document = m_frame->document())
            clientRequest.setFirstPartyForCookies(document->firstPartyForCookies());
    }

    m_request = clientRequest;

    willSendRequest(m_request, ResourceResponse());
    if (m_request.isNull()) {
        didFail(frameLoader()->cancelledError(m_request));
        return false;
    }

    return true;
}
Exemple #14
0
RefPtr<ResourceHandle> ApplicationCacheGroup::createResourceHandle(const URL& url, ApplicationCacheResource* newestCachedResource)
{
    ResourceRequest request(url);
    m_frame->loader().applyUserAgent(request);
    request.setHTTPHeaderField(HTTPHeaderName::CacheControl, "max-age=0");

    if (newestCachedResource) {
        const String& lastModified = newestCachedResource->response().httpHeaderField(HTTPHeaderName::LastModified);
        const String& eTag = newestCachedResource->response().httpHeaderField(HTTPHeaderName::ETag);
        if (!lastModified.isEmpty() || !eTag.isEmpty()) {
            if (!lastModified.isEmpty())
                request.setHTTPHeaderField(HTTPHeaderName::IfModifiedSince, lastModified);
            if (!eTag.isEmpty())
                request.setHTTPHeaderField(HTTPHeaderName::IfNoneMatch, eTag);
        }
    }

    RefPtr<ResourceHandle> handle = ResourceHandle::create(m_frame->loader().networkingContext(), request, this, false, true);

    // Because willSendRequest only gets called during redirects, we initialize
    // the identifier and the first willSendRequest here.
    m_currentResourceIdentifier = m_frame->page()->progress().createUniqueIdentifier();
    ResourceResponse redirectResponse = ResourceResponse();
    InspectorInstrumentation::willSendRequest(m_frame, m_currentResourceIdentifier, m_frame->loader().documentLoader(), request, redirectResponse);
    return handle;
}
Exemple #15
0
bool ResourceLoader::init(const ResourceRequest& r) {
    ResourceRequest clientRequest(r);

    willSendRequest(clientRequest, ResourceResponse());
    m_request = clientRequest;
    return true;
}
Exemple #16
0
bool MainResourceLoader::loadNow(ResourceRequest& r)
{
    bool shouldLoadEmptyBeforeRedirect = shouldLoadAsEmptyDocument(r.url());

    ASSERT(!m_handle);
    ASSERT(shouldLoadEmptyBeforeRedirect || !defersLoading());

    // Send this synthetic delegate callback since clients expect it, and
    // we no longer send the callback from within NSURLConnection for
    // initial requests.
    willSendRequest(r, 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())
        return false;
    
    const KURL& url = r.url();
    bool shouldLoadEmpty = shouldLoadAsEmptyDocument(url) && !m_substituteData.isValid();

    if (shouldLoadEmptyBeforeRedirect && !shouldLoadEmpty && defersLoading())
        return true;

    resourceLoadScheduler()->addMainResourceLoad(this);
    if (m_substituteData.isValid()) 
        handleSubstituteDataLoadSoon(r);
    else if (shouldLoadEmpty || frameLoader()->client()->representationExistsForURLScheme(url.protocol()))
        handleEmptyLoad(url, !shouldLoadEmpty);
    else
        m_handle = ResourceHandle::create(m_frame->loader()->networkingContext(), r, this, false, true);

    return false;
}
Exemple #17
0
bool ResourceLoader::init(const ResourceRequest& r)
{
    ASSERT(!m_handle);
    ASSERT(m_request.isNull());
    ASSERT(m_deferredRequest.isNull());
    ASSERT(!m_documentLoader->isSubstituteLoadPending(this));
    
    ResourceRequest clientRequest(r);
    
    m_defersLoading = m_frame->page()->defersLoading();
    if (m_options.securityCheck == DoSecurityCheck && !m_frame->document()->securityOrigin()->canDisplay(clientRequest.url())) {
        FrameLoader::reportLocalLoadFailed(m_frame.get(), clientRequest.url().string());
        releaseResources();
        return false;
    }
    
    // https://bugs.webkit.org/show_bug.cgi?id=26391
    // The various plug-in implementations call directly to ResourceLoader::load() instead of piping requests
    // through FrameLoader. As a result, they miss the FrameLoader::addExtraFieldsToRequest() step which sets
    // up the 1st party for cookies URL. Until plug-in implementations can be reigned in to pipe through that
    // method, we need to make sure there is always a 1st party for cookies set.
    if (clientRequest.firstPartyForCookies().isNull()) {
        if (Document* document = m_frame->document())
            clientRequest.setFirstPartyForCookies(document->firstPartyForCookies());
    }

    willSendRequest(clientRequest, ResourceResponse());
    if (clientRequest.isNull()) {
        cancel();
        return false;
    }

    m_originalRequest = m_request = clientRequest;
    return true;
}
ResourceResponse LegacyWebArchive::createResourceResponseFromMacArchivedData(CFDataRef responseData)
{
    // FIXME: If is is possible to parse in a serialized NSURLResponse manually, without using
    // NSKeyedUnarchiver, manipulating plists directly, then we want to do that here.
    // Until then, this can be done on Mac only.
    return ResourceResponse();
}
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 ENABLE(OFFLINE_WEB_APPLICATIONS)
    documentLoader()->applicationCacheHost()->mainResourceDataReceived(data, length, encodedDataLength, allAtOnce);
#endif

    // 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 = currentTime();

    ResourceLoader::didReceiveData(data, length, encodedDataLength, allAtOnce);
}
PassRefPtr<ResourceHandle> ApplicationCacheGroup::createResourceHandle(const KURL& url, ApplicationCacheResource* newestCachedResource)
{
    ResourceRequest request(url);
    m_frame->loader()->applyUserAgent(request);
    request.setHTTPHeaderField("Cache-Control", "max-age=0");

    if (newestCachedResource) {
        const String& lastModified = newestCachedResource->response().httpHeaderField("Last-Modified");
        const String& eTag = newestCachedResource->response().httpHeaderField("ETag");
        if (!lastModified.isEmpty() || !eTag.isEmpty()) {
            if (!lastModified.isEmpty())
                request.setHTTPHeaderField("If-Modified-Since", lastModified);
            if (!eTag.isEmpty())
                request.setHTTPHeaderField("If-None-Match", eTag);
        }
    }

    RefPtr<ResourceHandle> handle = ResourceHandle::create(m_frame->loader()->networkingContext(), request, this, false, true);
#if ENABLE(INSPECTOR)
    // Because willSendRequest only gets called during redirects, we initialize
    // the identifier and the first willSendRequest here.
    m_currentResourceIdentifier = m_frame->page()->progress()->createUniqueIdentifier();
    if (Page* page = m_frame->page()) {
        InspectorController* inspectorController = page->inspectorController();
        inspectorController->identifierForInitialRequest(m_currentResourceIdentifier, m_frame->loader()->documentLoader(), handle->firstRequest());
        ResourceResponse redirectResponse = ResourceResponse();
        inspectorController->willSendRequest(m_currentResourceIdentifier, request, redirectResponse);
    }
#endif
    return handle;
}
Exemple #21
0
void XMLHttpRequest::clearResponse()
{
    m_response = ResourceResponse();
    m_responseText = "";
    m_createdDocument = false;
    m_responseXML = 0;
}
Exemple #22
0
bool ArgumentCoder<ResourceResponse>::decode(ArgumentDecoder* decoder, ResourceResponse& resourceResponse)
{
    if (kShouldSerializeWebCoreData) {
        bool responseIsNull;
        if (!decoder->decode(responseIsNull))
            return false;
        if (responseIsNull) {
            resourceResponse = ResourceResponse();
            return true;
        }

        ResourceResponse response;

        String url;
        if (!decoder->decode(url))
            return false;
        response.setURL(KURL(KURL(), url));

        int32_t httpStatusCode;
        if (!decoder->decode(httpStatusCode))
            return false;
        response.setHTTPStatusCode(httpStatusCode);

        HTTPHeaderMap headers;
        if (!decoder->decode(headers))
            return false;
        for (HTTPHeaderMap::const_iterator it = headers.begin(), end = headers.end(); it != end; ++it)
            response.setHTTPHeaderField(it->key, it->value);

        String mimeType;
        if (!decoder->decode(mimeType))
            return false;
        response.setMimeType(mimeType);

        String textEncodingName;
        if (!decoder->decode(textEncodingName))
            return false;
        response.setTextEncodingName(textEncodingName);

        int64_t contentLength;
        if (!decoder->decode(contentLength))
            return false;
        response.setExpectedContentLength(contentLength);

        String httpStatusText;
        if (!decoder->decode(httpStatusText))
            return false;
        response.setHTTPStatusText(httpStatusText);

        String suggestedFilename;
        if (!decoder->decode(suggestedFilename))
            return false;
        response.setSuggestedFilename(suggestedFilename);

        resourceResponse = response;
    }

    return decodePlatformData(decoder, resourceResponse);
}
Exemple #23
0
void WebDevToolsAgentImpl::willSendRequest(unsigned long resourceId, WebURLRequest& request)
{
    if (InspectorController* ic = inspectorController()) {
        ic->willSendRequest(resourceId, request.toMutableResourceRequest(), ResourceResponse());
        if (ic->hasFrontend() && request.reportLoadTiming())
            request.setReportRawHeaders(true);
    }
}
Exemple #24
0
void MainResourceLoader::dataReceived(CachedResource* resource, const char* data, int length)
{
    ASSERT(data);
    ASSERT(length != 0);
    ASSERT_UNUSED(resource, resource == m_resource);
    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 = m_documentLoader.get())
            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 USE(CONTENT_FILTERING)
    bool loadWasBlockedBeforeFinishing = false;
    if (m_contentFilter && m_contentFilter->needsMoreData()) {
        m_contentFilter->addData(data, length);

        if (m_contentFilter->needsMoreData()) {
            // Since the filter still needs more data to make a decision,
            // transition back to the committed state so that we don't partially
            // load content that might later be blocked.
            documentLoader()->receivedData(0, 0);
            return;
        }

        data = m_contentFilter->getReplacementData(length);
        loadWasBlockedBeforeFinishing = m_contentFilter->didBlockData();
    }
#endif

    if (!loader())
        frameLoader()->notifier()->dispatchDidReceiveData(documentLoader(), identifier(), data, length, -1);

    documentLoader()->applicationCacheHost()->mainResourceDataReceived(data, length, -1, false);

    // 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();

    documentLoader()->receivedData(data, length);

#if USE(CONTENT_FILTERING)
    if (loadWasBlockedBeforeFinishing)
        cancel();
#endif
}
Exemple #25
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()) {
        m_identifierForLoadWithoutResourceLoader = m_documentLoader->frame()->page()->progress()->createUniqueIdentifier();
        frameLoader()->notifier()->assignIdentifierToInitialRequest(m_identifierForLoadWithoutResourceLoader, documentLoader(), request);
        frameLoader()->notifier()->dispatchWillSendRequest(documentLoader(), m_identifierForLoadWithoutResourceLoader, request, ResourceResponse());
        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;
    }
    if (!loader()) {
        m_identifierForLoadWithoutResourceLoader = m_documentLoader->frame()->page()->progress()->createUniqueIdentifier();
        frameLoader()->notifier()->assignIdentifierToInitialRequest(m_identifierForLoadWithoutResourceLoader, documentLoader(), request);
        frameLoader()->notifier()->dispatchWillSendRequest(documentLoader(), m_identifierForLoadWithoutResourceLoader, request, ResourceResponse());
    }
    m_resource->addClient(this);

    // A bunch of headers are set when the underlying ResourceLoader is created, and DocumentLoader::m_request needs to include those.
    if (loader())
        request = loader()->originalRequest();
    // If there was a fragment identifier on initialRequest, the cache will have stripped it. DocumentLoader::m_request should include
    // the fragment identifier, so add that back in.
    if (equalIgnoringFragmentIdentifier(initialRequest.url(), request.url()))
        request.setURL(initialRequest.url());
    documentLoader()->setRequest(request);
}
Exemple #26
0
void XMLHttpRequest::clearResponse()
{
    m_response = ResourceResponse();
    {
        JSC::JSLock lock(false);
        m_responseText = "";
    }
    m_createdDocument = false;
    m_responseXML = 0;
}
Exemple #27
0
void XMLHttpRequest::clearResponse()
{
    m_response = ResourceResponse();
    m_responseBuilder.clear();
    m_createdDocument = false;
    m_responseXML = 0;
#if ENABLE(XHR_RESPONSE_BLOB)
    m_responseBlob = 0;
#endif
}
TEST(ImageResourceTest, DecodedDataRemainsWhileHasClients) {
  ImageResource* cachedImage = ImageResource::create(ResourceRequest());
  cachedImage->setStatus(Resource::Pending);

  Persistent<MockImageResourceClient> client =
      new MockImageResourceClient(cachedImage);

  // Send the image response.
  cachedImage->responseReceived(
      ResourceResponse(KURL(), "multipart/x-mixed-replace", 0, nullAtom,
                       String()),
      nullptr);

  Vector<unsigned char> jpeg = jpegImage();
  cachedImage->responseReceived(
      ResourceResponse(KURL(), "image/jpeg", jpeg.size(), nullAtom, String()),
      nullptr);
  cachedImage->appendData(reinterpret_cast<const char*>(jpeg.data()),
                          jpeg.size());
  EXPECT_NE(0u, cachedImage->encodedSizeMemoryUsageForTesting());
  cachedImage->finish();
  EXPECT_EQ(0u, cachedImage->encodedSizeMemoryUsageForTesting());
  EXPECT_FALSE(cachedImage->errorOccurred());
  ASSERT_TRUE(cachedImage->hasImage());
  EXPECT_FALSE(cachedImage->getImage()->isNull());
  EXPECT_TRUE(client->notifyFinishedCalled());

  // The prune comes when the ImageResource still has clients. The image should
  // not be deleted.
  cachedImage->prune();
  EXPECT_TRUE(cachedImage->isAlive());
  ASSERT_TRUE(cachedImage->hasImage());
  EXPECT_FALSE(cachedImage->getImage()->isNull());

  // The ImageResource no longer has clients. The decoded image data should be
  // deleted by prune.
  client->removeAsClient();
  cachedImage->prune();
  EXPECT_FALSE(cachedImage->isAlive());
  EXPECT_TRUE(cachedImage->hasImage());
  // TODO(hajimehoshi): Should check cachedImage doesn't have decoded image
  // data.
}
void ResourceLoader::init(const ResourceRequest& passedRequest)
{
    ResourceRequest request(passedRequest);
    m_host->willSendRequest(m_resource->identifier(), request, ResourceResponse(), m_options);
    request.setReportLoadTiming(true);
    ASSERT(m_state != Terminated);
    ASSERT(!request.isNull());
    m_originalRequest = m_request = request;
    m_host->didInitializeResourceLoader(this);
}
Exemple #30
0
void DocumentLoader::startLoadingMainResource()
{
    m_mainDocumentError = ResourceError();
    timing()->markNavigationStart();
    ASSERT(!m_mainResource);
    ASSERT(!m_loadingMainResource);
    m_loadingMainResource = true;

    if (maybeLoadEmpty())
        return;

    ASSERT(timing()->navigationStart());
    ASSERT(!timing()->fetchStart());
    timing()->markFetchStart();
    willSendRequest(m_request, ResourceResponse());

    // willSendRequest() may lead to our Frame being detached or cancelling the load via nulling the ResourceRequest.
    if (!m_frame || m_request.isNull())
        return;

    m_applicationCacheHost->willStartLoadingMainResource(m_request);
    prepareSubframeArchiveLoadIfNeeded();

    if (m_substituteData.isValid()) {
        m_identifierForLoadWithoutResourceLoader = createUniqueIdentifier();
        frameLoader()->notifier()->dispatchWillSendRequest(this, m_identifierForLoadWithoutResourceLoader, m_request, ResourceResponse());
        handleSubstituteDataLoadSoon();
        return;
    }

    ResourceRequest request(m_request);
    DEFINE_STATIC_LOCAL(ResourceLoaderOptions, mainResourceLoadOptions,
        (SendCallbacks, SniffContent, DoNotBufferData, AllowStoredCredentials, ClientRequestedCredentials, AskClientForCrossOriginCredentials, SkipSecurityCheck, CheckContentSecurityPolicy, UseDefaultOriginRestrictionsForType));
    CachedResourceRequest cachedResourceRequest(request, cachedResourceRequestInitiators().document, mainResourceLoadOptions);
    m_mainResource = m_cachedResourceLoader->requestMainResource(cachedResourceRequest);
    if (!m_mainResource) {
        setRequest(ResourceRequest());
        // If the load was aborted by clearing m_request, it's possible the ApplicationCacheHost
        // is now in a state where starting an empty load will be inconsistent. Replace it with
        // a new ApplicationCacheHost.
        m_applicationCacheHost = adoptPtr(new ApplicationCacheHost(this));
        maybeLoadEmpty();
        return;
    }
    m_mainResource->addClient(this);

    // A bunch of headers are set when the underlying ResourceLoader is created, and m_request needs to include those.
    if (mainResourceLoader())
        request = mainResourceLoader()->originalRequest();
    // If there was a fragment identifier on m_request, the cache will have stripped it. m_request should include
    // the fragment identifier, so add that back in.
    if (equalIgnoringFragmentIdentifier(m_request.url(), request.url()))
        request.setURL(m_request.url());
    setRequest(request);
}