⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 resourceloader.cpp

📁 linux下开源浏览器WebKit的源码,市面上的很多商用浏览器都是移植自WebKit
💻 CPP
字号:
/* * Copyright (C) 2006, 2007 Apple Inc. All rights reserved. *           (C) 2007 Graham Dennis (graham.dennis@gmail.com) * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1.  Redistributions of source code must retain the above copyright *     notice, this list of conditions and the following disclaimer.  * 2.  Redistributions in binary form must reproduce the above copyright *     notice, this list of conditions and the following disclaimer in the *     documentation and/or other materials provided with the distribution.  * 3.  Neither the name of Apple Computer, Inc. ("Apple") nor the names of *     its contributors may be used to endorse or promote products derived *     from this software without specific prior written permission.  * * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */#include "config.h"#include "ResourceLoader.h"#include "DocumentLoader.h"#include "Frame.h"#include "FrameLoader.h"#include "Page.h"#include "ProgressTracker.h"#include "ResourceHandle.h"#include "ResourceError.h"#include "Settings.h"#include "SharedBuffer.h"namespace WebCore {PassRefPtr<SharedBuffer> ResourceLoader::resourceData(){    if (m_resourceData)        return m_resourceData;    if (ResourceHandle::supportsBufferedData() && m_handle)        return m_handle->bufferedData();        return 0;}ResourceLoader::ResourceLoader(Frame* frame, bool sendResourceLoadCallbacks, bool shouldContentSniff)    : m_frame(frame)    , m_documentLoader(frame->loader()->activeDocumentLoader())    , m_identifier(0)    , m_reachedTerminalState(false)    , m_cancelled(false)    , m_calledDidFinishLoad(false)    , m_sendResourceLoadCallbacks(sendResourceLoadCallbacks)    , m_shouldContentSniff(shouldContentSniff)    , m_shouldBufferData(true)    , m_defersLoading(frame->page()->defersLoading()){}ResourceLoader::~ResourceLoader(){    ASSERT(m_reachedTerminalState);}void ResourceLoader::releaseResources(){    ASSERT(!m_reachedTerminalState);        // It's possible that when we release the handle, it will be    // deallocated and release the last reference to this object.    // We need to retain to avoid accessing the object after it    // has been deallocated and also to avoid reentering this method.    RefPtr<ResourceLoader> protector(this);    m_frame = 0;    m_documentLoader = 0;        // We need to set reachedTerminalState to true before we release    // the resources to prevent a double dealloc of WebView <rdar://problem/4372628>    m_reachedTerminalState = true;    m_identifier = 0;    if (m_handle) {        // Clear out the ResourceHandle's client so that it doesn't try to call        // us back after we release it.        m_handle->setClient(0);        m_handle = 0;    }    m_resourceData = 0;    m_deferredRequest = ResourceRequest();}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->scheduleApplicationCacheLoad(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;}void ResourceLoader::setDefersLoading(bool defers){    m_defersLoading = defers;    if (m_handle)        m_handle->setDefersLoading(defers);    if (!defers && !m_deferredRequest.isNull()) {        ResourceRequest request(m_deferredRequest);        m_deferredRequest = ResourceRequest();        load(request);    }}FrameLoader* ResourceLoader::frameLoader() const{    if (!m_frame)        return 0;    return m_frame->loader();}void ResourceLoader::setShouldBufferData(bool shouldBufferData){     m_shouldBufferData = shouldBufferData;     // Reset any already buffered data    if (!m_shouldBufferData)        m_resourceData = 0;}    void ResourceLoader::addData(const char* data, int length, bool allAtOnce){    if (!m_shouldBufferData)        return;    if (allAtOnce) {        m_resourceData = SharedBuffer::create(data, length);        return;    }            if (ResourceHandle::supportsBufferedData()) {        // Buffer data only if the connection has handed us the data because is has stopped buffering it.        if (m_resourceData)            m_resourceData->append(data, length);    } else {        if (!m_resourceData)            m_resourceData = SharedBuffer::create(data, length);        else            m_resourceData->append(data, length);    }}void ResourceLoader::clearResourceData(){    if (m_resourceData)        m_resourceData->clear();}#if ENABLE(OFFLINE_WEB_APPLICATIONS)bool ResourceLoader::scheduleLoadFallbackResourceFromApplicationCache(ApplicationCache* cache){    if (documentLoader()->scheduleLoadFallbackResourceFromApplicationCache(this, m_request, cache)) {        handle()->cancel();        return true;    }    return false;}#endifvoid ResourceLoader::willSendRequest(ResourceRequest& request, const ResourceResponse& redirectResponse){    // Protect this in this delegate method since the additional processing can do    // anything including possibly derefing this; one example of this is Radar 3266216.    RefPtr<ResourceLoader> protector(this);            ASSERT(!m_reachedTerminalState);    if (m_sendResourceLoadCallbacks) {        if (!m_identifier) {            m_identifier = m_frame->page()->progress()->createUniqueIdentifier();            frameLoader()->assignIdentifierToInitialRequest(m_identifier, request);        }        frameLoader()->willSendRequest(this, request, redirectResponse);    }        m_request = request;}void ResourceLoader::didSendData(unsigned long long, unsigned long long){}void ResourceLoader::didReceiveResponse(const ResourceResponse& r){    ASSERT(!m_reachedTerminalState);    // Protect this in this delegate method since the additional processing can do    // anything including possibly derefing this; one example of this is Radar 3266216.    RefPtr<ResourceLoader> protector(this);    m_response = r;    if (FormData* data = m_request.httpBody())        data->removeGeneratedFilesIfNeeded();            if (m_sendResourceLoadCallbacks)        frameLoader()->didReceiveResponse(this, m_response);}void ResourceLoader::didReceiveData(const char* data, int length, long long lengthReceived, bool allAtOnce){    // The following assertions are not quite valid here, since a subclass    // might override didReceiveData in a way that invalidates them. This    // happens with the steps listed in 3266216    // ASSERT(con == connection);    // ASSERT(!m_reachedTerminalState);    // Protect this in this delegate method since the additional processing can do    // anything including possibly derefing this; one example of this is Radar 3266216.    RefPtr<ResourceLoader> protector(this);    addData(data, length, allAtOnce);    // FIXME: If we get a resource with more than 2B bytes, this code won't do the right thing.    // However, with today's computers and networking speeds, this won't happen in practice.    // Could be an issue with a giant local file.    if (m_sendResourceLoadCallbacks && m_frame)        frameLoader()->didReceiveData(this, data, length, static_cast<int>(lengthReceived));}void ResourceLoader::willStopBufferingData(const char* data, int length){    if (!m_shouldBufferData)        return;    ASSERT(!m_resourceData);    m_resourceData = SharedBuffer::create(data, length);}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();}void ResourceLoader::didFinishLoadingOnePart(){    if (m_cancelled)        return;    ASSERT(!m_reachedTerminalState);    if (m_calledDidFinishLoad)        return;    m_calledDidFinishLoad = true;    if (m_sendResourceLoadCallbacks)        frameLoader()->didFinishLoad(this);}void ResourceLoader::didFail(const ResourceError& error){    if (m_cancelled)        return;    ASSERT(!m_reachedTerminalState);    // Protect this in this delegate method since the additional processing can do    // anything including possibly derefing this; one example of this is Radar 3266216.    RefPtr<ResourceLoader> protector(this);    if (FormData* data = m_request.httpBody())        data->removeGeneratedFilesIfNeeded();    if (m_sendResourceLoadCallbacks && !m_calledDidFinishLoad)        frameLoader()->didFailToLoad(this, error);    releaseResources();}void ResourceLoader::didCancel(const ResourceError& error){    ASSERT(!m_cancelled);    ASSERT(!m_reachedTerminalState);    if (FormData* data = m_request.httpBody())        data->removeGeneratedFilesIfNeeded();    // This flag prevents bad behavior when loads that finish cause the    // load itself to be cancelled (which could happen with a javascript that     // changes the window location). This is used to prevent both the body    // of this method and the body of connectionDidFinishLoading: running    // for a single delegate. Cancelling wins.    m_cancelled = true;        if (m_handle)        m_handle->clearAuthentication();    m_documentLoader->cancelPendingSubstituteLoad(this);    if (m_handle) {        m_handle->cancel();        m_handle = 0;    }    if (m_sendResourceLoadCallbacks && !m_calledDidFinishLoad)        frameLoader()->didFailToLoad(this, error);    releaseResources();}void ResourceLoader::cancel(){    cancel(ResourceError());}void ResourceLoader::cancel(const ResourceError& error){    if (m_reachedTerminalState)        return;    if (!error.isNull())        didCancel(error);    else        didCancel(cancelledError());}const ResourceResponse& ResourceLoader::response() const{    return m_response;}ResourceError ResourceLoader::cancelledError(){    return frameLoader()->cancelledError(m_request);}ResourceError ResourceLoader::blockedError(){    return frameLoader()->blockedError(m_request);}ResourceError ResourceLoader::cannotShowURLError(){    return frameLoader()->cannotShowURLError(m_request);}void ResourceLoader::willSendRequest(ResourceHandle*, ResourceRequest& request, const ResourceResponse& redirectResponse){#if ENABLE(OFFLINE_WEB_APPLICATIONS)    if (!redirectResponse.isNull() && !protocolHostAndPortAreEqual(request.url(), redirectResponse.url())) {        if (scheduleLoadFallbackResourceFromApplicationCache())            return;    }#endif    willSendRequest(request, redirectResponse);}void ResourceLoader::didSendData(ResourceHandle*, unsigned long long bytesSent, unsigned long long totalBytesToBeSent){    didSendData(bytesSent, totalBytesToBeSent);}void ResourceLoader::didReceiveResponse(ResourceHandle*, const ResourceResponse& response){#if ENABLE(OFFLINE_WEB_APPLICATIONS)    if (response.httpStatusCode() / 100 == 4 || response.httpStatusCode() / 100 == 5) {        if (scheduleLoadFallbackResourceFromApplicationCache())            return;    }#endif    didReceiveResponse(response);}void ResourceLoader::didReceiveData(ResourceHandle*, const char* data, int length, int lengthReceived){    didReceiveData(data, length, lengthReceived, false);}void ResourceLoader::didFinishLoading(ResourceHandle*){    didFinishLoading();}void ResourceLoader::didFail(ResourceHandle*, const ResourceError& error){#if ENABLE(OFFLINE_WEB_APPLICATIONS)    if (!error.isCancellation()) {        if (documentLoader()->scheduleLoadFallbackResourceFromApplicationCache(this, m_request))            return;    }#endif    didFail(error);}void ResourceLoader::wasBlocked(ResourceHandle*){    didFail(blockedError());}void ResourceLoader::cannotShowURL(ResourceHandle*){    didFail(cannotShowURLError());}bool ResourceLoader::shouldUseCredentialStorage(){    RefPtr<ResourceLoader> protector(this);    return frameLoader()->shouldUseCredentialStorage(this);}void ResourceLoader::didReceiveAuthenticationChallenge(const AuthenticationChallenge& challenge){    // Protect this in this delegate method since the additional processing can do    // anything including possibly derefing this; one example of this is Radar 3266216.    RefPtr<ResourceLoader> protector(this);    frameLoader()->didReceiveAuthenticationChallenge(this, challenge);}void ResourceLoader::didCancelAuthenticationChallenge(const AuthenticationChallenge& challenge){    // Protect this in this delegate method since the additional processing can do    // anything including possibly derefing this; one example of this is Radar 3266216.    RefPtr<ResourceLoader> protector(this);    frameLoader()->didCancelAuthenticationChallenge(this, challenge);}void ResourceLoader::receivedCancellation(const AuthenticationChallenge&){    cancel();}void ResourceLoader::willCacheResponse(ResourceHandle*, CacheStoragePolicy& policy){    // When in private browsing mode, prevent caching to disk    if (policy == StorageAllowed && m_frame->settings()->privateBrowsingEnabled())        policy = StorageAllowedInMemoryOnly;    }}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -