diff options
author | Oswald Buddenhagen <oswald.buddenhagen@qt.io> | 2017-05-30 12:48:17 +0200 |
---|---|---|
committer | Oswald Buddenhagen <oswald.buddenhagen@qt.io> | 2017-05-30 12:48:17 +0200 |
commit | 881da28418d380042aa95a97f0cbd42560a64f7c (patch) | |
tree | a794dff3274695e99c651902dde93d934ea7a5af /Source/WebKit2/WebProcess/Network | |
parent | 7e104c57a70fdf551bb3d22a5d637cdcbc69dbea (diff) | |
parent | 0fcedcd17cc00d3dd44c718b3cb36c1033319671 (diff) | |
download | qtwebkit-881da28418d380042aa95a97f0cbd42560a64f7c.tar.gz |
Merge 'wip/next' into dev
Change-Id: Iff9ee5e23bb326c4371ec8ed81d56f2f05d680e9
Diffstat (limited to 'Source/WebKit2/WebProcess/Network')
10 files changed, 593 insertions, 420 deletions
diff --git a/Source/WebKit2/WebProcess/Network/NetworkProcessConnection.cpp b/Source/WebKit2/WebProcess/Network/NetworkProcessConnection.cpp index dfa859fce..5564f6a0b 100644 --- a/Source/WebKit2/WebProcess/Network/NetworkProcessConnection.cpp +++ b/Source/WebKit2/WebProcess/Network/NetworkProcessConnection.cpp @@ -29,23 +29,21 @@ #include "DataReference.h" #include "NetworkConnectionToWebProcessMessages.h" #include "WebCoreArgumentCoders.h" +#include "WebLoaderStrategy.h" #include "WebProcess.h" -#include "WebResourceBuffer.h" -#include "WebResourceLoadScheduler.h" #include "WebResourceLoaderMessages.h" #include <WebCore/CachedResource.h> #include <WebCore/MemoryCache.h> -#include <WebCore/ResourceBuffer.h> - -#if ENABLE(NETWORK_PROCESS) +#include <WebCore/SessionID.h> +#include <WebCore/SharedBuffer.h> using namespace WebCore; namespace WebKit { -NetworkProcessConnection::NetworkProcessConnection(CoreIPC::Connection::Identifier connectionIdentifier) +NetworkProcessConnection::NetworkProcessConnection(IPC::Connection::Identifier connectionIdentifier) { - m_connection = CoreIPC::Connection::createClientConnection(connectionIdentifier, this, RunLoop::main()); + m_connection = IPC::Connection::createClientConnection(connectionIdentifier, *this); m_connection->open(); } @@ -53,10 +51,10 @@ NetworkProcessConnection::~NetworkProcessConnection() { } -void NetworkProcessConnection::didReceiveMessage(CoreIPC::Connection* connection, CoreIPC::MessageDecoder& decoder) +void NetworkProcessConnection::didReceiveMessage(IPC::Connection& connection, IPC::MessageDecoder& decoder) { if (decoder.messageReceiverName() == Messages::WebResourceLoader::messageReceiverName()) { - if (WebResourceLoader* webResourceLoader = WebProcess::shared().webResourceLoadScheduler().webResourceLoaderForIdentifier(decoder.destinationID())) + if (WebResourceLoader* webResourceLoader = WebProcess::singleton().webLoaderStrategy().webResourceLoaderForIdentifier(decoder.destinationID())) webResourceLoader->didReceiveWebResourceLoaderMessage(connection, decoder); return; @@ -65,36 +63,36 @@ void NetworkProcessConnection::didReceiveMessage(CoreIPC::Connection* connection didReceiveNetworkProcessConnectionMessage(connection, decoder); } -void NetworkProcessConnection::didReceiveSyncMessage(CoreIPC::Connection* connection, CoreIPC::MessageDecoder& decoder, OwnPtr<CoreIPC::MessageEncoder>& replyEncoder) +void NetworkProcessConnection::didReceiveSyncMessage(IPC::Connection&, IPC::MessageDecoder&, std::unique_ptr<IPC::MessageEncoder>&) { ASSERT_NOT_REACHED(); } -void NetworkProcessConnection::didClose(CoreIPC::Connection*) +void NetworkProcessConnection::didClose(IPC::Connection&) { // The NetworkProcess probably crashed. - WebProcess::shared().networkProcessConnectionClosed(this); + WebProcess::singleton().networkProcessConnectionClosed(this); } -void NetworkProcessConnection::didReceiveInvalidMessage(CoreIPC::Connection*, CoreIPC::StringReference, CoreIPC::StringReference) +void NetworkProcessConnection::didReceiveInvalidMessage(IPC::Connection&, IPC::StringReference, IPC::StringReference) { } -void NetworkProcessConnection::didCacheResource(const ResourceRequest& request, const ShareableResource::Handle& handle) +#if ENABLE(SHAREABLE_RESOURCE) +void NetworkProcessConnection::didCacheResource(const ResourceRequest& request, const ShareableResource::Handle& handle, SessionID sessionID) { - CachedResource* resource = memoryCache()->resourceForRequest(request); + CachedResource* resource = MemoryCache::singleton().resourceForRequest(request, sessionID); if (!resource) return; RefPtr<SharedBuffer> buffer = handle.tryWrapInSharedBuffer(); if (!buffer) { - LOG_ERROR("Unabled to create SharedBuffer from ShareableResource handle for resource url %s", request.url().string().utf8().data()); + LOG_ERROR("Unable to create SharedBuffer from ShareableResource handle for resource url %s", request.url().string().utf8().data()); return; } - resource->tryReplaceEncodedData(buffer.release()); + resource->tryReplaceEncodedData(*buffer); } +#endif } // namespace WebKit - -#endif // ENABLE(NETWORK_PROCESS) diff --git a/Source/WebKit2/WebProcess/Network/NetworkProcessConnection.h b/Source/WebKit2/WebProcess/Network/NetworkProcessConnection.h index 0cdc73e28..cae80a3e2 100644 --- a/Source/WebKit2/WebProcess/Network/NetworkProcessConnection.h +++ b/Source/WebKit2/WebProcess/Network/NetworkProcessConnection.h @@ -31,9 +31,7 @@ #include <wtf/RefCounted.h> #include <wtf/text/WTFString.h> -#if ENABLE(NETWORK_PROCESS) - -namespace CoreIPC { +namespace IPC { class DataReference; } @@ -41,43 +39,45 @@ namespace WebCore { class ResourceError; class ResourceRequest; class ResourceResponse; +class SessionID; } namespace WebKit { typedef uint64_t ResourceLoadIdentifier; -class NetworkProcessConnection : public RefCounted<NetworkProcessConnection>, CoreIPC::Connection::Client { +class NetworkProcessConnection : public RefCounted<NetworkProcessConnection>, IPC::Connection::Client { public: - static PassRefPtr<NetworkProcessConnection> create(CoreIPC::Connection::Identifier connectionIdentifier) + static Ref<NetworkProcessConnection> create(IPC::Connection::Identifier connectionIdentifier) { - return adoptRef(new NetworkProcessConnection(connectionIdentifier)); + return adoptRef(*new NetworkProcessConnection(connectionIdentifier)); } ~NetworkProcessConnection(); - CoreIPC::Connection* connection() const { return m_connection.get(); } + IPC::Connection* connection() const { return m_connection.get(); } - void didReceiveNetworkProcessConnectionMessage(CoreIPC::Connection*, CoreIPC::MessageDecoder&); + void didReceiveNetworkProcessConnectionMessage(IPC::Connection&, IPC::MessageDecoder&); private: - NetworkProcessConnection(CoreIPC::Connection::Identifier); + NetworkProcessConnection(IPC::Connection::Identifier); - // CoreIPC::Connection::Client - virtual void didReceiveMessage(CoreIPC::Connection*, CoreIPC::MessageDecoder&) OVERRIDE; - virtual void didReceiveSyncMessage(CoreIPC::Connection*, CoreIPC::MessageDecoder&, OwnPtr<CoreIPC::MessageEncoder>&) OVERRIDE; - virtual void didClose(CoreIPC::Connection*) OVERRIDE; - virtual void didReceiveInvalidMessage(CoreIPC::Connection*, CoreIPC::StringReference messageReceiverName, CoreIPC::StringReference messageName) OVERRIDE; + // IPC::Connection::Client + virtual void didReceiveMessage(IPC::Connection&, IPC::MessageDecoder&) override; + virtual void didReceiveSyncMessage(IPC::Connection&, IPC::MessageDecoder&, std::unique_ptr<IPC::MessageEncoder>&) override; + virtual void didClose(IPC::Connection&) override; + virtual void didReceiveInvalidMessage(IPC::Connection&, IPC::StringReference messageReceiverName, IPC::StringReference messageName) override; + virtual IPC::ProcessType localProcessType() override { return IPC::ProcessType::Web; } + virtual IPC::ProcessType remoteProcessType() override { return IPC::ProcessType::Network; } +#if ENABLE(SHAREABLE_RESOURCE) // Message handlers. - void didCacheResource(const WebCore::ResourceRequest&, const ShareableResource::Handle&); + void didCacheResource(const WebCore::ResourceRequest&, const ShareableResource::Handle&, WebCore::SessionID); +#endif // The connection from the web process to the network process. - RefPtr<CoreIPC::Connection> m_connection; + RefPtr<IPC::Connection> m_connection; }; } // namespace WebKit -#endif // ENABLE(NETWORK_PROCESS) - - #endif // NetworkProcessConnection_h diff --git a/Source/WebKit2/WebProcess/Network/NetworkProcessConnection.messages.in b/Source/WebKit2/WebProcess/Network/NetworkProcessConnection.messages.in index 56cbf71c8..c2407f2ce 100644 --- a/Source/WebKit2/WebProcess/Network/NetworkProcessConnection.messages.in +++ b/Source/WebKit2/WebProcess/Network/NetworkProcessConnection.messages.in @@ -20,12 +20,10 @@ # 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. -#if ENABLE(NETWORK_PROCESS) - messages -> NetworkProcessConnection LegacyReceiver { - DidCacheResource(WebCore::ResourceRequest request, WebKit::ShareableResource::Handle resource) +#if ENABLE(SHAREABLE_RESOURCE) + DidCacheResource(WebCore::ResourceRequest request, WebKit::ShareableResource::Handle resource, WebCore::SessionID sessionID) +#endif } - -#endif // ENABLE(NETWORK_PROCESS) diff --git a/Source/WebKit2/WebProcess/Network/WebLoaderStrategy.cpp b/Source/WebKit2/WebProcess/Network/WebLoaderStrategy.cpp new file mode 100644 index 000000000..ad042e53e --- /dev/null +++ b/Source/WebKit2/WebProcess/Network/WebLoaderStrategy.cpp @@ -0,0 +1,369 @@ +/* + * Copyright (C) 2012, 2015 Apple Inc. All rights reserved. + * + * 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. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. 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 INC. 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 "WebLoaderStrategy.h" + +#include "HangDetectionDisabler.h" +#include "Logging.h" +#include "NetworkConnectionToWebProcessMessages.h" +#include "NetworkProcessConnection.h" +#include "NetworkResourceLoadParameters.h" +#include "SessionTracker.h" +#include "WebCoreArgumentCoders.h" +#include "WebErrors.h" +#include "WebFrame.h" +#include "WebFrameLoaderClient.h" +#include "WebFrameNetworkingContext.h" +#include "WebPage.h" +#include "WebPageProxyMessages.h" +#include "WebProcess.h" +#include "WebResourceLoader.h" +#include "WebURLSchemeHandlerProxy.h" +#include "WebURLSchemeHandlerTaskProxy.h" +#include <WebCore/ApplicationCacheHost.h> +#include <WebCore/CachedResource.h> +#include <WebCore/Document.h> +#include <WebCore/DocumentLoader.h> +#include <WebCore/Frame.h> +#include <WebCore/FrameLoader.h> +#include <WebCore/NetscapePlugInStreamLoader.h> +#include <WebCore/PlatformStrategies.h> +#include <WebCore/ReferrerPolicy.h> +#include <WebCore/ResourceLoader.h> +#include <WebCore/SessionID.h> +#include <WebCore/Settings.h> +#include <WebCore/SubresourceLoader.h> +#include <wtf/text/CString.h> + +using namespace WebCore; + +namespace WebKit { + +WebLoaderStrategy::WebLoaderStrategy() + : m_internallyFailedLoadTimer(RunLoop::main(), this, &WebLoaderStrategy::internallyFailedLoadTimerFired) +{ +} + +WebLoaderStrategy::~WebLoaderStrategy() +{ +} + +RefPtr<SubresourceLoader> WebLoaderStrategy::loadResource(Frame* frame, CachedResource* resource, const ResourceRequest& request, const ResourceLoaderOptions& options) +{ + RefPtr<SubresourceLoader> loader = SubresourceLoader::create(frame, resource, request, options); + if (loader) + scheduleLoad(loader.get(), resource, frame->document()->referrerPolicy() == ReferrerPolicyDefault); + return loader; +} + +RefPtr<NetscapePlugInStreamLoader> WebLoaderStrategy::schedulePluginStreamLoad(Frame* frame, NetscapePlugInStreamLoaderClient* client, const ResourceRequest& request) +{ + RefPtr<NetscapePlugInStreamLoader> loader = NetscapePlugInStreamLoader::create(frame, client, request); + if (loader) + scheduleLoad(loader.get(), 0, frame->document()->referrerPolicy() == ReferrerPolicyDefault); + return loader; +} + +static std::chrono::milliseconds maximumBufferingTime(CachedResource* resource) +{ +#if !ENABLE(NETWORK_CACHE) + return 0_ms; +#endif + + if (!resource) + return 0_ms; + + switch (resource->type()) { + case CachedResource::CSSStyleSheet: + case CachedResource::Script: +#if ENABLE(SVG_FONTS) + case CachedResource::SVGFontResource: +#endif + case CachedResource::FontResource: + return std::chrono::milliseconds::max(); + case CachedResource::ImageResource: + return 500_ms; + case CachedResource::MainResource: + case CachedResource::RawResource: + case CachedResource::SVGDocumentResource: +#if ENABLE(LINK_PREFETCH) + case CachedResource::LinkPrefetch: + case CachedResource::LinkSubresource: +#endif +#if ENABLE(VIDEO_TRACK) + case CachedResource::TextTrackResource: +#endif +#if ENABLE(XSLT) + case CachedResource::XSLStyleSheet: +#endif + return 0_ms; + } + + ASSERT_NOT_REACHED(); + return 0_ms; +} + +void WebLoaderStrategy::scheduleLoad(ResourceLoader* resourceLoader, CachedResource* resource, bool shouldClearReferrerOnHTTPSToHTTPRedirect) +{ + ASSERT(resourceLoader); + + ResourceLoadIdentifier identifier = resourceLoader->identifier(); + ASSERT(identifier); + + // 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 = toWebFrameLoaderClient(resourceLoader->frameLoader()->client()); + WebFrame* webFrame = webFrameLoaderClient ? webFrameLoaderClient->webFrame() : nullptr; + WebPage* webPage = webFrame ? webFrame->page() : nullptr; + +#if ENABLE(WEB_ARCHIVE) || ENABLE(MHTML) + // If the DocumentLoader schedules this as an archive resource load, + // then we should remember the ResourceLoader in our records but not schedule it in the NetworkProcess. + if (resourceLoader->documentLoader()->scheduleArchiveLoad(resourceLoader, resourceLoader->request())) { + LOG(NetworkScheduling, "(WebProcess) WebLoaderStrategy::scheduleLoad, url '%s' will be handled as an archive resource.", resourceLoader->url().string().utf8().data()); + m_webResourceLoaders.set(identifier, WebResourceLoader::create(resourceLoader)); + return; + } +#endif + + if (resourceLoader->documentLoader()->applicationCacheHost()->maybeLoadResource(resourceLoader, resourceLoader->request(), resourceLoader->request().url())) { + LOG(NetworkScheduling, "(WebProcess) WebLoaderStrategy::scheduleLoad, url '%s' will be loaded from application cache.", resourceLoader->url().string().utf8().data()); + m_webResourceLoaders.set(identifier, WebResourceLoader::create(resourceLoader)); + return; + } + + if (resourceLoader->request().url().protocolIsData()) { + LOG(NetworkScheduling, "(WebProcess) WebLoaderStrategy::scheduleLoad, url '%s' will be loaded as data.", resourceLoader->url().string().utf8().data()); + startLocalLoad(*resourceLoader); + return; + } + +#if USE(QUICK_LOOK) + if (resourceLoader->request().url().protocolIs(QLPreviewProtocol())) { + LOG(NetworkScheduling, "(WebProcess) WebLoaderStrategy::scheduleLoad, url '%s' will be handled as a QuickLook resource.", resourceLoader->url().string().utf8().data()); + startLocalLoad(*resourceLoader); + return; + } +#endif + +#if USE(SOUP) + // For apps that call g_resource_load in a web extension. + // https://blogs.gnome.org/alexl/2012/01/26/resources-in-glib/ + if (resourceLoader->request().url().protocolIs("resource")) { + LOG(NetworkScheduling, "(WebProcess) WebLoaderStrategy::scheduleLoad, url '%s' will be handled as a GResource.", resourceLoader->url().string().utf8().data()); + startLocalLoad(*resourceLoader); + return; + } +#endif + + if (webPage) { + if (auto* handler = webPage->urlSchemeHandlerForScheme(resourceLoader->request().url().protocol())) { + LOG(NetworkScheduling, "(WebProcess) WebLoaderStrategy::scheduleLoad, URL '%s' will be handled by a UIProcess URL scheme handler.", resourceLoader->url().string().utf8().data()); + //RELEASE_LOG_IF_ALLOWED(resourceLoader, "scheduleLoad: URL will be handled by a UIProcess URL scheme handler (frame = %p, resourceID = %" PRIu64 ")", resourceLoader->frame(), identifier); + + handler->startNewTask(*resourceLoader); + return; + } + } + + LOG(NetworkScheduling, "(WebProcess) WebLoaderStrategy::scheduleLoad, url '%s' will be scheduled with the NetworkProcess with priority %d", resourceLoader->url().string().utf8().data(), static_cast<int>(resourceLoader->request().priority())); + + ContentSniffingPolicy contentSniffingPolicy = resourceLoader->shouldSniffContent() ? SniffContent : DoNotSniffContent; + StoredCredentials allowStoredCredentials = resourceLoader->shouldUseCredentialStorage() ? AllowStoredCredentials : DoNotAllowStoredCredentials; + + NetworkResourceLoadParameters loadParameters; + loadParameters.identifier = identifier; + loadParameters.webPageID = webPage ? webPage->pageID() : 0; + loadParameters.webFrameID = webFrame ? webFrame->frameID() : 0; + loadParameters.sessionID = webPage ? webPage->sessionID() : SessionID::defaultSessionID(); + loadParameters.request = resourceLoader->request(); + loadParameters.contentSniffingPolicy = contentSniffingPolicy; + loadParameters.allowStoredCredentials = allowStoredCredentials; + // If there is no WebFrame then this resource cannot be authenticated with the client. + loadParameters.clientCredentialPolicy = (webFrame && webPage && resourceLoader->isAllowedToAskUserForCredentials()) ? AskClientForAllCredentials : DoNotAskClientForAnyCredentials; + loadParameters.shouldClearReferrerOnHTTPSToHTTPRedirect = shouldClearReferrerOnHTTPSToHTTPRedirect; + loadParameters.defersLoading = resourceLoader->defersLoading(); + loadParameters.needsCertificateInfo = resourceLoader->shouldIncludeCertificateInfo(); + loadParameters.maximumBufferingTime = maximumBufferingTime(resource); + + ASSERT((loadParameters.webPageID && loadParameters.webFrameID) || loadParameters.clientCredentialPolicy == DoNotAskClientForAnyCredentials); + + if (!WebProcess::singleton().networkConnection()->connection()->send(Messages::NetworkConnectionToWebProcess::ScheduleResourceLoad(loadParameters), 0)) { + // We probably failed to schedule this load with the NetworkProcess because it had crashed. + // This load will never succeed so we will schedule it to fail asynchronously. + scheduleInternallyFailedLoad(resourceLoader); + return; + } + + m_webResourceLoaders.set(identifier, WebResourceLoader::create(resourceLoader)); +} + +void WebLoaderStrategy::scheduleInternallyFailedLoad(WebCore::ResourceLoader* resourceLoader) +{ + m_internallyFailedResourceLoaders.add(resourceLoader); + m_internallyFailedLoadTimer.startOneShot(0); +} + +void WebLoaderStrategy::internallyFailedLoadTimerFired() +{ + Vector<RefPtr<ResourceLoader>> internallyFailedResourceLoaders; + copyToVector(m_internallyFailedResourceLoaders, internallyFailedResourceLoaders); + + for (size_t i = 0; i < internallyFailedResourceLoaders.size(); ++i) + internallyFailedResourceLoaders[i]->didFail(internalError(internallyFailedResourceLoaders[i]->url())); +} + +void WebLoaderStrategy::startLocalLoad(WebCore::ResourceLoader& resourceLoader) +{ + resourceLoader.start(); + m_webResourceLoaders.set(resourceLoader.identifier(), WebResourceLoader::create(&resourceLoader)); +} + +void WebLoaderStrategy::remove(ResourceLoader* resourceLoader) +{ + ASSERT(resourceLoader); + LOG(NetworkScheduling, "(WebProcess) WebLoaderStrategy::remove, url '%s'", resourceLoader->url().string().utf8().data()); + + if (m_internallyFailedResourceLoaders.contains(resourceLoader)) { + m_internallyFailedResourceLoaders.remove(resourceLoader); + return; + } + + if (auto task = m_urlSchemeHandlerTasks.take(resourceLoader->identifier())) { + task->stopLoading(); + return; + } + + ResourceLoadIdentifier identifier = resourceLoader->identifier(); + if (!identifier) { + LOG_ERROR("WebLoaderStrategy removing a ResourceLoader that has no identifier."); + return; + } + + RefPtr<WebResourceLoader> loader = m_webResourceLoaders.take(identifier); + // Loader may not be registered if we created it, but haven't scheduled yet (a bundle client can decide to cancel such request via willSendRequest). + if (!loader) + return; + + WebProcess::singleton().networkConnection()->connection()->send(Messages::NetworkConnectionToWebProcess::RemoveLoadIdentifier(identifier), 0); + + // It's possible that this WebResourceLoader might be just about to message back to the NetworkProcess (e.g. ContinueWillSendRequest) + // but there's no point in doing so anymore. + loader->detachFromCoreLoader(); +} + +void WebLoaderStrategy::setDefersLoading(ResourceLoader* resourceLoader, bool defers) +{ + ResourceLoadIdentifier identifier = resourceLoader->identifier(); + WebProcess::singleton().networkConnection()->connection()->send(Messages::NetworkConnectionToWebProcess::SetDefersLoading(identifier, defers), 0); +} + +void WebLoaderStrategy::crossOriginRedirectReceived(ResourceLoader*, const URL&) +{ + // We handle cross origin redirects entirely within the NetworkProcess. + // We override this call in the WebProcess to make it a no-op. +} + +void WebLoaderStrategy::servePendingRequests(ResourceLoadPriority) +{ + // This overrides the base class version. + // We don't need to do anything as this is handled by the network process. +} + +void WebLoaderStrategy::suspendPendingRequests() +{ + // Network process does keep requests in pending state. +} + +void WebLoaderStrategy::resumePendingRequests() +{ + // Network process does keep requests in pending state. +} + +void WebLoaderStrategy::networkProcessCrashed() +{ + HashMap<unsigned long, RefPtr<WebResourceLoader>>::iterator end = m_webResourceLoaders.end(); + for (HashMap<unsigned long, RefPtr<WebResourceLoader>>::iterator i = m_webResourceLoaders.begin(); i != end; ++i) + scheduleInternallyFailedLoad(i->value.get()->resourceLoader()); + + m_webResourceLoaders.clear(); +} + +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()); + } +} + +void WebLoaderStrategy::createPingHandle(NetworkingContext* networkingContext, ResourceRequest& request, bool shouldUseCredentialStorage) +{ + // It's possible that call to createPingHandle might be made during initial empty Document creation before a NetworkingContext exists. + // It is not clear that we should send ping loads during that process anyways. + if (!networkingContext) + return; + + WebFrameNetworkingContext* webContext = static_cast<WebFrameNetworkingContext*>(networkingContext); + WebFrameLoaderClient* webFrameLoaderClient = webContext->webFrameLoaderClient(); + WebFrame* webFrame = webFrameLoaderClient ? webFrameLoaderClient->webFrame() : nullptr; + WebPage* webPage = webFrame ? webFrame->page() : nullptr; + + NetworkResourceLoadParameters loadParameters; + loadParameters.request = request; + loadParameters.sessionID = webPage ? webPage->sessionID() : SessionID::defaultSessionID(); + loadParameters.allowStoredCredentials = shouldUseCredentialStorage ? AllowStoredCredentials : DoNotAllowStoredCredentials; + loadParameters.shouldClearReferrerOnHTTPSToHTTPRedirect = networkingContext->shouldClearReferrerOnHTTPSToHTTPRedirect(); + + WebProcess::singleton().networkConnection()->connection()->send(Messages::NetworkConnectionToWebProcess::LoadPing(loadParameters), 0); +} + + +} // namespace WebKit diff --git a/Source/WebKit2/WebProcess/Network/WebLoaderStrategy.h b/Source/WebKit2/WebProcess/Network/WebLoaderStrategy.h new file mode 100644 index 000000000..471ad4bbe --- /dev/null +++ b/Source/WebKit2/WebProcess/Network/WebLoaderStrategy.h @@ -0,0 +1,81 @@ +/* + * Copyright (C) 2012, 2015 Apple Inc. All rights reserved. + * + * 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. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. 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 INC. 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. + */ + +#ifndef WebLoaderStrategy_h +#define WebLoaderStrategy_h + +#include "WebResourceLoader.h" +#include <WebCore/LoaderStrategy.h> +#include <WebCore/ResourceLoader.h> +#include <wtf/HashSet.h> +#include <wtf/RunLoop.h> + +namespace WebKit { + +class NetworkProcessConnection; +class WebURLSchemeHandlerTaskProxy; +typedef uint64_t ResourceLoadIdentifier; + +class WebLoaderStrategy : public WebCore::LoaderStrategy { + WTF_MAKE_NONCOPYABLE(WebLoaderStrategy); WTF_MAKE_FAST_ALLOCATED; +public: + WebLoaderStrategy(); + ~WebLoaderStrategy() override; + + RefPtr<WebCore::SubresourceLoader> loadResource(WebCore::Frame*, WebCore::CachedResource*, const WebCore::ResourceRequest&, const WebCore::ResourceLoaderOptions&) override; + void loadResourceSynchronously(WebCore::NetworkingContext*, unsigned long resourceLoadIdentifier, const WebCore::ResourceRequest&, WebCore::StoredCredentials, WebCore::ClientCredentialPolicy, WebCore::ResourceError&, WebCore::ResourceResponse&, Vector<char>& data) override; + + void remove(WebCore::ResourceLoader*) override; + void setDefersLoading(WebCore::ResourceLoader*, bool) override; + void crossOriginRedirectReceived(WebCore::ResourceLoader*, const WebCore::URL& redirectURL) override; + + void servePendingRequests(WebCore::ResourceLoadPriority minimumPriority) override; + + void suspendPendingRequests() override; + void resumePendingRequests() override; + + void createPingHandle(WebCore::NetworkingContext*, WebCore::ResourceRequest&, bool shouldUseCredentialStorage) override; + + WebResourceLoader* webResourceLoaderForIdentifier(ResourceLoadIdentifier identifier) const { return m_webResourceLoaders.get(identifier); } + RefPtr<WebCore::NetscapePlugInStreamLoader> schedulePluginStreamLoad(WebCore::Frame*, WebCore::NetscapePlugInStreamLoaderClient*, const WebCore::ResourceRequest&); + + void networkProcessCrashed(); + +private: + void scheduleLoad(WebCore::ResourceLoader*, WebCore::CachedResource*, bool shouldClearReferrerOnHTTPSToHTTPRedirect); + void scheduleInternallyFailedLoad(WebCore::ResourceLoader*); + void internallyFailedLoadTimerFired(); + void startLocalLoad(WebCore::ResourceLoader&); + + HashSet<RefPtr<WebCore::ResourceLoader>> m_internallyFailedResourceLoaders; + RunLoop::Timer<WebLoaderStrategy> m_internallyFailedLoadTimer; + + HashMap<unsigned long, RefPtr<WebResourceLoader>> m_webResourceLoaders; + HashMap<unsigned long, std::unique_ptr<WebURLSchemeHandlerTaskProxy>> m_urlSchemeHandlerTasks; +}; + +} // namespace WebKit + +#endif diff --git a/Source/WebKit2/WebProcess/Network/WebResourceLoadScheduler.cpp b/Source/WebKit2/WebProcess/Network/WebResourceLoadScheduler.cpp deleted file mode 100644 index 3f7b7ceeb..000000000 --- a/Source/WebKit2/WebProcess/Network/WebResourceLoadScheduler.cpp +++ /dev/null @@ -1,231 +0,0 @@ -/* - * Copyright (C) 2012 Apple Inc. All rights reserved. - * - * 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. - * - * THIS SOFTWARE IS PROVIDED BY APPLE INC. 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 INC. 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 "WebResourceLoadScheduler.h" - -#include "Logging.h" -#include "NetworkConnectionToWebProcessMessages.h" -#include "NetworkProcessConnection.h" -#include "NetworkResourceLoadParameters.h" -#include "WebCoreArgumentCoders.h" -#include "WebErrors.h" -#include "WebFrame.h" -#include "WebFrameLoaderClient.h" -#include "WebPage.h" -#include "WebProcess.h" -#include "WebResourceLoader.h" -#include <WebCore/CachedResource.h> -#include <WebCore/Document.h> -#include <WebCore/DocumentLoader.h> -#include <WebCore/Frame.h> -#include <WebCore/FrameLoader.h> -#include <WebCore/NetscapePlugInStreamLoader.h> -#include <WebCore/ReferrerPolicy.h> -#include <WebCore/ResourceBuffer.h> -#include <WebCore/ResourceLoader.h> -#include <WebCore/Settings.h> -#include <WebCore/SubresourceLoader.h> -#include <wtf/text/CString.h> - -#if ENABLE(NETWORK_PROCESS) - -using namespace WebCore; - -namespace WebKit { - -WebResourceLoadScheduler::WebResourceLoadScheduler() - : m_internallyFailedLoadTimer(RunLoop::main(), this, &WebResourceLoadScheduler::internallyFailedLoadTimerFired) - , m_suspendPendingRequestsCount(0) -{ -} - -WebResourceLoadScheduler::~WebResourceLoadScheduler() -{ -} - -PassRefPtr<SubresourceLoader> WebResourceLoadScheduler::scheduleSubresourceLoad(Frame* frame, CachedResource* resource, const ResourceRequest& request, ResourceLoadPriority priority, const ResourceLoaderOptions& options) -{ - RefPtr<SubresourceLoader> loader = SubresourceLoader::create(frame, resource, request, options); - if (loader) - scheduleLoad(loader.get(), resource, priority, frame->document()->referrerPolicy() == ReferrerPolicyDefault); - return loader.release(); -} - -PassRefPtr<NetscapePlugInStreamLoader> WebResourceLoadScheduler::schedulePluginStreamLoad(Frame* frame, NetscapePlugInStreamLoaderClient* client, const ResourceRequest& request) -{ - RefPtr<NetscapePlugInStreamLoader> loader = NetscapePlugInStreamLoader::create(frame, client, request); - if (loader) - scheduleLoad(loader.get(), 0, ResourceLoadPriorityLow, frame->document()->referrerPolicy() == ReferrerPolicyDefault); - return loader.release(); -} - -void WebResourceLoadScheduler::scheduleLoad(ResourceLoader* resourceLoader, CachedResource* resource, ResourceLoadPriority priority, bool shouldClearReferrerOnHTTPSToHTTPRedirect) -{ - ASSERT(resourceLoader); - ASSERT(priority != ResourceLoadPriorityUnresolved); - priority = ResourceLoadPriorityHighest; - - ResourceLoadIdentifier identifier = resourceLoader->identifier(); - ASSERT(identifier); - - // If the DocumentLoader schedules this as an archive resource load, - // then we should remember the ResourceLoader in our records but not schedule it in the NetworkProcess. - if (resourceLoader->documentLoader()->scheduleArchiveLoad(resourceLoader, resourceLoader->request())) { - LOG(NetworkScheduling, "(WebProcess) WebResourceLoadScheduler::scheduleLoad, url '%s' will be handled as an archive resource.", resourceLoader->url().string().utf8().data()); - m_webResourceLoaders.set(identifier, WebResourceLoader::create(resourceLoader)); - return; - } - - LOG(NetworkScheduling, "(WebProcess) WebResourceLoadScheduler::scheduleLoad, url '%s' will be scheduled with the NetworkProcess with priority %i", resourceLoader->url().string().utf8().data(), priority); - - ContentSniffingPolicy contentSniffingPolicy = resourceLoader->shouldSniffContent() ? SniffContent : DoNotSniffContent; - StoredCredentials allowStoredCredentials = resourceLoader->shouldUseCredentialStorage() ? AllowStoredCredentials : DoNotAllowStoredCredentials; - bool privateBrowsingEnabled = resourceLoader->frameLoader()->frame()->settings()->privateBrowsingEnabled(); - - // 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 = toWebFrameLoaderClient(resourceLoader->frameLoader()->client()); - WebFrame* webFrame = webFrameLoaderClient ? webFrameLoaderClient->webFrame() : 0; - WebPage* webPage = webFrame ? webFrame->page() : 0; - - NetworkResourceLoadParameters loadParameters; - loadParameters.identifier = identifier; - loadParameters.webPageID = webPage ? webPage->pageID() : 0; - loadParameters.webFrameID = webFrame ? webFrame->frameID() : 0; - loadParameters.request = resourceLoader->request(); - loadParameters.priority = priority; - loadParameters.contentSniffingPolicy = contentSniffingPolicy; - loadParameters.allowStoredCredentials = allowStoredCredentials; - // If there is no WebFrame then this resource cannot be authenticated with the client. - loadParameters.clientCredentialPolicy = (webFrame && webPage) ? resourceLoader->clientCredentialPolicy() : DoNotAskClientForAnyCredentials; - loadParameters.inPrivateBrowsingMode = privateBrowsingEnabled; - loadParameters.shouldClearReferrerOnHTTPSToHTTPRedirect = shouldClearReferrerOnHTTPSToHTTPRedirect; - loadParameters.isMainResource = resource && resource->type() == CachedResource::MainResource; - - ASSERT((loadParameters.webPageID && loadParameters.webFrameID) || loadParameters.clientCredentialPolicy == DoNotAskClientForAnyCredentials); - - if (!WebProcess::shared().networkConnection()->connection()->send(Messages::NetworkConnectionToWebProcess::ScheduleResourceLoad(loadParameters), 0)) { - // We probably failed to schedule this load with the NetworkProcess because it had crashed. - // This load will never succeed so we will schedule it to fail asynchronously. - scheduleInternallyFailedLoad(resourceLoader); - return; - } - - m_webResourceLoaders.set(identifier, WebResourceLoader::create(resourceLoader)); - - notifyDidScheduleResourceRequest(resourceLoader); -} - -void WebResourceLoadScheduler::scheduleInternallyFailedLoad(WebCore::ResourceLoader* resourceLoader) -{ - m_internallyFailedResourceLoaders.add(resourceLoader); - m_internallyFailedLoadTimer.startOneShot(0); -} - -void WebResourceLoadScheduler::internallyFailedLoadTimerFired() -{ - Vector<RefPtr<ResourceLoader> > internallyFailedResourceLoaders; - copyToVector(m_internallyFailedResourceLoaders, internallyFailedResourceLoaders); - - for (size_t i = 0; i < internallyFailedResourceLoaders.size(); ++i) - internallyFailedResourceLoaders[i]->didFail(internalError(internallyFailedResourceLoaders[i]->url())); -} - -void WebResourceLoadScheduler::remove(ResourceLoader* resourceLoader) -{ - ASSERT(resourceLoader); - LOG(NetworkScheduling, "(WebProcess) WebResourceLoadScheduler::remove, url '%s'", resourceLoader->url().string().utf8().data()); - - if (m_internallyFailedResourceLoaders.contains(resourceLoader)) { - m_internallyFailedResourceLoaders.remove(resourceLoader); - return; - } - - ResourceLoadIdentifier identifier = resourceLoader->identifier(); - if (!identifier) { - LOG_ERROR("WebResourceLoadScheduler removing a ResourceLoader that has no identifier."); - return; - } - - RefPtr<WebResourceLoader> loader = m_webResourceLoaders.take(identifier); - // Loader may not be registered if we created it, but haven't scheduled yet (a bundle client can decide to cancel such request via willSendRequest). - if (!loader) - return; - - WebProcess::shared().networkConnection()->connection()->send(Messages::NetworkConnectionToWebProcess::RemoveLoadIdentifier(identifier), 0); - - // It's possible that this WebResourceLoader might be just about to message back to the NetworkProcess (e.g. ContinueWillSendRequest) - // but there's no point in doing so anymore. - loader->detachFromCoreLoader(); -} - -void WebResourceLoadScheduler::crossOriginRedirectReceived(ResourceLoader*, const KURL&) -{ - // We handle cross origin redirects entirely within the NetworkProcess. - // We override this call in the WebProcess to make it a no-op. -} - -void WebResourceLoadScheduler::servePendingRequests(ResourceLoadPriority minimumPriority) -{ - LOG(NetworkScheduling, "(WebProcess) WebResourceLoadScheduler::servePendingRequests"); - - // The NetworkProcess scheduler is good at making sure loads are serviced until there are no more pending requests. - // If this WebProcess isn't expecting requests to be served then we can ignore messaging the NetworkProcess right now. - if (m_suspendPendingRequestsCount) - return; - - WebProcess::shared().networkConnection()->connection()->send(Messages::NetworkConnectionToWebProcess::ServePendingRequests(minimumPriority), 0); -} - -void WebResourceLoadScheduler::suspendPendingRequests() -{ - ++m_suspendPendingRequestsCount; -} - -void WebResourceLoadScheduler::resumePendingRequests() -{ - ASSERT(m_suspendPendingRequestsCount); - --m_suspendPendingRequestsCount; -} - -void WebResourceLoadScheduler::setSerialLoadingEnabled(bool enabled) -{ - WebProcess::shared().networkConnection()->connection()->sendSync(Messages::NetworkConnectionToWebProcess::SetSerialLoadingEnabled(enabled), Messages::NetworkConnectionToWebProcess::SetSerialLoadingEnabled::Reply(), 0); -} - -void WebResourceLoadScheduler::networkProcessCrashed() -{ - HashMap<unsigned long, RefPtr<WebResourceLoader>>::iterator end = m_webResourceLoaders.end(); - for (HashMap<unsigned long, RefPtr<WebResourceLoader>>::iterator i = m_webResourceLoaders.begin(); i != end; ++i) - scheduleInternallyFailedLoad(i->value.get()->resourceLoader()); - - m_webResourceLoaders.clear(); -} - -} // namespace WebKit - -#endif // ENABLE(NETWORK_PROCESS) diff --git a/Source/WebKit2/WebProcess/Network/WebResourceLoadScheduler.h b/Source/WebKit2/WebProcess/Network/WebResourceLoadScheduler.h deleted file mode 100644 index f1876f655..000000000 --- a/Source/WebKit2/WebProcess/Network/WebResourceLoadScheduler.h +++ /dev/null @@ -1,83 +0,0 @@ -/* - * Copyright (C) 2012 Apple Inc. All rights reserved. - * - * 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. - * - * THIS SOFTWARE IS PROVIDED BY APPLE INC. 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 INC. 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. - */ - -#ifndef WebResourceLoadScheduler_h -#define WebResourceLoadScheduler_h - -#include "WebResourceLoader.h" -#include <WebCore/ResourceLoadPriority.h> -#include <WebCore/ResourceLoadScheduler.h> -#include <WebCore/ResourceLoader.h> -#include <WebCore/RunLoop.h> - -#if ENABLE(NETWORK_PROCESS) - -namespace WebKit { - -class NetworkProcessConnection; -typedef uint64_t ResourceLoadIdentifier; - -class WebResourceLoadScheduler : public WebCore::ResourceLoadScheduler { - WTF_MAKE_NONCOPYABLE(WebResourceLoadScheduler); WTF_MAKE_FAST_ALLOCATED; -public: - WebResourceLoadScheduler(); - virtual ~WebResourceLoadScheduler(); - - virtual PassRefPtr<WebCore::SubresourceLoader> scheduleSubresourceLoad(WebCore::Frame*, WebCore::CachedResource*, const WebCore::ResourceRequest&, WebCore::ResourceLoadPriority, const WebCore::ResourceLoaderOptions&) OVERRIDE; - virtual PassRefPtr<WebCore::NetscapePlugInStreamLoader> schedulePluginStreamLoad(WebCore::Frame*, WebCore::NetscapePlugInStreamLoaderClient*, const WebCore::ResourceRequest&) OVERRIDE; - - virtual void remove(WebCore::ResourceLoader*) OVERRIDE; - virtual void crossOriginRedirectReceived(WebCore::ResourceLoader*, const WebCore::KURL& redirectURL) OVERRIDE; - - virtual void servePendingRequests(WebCore::ResourceLoadPriority minimumPriority = WebCore::ResourceLoadPriorityVeryLow) OVERRIDE; - - virtual void suspendPendingRequests() OVERRIDE; - virtual void resumePendingRequests() OVERRIDE; - - virtual void setSerialLoadingEnabled(bool) OVERRIDE; - - WebResourceLoader* webResourceLoaderForIdentifier(ResourceLoadIdentifier identifier) const { return m_webResourceLoaders.get(identifier); } - - void networkProcessCrashed(); - -private: - void scheduleLoad(WebCore::ResourceLoader*, WebCore::CachedResource*, WebCore::ResourceLoadPriority, bool shouldClearReferrerOnHTTPSToHTTPRedirect); - void scheduleInternallyFailedLoad(WebCore::ResourceLoader*); - void internallyFailedLoadTimerFired(); - - HashSet<RefPtr<WebCore::ResourceLoader> > m_internallyFailedResourceLoaders; - WebCore::RunLoop::Timer<WebResourceLoadScheduler> m_internallyFailedLoadTimer; - - HashMap<unsigned long, RefPtr<WebResourceLoader> > m_webResourceLoaders; - - unsigned m_suspendPendingRequestsCount; - -}; - -} // namespace WebKit - -#endif // ENABLE(NETWORK_PROCESS) - -#endif // WebResourceLoadScheduler_h diff --git a/Source/WebKit2/WebProcess/Network/WebResourceLoader.cpp b/Source/WebKit2/WebProcess/Network/WebResourceLoader.cpp index 5357bbcf4..2a0f559ac 100644 --- a/Source/WebKit2/WebProcess/Network/WebResourceLoader.cpp +++ b/Source/WebKit2/WebProcess/Network/WebResourceLoader.cpp @@ -26,28 +26,27 @@ #include "config.h" #include "WebResourceLoader.h" -#if ENABLE(NETWORK_PROCESS) - #include "DataReference.h" #include "Logging.h" #include "NetworkProcessConnection.h" #include "NetworkResourceLoaderMessages.h" -#include "PlatformCertificateInfo.h" #include "WebCoreArgumentCoders.h" #include "WebErrors.h" #include "WebProcess.h" +#include <WebCore/ApplicationCacheHost.h> +#include <WebCore/CertificateInfo.h> #include <WebCore/DocumentLoader.h> -#include <WebCore/ResourceBuffer.h> #include <WebCore/ResourceError.h> #include <WebCore/ResourceLoader.h> +#include <WebCore/SubresourceLoader.h> using namespace WebCore; namespace WebKit { -PassRefPtr<WebResourceLoader> WebResourceLoader::create(PassRefPtr<ResourceLoader> coreLoader) +Ref<WebResourceLoader> WebResourceLoader::create(PassRefPtr<ResourceLoader> coreLoader) { - return adoptRef(new WebResourceLoader(coreLoader)); + return adoptRef(*new WebResourceLoader(coreLoader)); } WebResourceLoader::WebResourceLoader(PassRefPtr<WebCore::ResourceLoader> coreLoader) @@ -59,9 +58,9 @@ WebResourceLoader::~WebResourceLoader() { } -CoreIPC::Connection* WebResourceLoader::messageSenderConnection() +IPC::Connection* WebResourceLoader::messageSenderConnection() { - return WebProcess::shared().networkConnection()->connection(); + return WebProcess::singleton().networkConnection()->connection(); } uint64_t WebResourceLoader::messageSenderDestinationID() @@ -69,29 +68,27 @@ uint64_t WebResourceLoader::messageSenderDestinationID() return m_coreLoader->identifier(); } -void WebResourceLoader::cancelResourceLoader() -{ - m_coreLoader->cancel(); -} - void WebResourceLoader::detachFromCoreLoader() { - m_coreLoader = 0; + m_coreLoader = nullptr; } void WebResourceLoader::willSendRequest(const ResourceRequest& proposedRequest, const ResourceResponse& redirectResponse) { LOG(Network, "(WebProcess) WebResourceLoader::willSendRequest to '%s'", proposedRequest.url().string().utf8().data()); - RefPtr<WebResourceLoader> protector(this); - + RefPtr<WebResourceLoader> protect(this); + ResourceRequest newRequest = proposedRequest; - m_coreLoader->willSendRequest(newRequest, redirectResponse); - - if (!m_coreLoader) + if (m_coreLoader->documentLoader()->applicationCacheHost()->maybeLoadFallbackForRedirect(m_coreLoader.get(), newRequest, redirectResponse)) return; - - send(Messages::NetworkResourceLoader::ContinueWillSendRequest(newRequest)); + // FIXME: Do we need to update NetworkResourceLoader clientCredentialPolicy in case loader policy is DoNotAskClientForCrossOriginCredentials? + m_coreLoader->willSendRequest(WTFMove(newRequest), redirectResponse, [protect](ResourceRequest&& request) { + if (!protect->m_coreLoader) + return; + + protect->send(Messages::NetworkResourceLoader::ContinueWillSendRequest(request)); + }); } void WebResourceLoader::didSendData(uint64_t bytesSent, uint64_t totalBytesToBeSent) @@ -99,15 +96,28 @@ void WebResourceLoader::didSendData(uint64_t bytesSent, uint64_t totalBytesToBeS m_coreLoader->didSendData(bytesSent, totalBytesToBeSent); } -void WebResourceLoader::didReceiveResponseWithCertificateInfo(const ResourceResponse& response, const PlatformCertificateInfo& certificateInfo, bool needsContinueDidReceiveResponseMessage) +void WebResourceLoader::didReceiveResponse(const ResourceResponse& response, bool needsContinueDidReceiveResponseMessage) { - LOG(Network, "(WebProcess) WebResourceLoader::didReceiveResponseWithCertificateInfo for '%s'. Status %d.", m_coreLoader->url().string().utf8().data(), response.httpStatusCode()); + LOG(Network, "(WebProcess) WebResourceLoader::didReceiveResponse for '%s'. Status %d.", m_coreLoader->url().string().utf8().data(), response.httpStatusCode()); - RefPtr<WebResourceLoader> protector(this); + Ref<WebResourceLoader> protect(*this); - ResourceResponse responseCopy(response); - responseCopy.setCertificateChain(certificateInfo.certificateChain()); - m_coreLoader->didReceiveResponse(responseCopy); + if (m_coreLoader->documentLoader()->applicationCacheHost()->maybeLoadFallbackForResponse(m_coreLoader.get(), response)) + return; + + bool shoudCallCoreLoaderDidReceiveResponse = true; +#if USE(QUICK_LOOK) + // Refrain from calling didReceiveResponse if QuickLook will convert this response, since the MIME type of the + // converted resource isn't yet known. WebResourceLoaderQuickLookDelegate will later call didReceiveResponse upon + // receiving the converted data. + bool isMainLoad = m_coreLoader->documentLoader()->mainResourceLoader() == m_coreLoader; + if (isMainLoad && QuickLookHandle::shouldCreateForMIMEType(response.mimeType())) { + m_coreLoader->documentLoader()->setQuickLookHandle(QuickLookHandle::create(*m_coreLoader, response)); + shoudCallCoreLoaderDidReceiveResponse = false; + } +#endif + if (shoudCallCoreLoaderDidReceiveResponse) + m_coreLoader->didReceiveResponse(response); // If m_coreLoader becomes null as a result of the didReceiveResponse callback, we can't use the send function(). if (!m_coreLoader) @@ -117,15 +127,29 @@ void WebResourceLoader::didReceiveResponseWithCertificateInfo(const ResourceResp send(Messages::NetworkResourceLoader::ContinueDidReceiveResponse()); } -void WebResourceLoader::didReceiveData(const CoreIPC::DataReference& data, int64_t encodedDataLength) +void WebResourceLoader::didReceiveData(const IPC::DataReference& data, int64_t encodedDataLength) { LOG(Network, "(WebProcess) WebResourceLoader::didReceiveData of size %i for '%s'", (int)data.size(), m_coreLoader->url().string().utf8().data()); + +#if USE(QUICK_LOOK) + if (QuickLookHandle* quickLookHandle = m_coreLoader->documentLoader()->quickLookHandle()) { + if (quickLookHandle->didReceiveData(adoptCF(CFDataCreate(kCFAllocatorDefault, data.data(), data.size())).get())) + return; + } +#endif m_coreLoader->didReceiveData(reinterpret_cast<const char*>(data.data()), data.size(), encodedDataLength, DataPayloadBytes); } void WebResourceLoader::didFinishResourceLoad(double finishTime) { LOG(Network, "(WebProcess) WebResourceLoader::didFinishResourceLoad for '%s'", m_coreLoader->url().string().utf8().data()); + +#if USE(QUICK_LOOK) + if (QuickLookHandle* quickLookHandle = m_coreLoader->documentLoader()->quickLookHandle()) { + if (quickLookHandle->didFinishLoading()) + return; + } +#endif m_coreLoader->didFinishLoading(finishTime); } @@ -133,44 +157,60 @@ void WebResourceLoader::didFailResourceLoad(const ResourceError& error) { LOG(Network, "(WebProcess) WebResourceLoader::didFailResourceLoad for '%s'", m_coreLoader->url().string().utf8().data()); +#if USE(QUICK_LOOK) + if (QuickLookHandle* quickLookHandle = m_coreLoader->documentLoader()->quickLookHandle()) + quickLookHandle->didFail(); +#endif + if (m_coreLoader->documentLoader()->applicationCacheHost()->maybeLoadFallbackForError(m_coreLoader.get(), error)) + return; m_coreLoader->didFail(error); } +#if ENABLE(SHAREABLE_RESOURCE) void WebResourceLoader::didReceiveResource(const ShareableResource::Handle& handle, double finishTime) { LOG(Network, "(WebProcess) WebResourceLoader::didReceiveResource for '%s'", m_coreLoader->url().string().utf8().data()); RefPtr<SharedBuffer> buffer = handle.tryWrapInSharedBuffer(); + +#if USE(QUICK_LOOK) + if (QuickLookHandle* quickLookHandle = m_coreLoader->documentLoader()->quickLookHandle()) { + if (buffer) { + if (quickLookHandle->didReceiveData(buffer->existingCFData())) { + quickLookHandle->didFinishLoading(); + return; + } + } else + quickLookHandle->didFail(); + } +#endif + if (!buffer) { LOG_ERROR("Unable to create buffer from ShareableResource sent from the network process."); m_coreLoader->didFail(internalError(m_coreLoader->request().url())); return; } - RefPtr<WebResourceLoader> protector(this); + Ref<WebResourceLoader> protect(*this); // Only send data to the didReceiveData callback if it exists. - if (buffer->size()) - m_coreLoader->didReceiveBuffer(buffer.get(), buffer->size(), DataPayloadWholeResource); + if (unsigned bufferSize = buffer->size()) + m_coreLoader->didReceiveBuffer(buffer.release(), bufferSize, DataPayloadWholeResource); if (!m_coreLoader) return; m_coreLoader->didFinishLoading(finishTime); } +#endif +#if USE(PROTECTION_SPACE_AUTH_CALLBACK) void WebResourceLoader::canAuthenticateAgainstProtectionSpace(const ProtectionSpace& protectionSpace) { - RefPtr<WebResourceLoader> protector(this); - - bool result = m_coreLoader->canAuthenticateAgainstProtectionSpace(protectionSpace); - - if (!m_coreLoader) - return; + bool result = m_coreLoader ? m_coreLoader->canAuthenticateAgainstProtectionSpace(protectionSpace) : false; send(Messages::NetworkResourceLoader::ContinueCanAuthenticateAgainstProtectionSpace(result)); } +#endif } // namespace WebKit - -#endif // ENABLE(NETWORK_PROCESS) diff --git a/Source/WebKit2/WebProcess/Network/WebResourceLoader.h b/Source/WebKit2/WebProcess/Network/WebResourceLoader.h index b37e9b0f0..3a62009f8 100644 --- a/Source/WebKit2/WebProcess/Network/WebResourceLoader.h +++ b/Source/WebKit2/WebProcess/Network/WebResourceLoader.h @@ -26,8 +26,6 @@ #ifndef WebResourceLoader_h #define WebResourceLoader_h -#if ENABLE(NETWORK_PROCESS) - #include "Connection.h" #include "MessageSender.h" #include "ShareableResource.h" @@ -35,13 +33,17 @@ #include <wtf/RefCounted.h> #include <wtf/RefPtr.h> -namespace CoreIPC { +#if USE(QUICK_LOOK) +#include <WebCore/QuickLook.h> +#endif + +namespace IPC { class DataReference; } namespace WebCore { +class CertificateInfo; class ProtectionSpace; -class ResourceBuffer; class ResourceError; class ResourceLoader; class ResourceRequest; @@ -50,16 +52,15 @@ class ResourceResponse; namespace WebKit { -class PlatformCertificateInfo; typedef uint64_t ResourceLoadIdentifier; -class WebResourceLoader : public RefCounted<WebResourceLoader>, public CoreIPC::MessageSender { +class WebResourceLoader : public RefCounted<WebResourceLoader>, public IPC::MessageSender { public: - static PassRefPtr<WebResourceLoader> create(PassRefPtr<WebCore::ResourceLoader>); + static Ref<WebResourceLoader> create(PassRefPtr<WebCore::ResourceLoader>); ~WebResourceLoader(); - void didReceiveWebResourceLoaderMessage(CoreIPC::Connection*, CoreIPC::MessageDecoder&); + void didReceiveWebResourceLoaderMessage(IPC::Connection&, IPC::MessageDecoder&); WebCore::ResourceLoader* resourceLoader() const { return m_coreLoader.get(); } @@ -68,27 +69,27 @@ public: private: WebResourceLoader(PassRefPtr<WebCore::ResourceLoader>); - // CoreIPC::MessageSender - virtual CoreIPC::Connection* messageSenderConnection() OVERRIDE; - virtual uint64_t messageSenderDestinationID() OVERRIDE; - - void cancelResourceLoader(); + // IPC::MessageSender + virtual IPC::Connection* messageSenderConnection() override; + virtual uint64_t messageSenderDestinationID() override; void willSendRequest(const WebCore::ResourceRequest&, const WebCore::ResourceResponse& redirectResponse); void didSendData(uint64_t bytesSent, uint64_t totalBytesToBeSent); - void didReceiveResponseWithCertificateInfo(const WebCore::ResourceResponse&, const PlatformCertificateInfo&, bool needsContinueDidReceiveResponseMessage); - void didReceiveData(const CoreIPC::DataReference&, int64_t encodedDataLength); + void didReceiveResponse(const WebCore::ResourceResponse&, bool needsContinueDidReceiveResponseMessage); + void didReceiveData(const IPC::DataReference&, int64_t encodedDataLength); void didFinishResourceLoad(double finishTime); void didFailResourceLoad(const WebCore::ResourceError&); +#if ENABLE(SHAREABLE_RESOURCE) void didReceiveResource(const ShareableResource::Handle&, double finishTime); +#endif +#if USE(PROTECTION_SPACE_AUTH_CALLBACK) void canAuthenticateAgainstProtectionSpace(const WebCore::ProtectionSpace&); +#endif RefPtr<WebCore::ResourceLoader> m_coreLoader; }; } // namespace WebKit -#endif // ENABLE(NETWORK_PROCESS) - #endif // WebResourceLoader_h diff --git a/Source/WebKit2/WebProcess/Network/WebResourceLoader.messages.in b/Source/WebKit2/WebProcess/Network/WebResourceLoader.messages.in index 2ac264909..67fd0d9f2 100644 --- a/Source/WebKit2/WebProcess/Network/WebResourceLoader.messages.in +++ b/Source/WebKit2/WebProcess/Network/WebResourceLoader.messages.in @@ -21,19 +21,19 @@ # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. messages -> WebResourceLoader LegacyReceiver { - - CancelResourceLoader() - - // FIXME (NetworkProcess): We'll need much more granularity for response messages. WillSendRequest(WebCore::ResourceRequest request, WebCore::ResourceResponse redirectResponse) DidSendData(uint64_t bytesSent, uint64_t totalBytesToBeSent) - DidReceiveResponseWithCertificateInfo(WebCore::ResourceResponse response, WebKit::PlatformCertificateInfo certificateInfo, bool needsContinueDidReceiveResponseMessage) - DidReceiveData(CoreIPC::DataReference data, int64_t encodedDataLength) + DidReceiveResponse(WebCore::ResourceResponse response, bool needsContinueDidReceiveResponseMessage) + DidReceiveData(IPC::DataReference data, int64_t encodedDataLength) DidFinishResourceLoad(double finishTime) DidFailResourceLoad(WebCore::ResourceError error) - + +#if USE(PROTECTION_SPACE_AUTH_CALLBACK) CanAuthenticateAgainstProtectionSpace(WebCore::ProtectionSpace protectionSpace) +#endif +#if ENABLE(SHAREABLE_RESOURCE) // DidReceiveResource is for when we have the entire resource data available at once, such as when the resource is cached in memory DidReceiveResource(WebKit::ShareableResource::Handle resource, double finishTime) +#endif } |