summaryrefslogtreecommitdiff
path: root/Source/WebKit2/NetworkProcess
diff options
context:
space:
mode:
authorAllan Sandfeld Jensen <allan.jensen@digia.com>2013-09-13 12:51:20 +0200
committerThe Qt Project <gerrit-noreply@qt-project.org>2013-09-19 20:50:05 +0200
commitd441d6f39bb846989d95bcf5caf387b42414718d (patch)
treee367e64a75991c554930278175d403c072de6bb8 /Source/WebKit2/NetworkProcess
parent0060b2994c07842f4c59de64b5e3e430525c4b90 (diff)
downloadqtwebkit-d441d6f39bb846989d95bcf5caf387b42414718d.tar.gz
Import Qt5x2 branch of QtWebkit for Qt 5.2
Importing a new snapshot of webkit. Change-Id: I2d01ad12cdc8af8cb015387641120a9d7ea5f10c Reviewed-by: Allan Sandfeld Jensen <allan.jensen@digia.com>
Diffstat (limited to 'Source/WebKit2/NetworkProcess')
-rw-r--r--Source/WebKit2/NetworkProcess/EntryPoint/mac/LegacyProcess/Info.plist (renamed from Source/WebKit2/NetworkProcess/Info.plist)6
-rw-r--r--Source/WebKit2/NetworkProcess/EntryPoint/mac/LegacyProcess/NetworkProcessMain.mm (renamed from Source/WebKit2/NetworkProcess/NetworkProcessMain.h)22
-rw-r--r--Source/WebKit2/NetworkProcess/EntryPoint/mac/XPCService/NetworkService.Development/Info.plist45
-rw-r--r--Source/WebKit2/NetworkProcess/EntryPoint/mac/XPCService/NetworkService/Info.plist50
-rw-r--r--Source/WebKit2/NetworkProcess/EntryPoint/mac/XPCService/NetworkServiceEntryPoint.mm48
-rw-r--r--Source/WebKit2/NetworkProcess/FileAPI/NetworkBlobRegistry.cpp117
-rw-r--r--Source/WebKit2/NetworkProcess/FileAPI/NetworkBlobRegistry.h72
-rw-r--r--Source/WebKit2/NetworkProcess/HostRecord.cpp164
-rw-r--r--Source/WebKit2/NetworkProcess/HostRecord.h42
-rw-r--r--Source/WebKit2/NetworkProcess/NetworkConnectionToWebProcess.cpp182
-rw-r--r--Source/WebKit2/NetworkProcess/NetworkConnectionToWebProcess.h57
-rw-r--r--Source/WebKit2/NetworkProcess/NetworkConnectionToWebProcess.messages.in35
-rw-r--r--Source/WebKit2/NetworkProcess/NetworkProcess.cpp171
-rw-r--r--Source/WebKit2/NetworkProcess/NetworkProcess.h82
-rw-r--r--Source/WebKit2/NetworkProcess/NetworkProcess.messages.in16
-rw-r--r--Source/WebKit2/NetworkProcess/NetworkProcessPlatformStrategies.cpp101
-rw-r--r--Source/WebKit2/NetworkProcess/NetworkProcessPlatformStrategies.h60
-rw-r--r--Source/WebKit2/NetworkProcess/NetworkResourceLoadScheduler.cpp241
-rw-r--r--Source/WebKit2/NetworkProcess/NetworkResourceLoadScheduler.h62
-rw-r--r--Source/WebKit2/NetworkProcess/NetworkResourceLoader.cpp353
-rw-r--r--Source/WebKit2/NetworkProcess/NetworkResourceLoader.h112
-rw-r--r--Source/WebKit2/NetworkProcess/NetworkResourceLoader.messages.in16
-rw-r--r--Source/WebKit2/NetworkProcess/SchedulableLoader.cpp118
-rw-r--r--Source/WebKit2/NetworkProcess/SchedulableLoader.h102
-rw-r--r--Source/WebKit2/NetworkProcess/SyncNetworkResourceLoader.cpp87
-rw-r--r--Source/WebKit2/NetworkProcess/SyncNetworkResourceLoader.h61
-rw-r--r--Source/WebKit2/NetworkProcess/mac/DiskCacheMonitor.h60
-rw-r--r--Source/WebKit2/NetworkProcess/mac/DiskCacheMonitor.mm109
-rw-r--r--Source/WebKit2/NetworkProcess/mac/NetworkProcessMac.mm189
-rw-r--r--Source/WebKit2/NetworkProcess/mac/NetworkProcessMainMac.mm99
-rw-r--r--Source/WebKit2/NetworkProcess/mac/NetworkResourceLoadSchedulerMac.mm13
-rw-r--r--Source/WebKit2/NetworkProcess/mac/NetworkResourceLoaderMac.mm116
-rw-r--r--Source/WebKit2/NetworkProcess/mac/RemoteNetworkingContext.h20
-rw-r--r--Source/WebKit2/NetworkProcess/mac/RemoteNetworkingContext.mm78
-rw-r--r--Source/WebKit2/NetworkProcess/mac/com.apple.WebKit.NetworkProcess.sb.in148
-rw-r--r--Source/WebKit2/NetworkProcess/unix/NetworkProcessMainUnix.cpp80
-rw-r--r--Source/WebKit2/NetworkProcess/unix/NetworkProcessMainUnix.h42
37 files changed, 2625 insertions, 751 deletions
diff --git a/Source/WebKit2/NetworkProcess/Info.plist b/Source/WebKit2/NetworkProcess/EntryPoint/mac/LegacyProcess/Info.plist
index ca50b3cab..45905e5a6 100644
--- a/Source/WebKit2/NetworkProcess/Info.plist
+++ b/Source/WebKit2/NetworkProcess/EntryPoint/mac/LegacyProcess/Info.plist
@@ -5,7 +5,7 @@
<key>CFBundleExecutable</key>
<string>${EXECUTABLE_NAME}</string>
<key>CFBundleGetInfoString</key>
- <string>${BUNDLE_VERSION}, Copyright 2003-2012 Apple Inc.</string>
+ <string>${BUNDLE_VERSION}, Copyright 2003-2013 Apple Inc.</string>
<key>CFBundleIdentifier</key>
<string>com.apple.WebKit.${PRODUCT_NAME}</string>
<key>CFBundleInfoDictionaryVersion</key>
@@ -26,5 +26,9 @@
<true/>
<key>NSPrincipalClass</key>
<string>NSApplication</string>
+ <key>CFBundleIconFile</key>
+ <string>${APP_ICON}</string>
+ <key>WebKitEntryPoint</key>
+ <string>NetworkProcessMain</string>
</dict>
</plist>
diff --git a/Source/WebKit2/NetworkProcess/NetworkProcessMain.h b/Source/WebKit2/NetworkProcess/EntryPoint/mac/LegacyProcess/NetworkProcessMain.mm
index ee55a37d6..87b9e4000 100644
--- a/Source/WebKit2/NetworkProcess/NetworkProcessMain.h
+++ b/Source/WebKit2/NetworkProcess/EntryPoint/mac/LegacyProcess/NetworkProcessMain.mm
@@ -23,19 +23,21 @@
* THE POSSIBILITY OF SUCH DAMAGE.
*/
-#ifndef NetworkProcessMain_h
-#define NetworkProcessMain_h
+#import "config.h"
#if ENABLE(NETWORK_PROCESS)
-namespace WebKit {
-
-class CommandLine;
+#import "ChildProcessEntryPoint.h"
+#import "NetworkProcess.h"
+#import "WKBase.h"
-int NetworkProcessMain(const CommandLine&);
-
-} // namespace WebKit
+using namespace WebKit;
-#endif // ENABLE(NETWORK_PROCESS)
+extern "C" WK_EXPORT int NetworkProcessMain(int argc, char** argv);
+
+int NetworkProcessMain(int argc, char** argv)
+{
+ return ChildProcessMain<NetworkProcess, ChildProcessMainDelegate>(argc, argv);
+}
-#endif // NetworkProcessMain_h
+#endif // ENABLE(NETWORK_PROCESS)
diff --git a/Source/WebKit2/NetworkProcess/EntryPoint/mac/XPCService/NetworkService.Development/Info.plist b/Source/WebKit2/NetworkProcess/EntryPoint/mac/XPCService/NetworkService.Development/Info.plist
new file mode 100644
index 000000000..c73c3d3bb
--- /dev/null
+++ b/Source/WebKit2/NetworkProcess/EntryPoint/mac/XPCService/NetworkService.Development/Info.plist
@@ -0,0 +1,45 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+ <key>CFBundleGetInfoString</key>
+ <string>${BUNDLE_VERSION}, Copyright 2003-2013 Apple Inc.</string>
+ <key>CFBundleDevelopmentRegion</key>
+ <string>English</string>
+ <key>CFBundleExecutable</key>
+ <string>${EXECUTABLE_NAME}</string>
+ <key>CFBundleIdentifier</key>
+ <string>com.apple.WebKit.Networking.Development</string>
+ <key>CFBundleInfoDictionaryVersion</key>
+ <string>6.0</string>
+ <key>CFBundleName</key>
+ <string>${PRODUCT_NAME}</string>
+ <key>CFBundlePackageType</key>
+ <string>XPC!</string>
+ <key>CFBundleShortVersionString</key>
+ <string>${SHORT_VERSION_STRING}</string>
+ <key>CFBundleSignature</key>
+ <string>????</string>
+ <key>CFBundleVersion</key>
+ <string>${BUNDLE_VERSION}</string>
+ <key>LSFileQuarantineEnabled</key>
+ <true/>
+ <key>NSPrincipalClass</key>
+ <string>NSApplication</string>
+ <key>WebKitEntryPoint</key>
+ <string>NetworkServiceInitializer</string>
+ <key>LSUIElement</key>
+ <true/>
+ <key>XPCService</key>
+ <dict>
+ <key>ServiceType</key>
+ <string>Application</string>
+ <key>JoinExistingSession</key>
+ <true/>
+ <key>RunLoopType</key>
+ <string>NSRunLoop</string>
+ <key>_MultipleInstances</key>
+ <true/>
+ </dict>
+</dict>
+</plist>
diff --git a/Source/WebKit2/NetworkProcess/EntryPoint/mac/XPCService/NetworkService/Info.plist b/Source/WebKit2/NetworkProcess/EntryPoint/mac/XPCService/NetworkService/Info.plist
new file mode 100644
index 000000000..ac5e4e522
--- /dev/null
+++ b/Source/WebKit2/NetworkProcess/EntryPoint/mac/XPCService/NetworkService/Info.plist
@@ -0,0 +1,50 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+ <key>CFBundleGetInfoString</key>
+ <string>${BUNDLE_VERSION}, Copyright 2003-2013 Apple Inc.</string>
+ <key>CFBundleDevelopmentRegion</key>
+ <string>English</string>
+ <key>CFBundleExecutable</key>
+ <string>${EXECUTABLE_NAME}</string>
+ <key>CFBundleIdentifier</key>
+ <string>com.apple.WebKit.Networking</string>
+ <key>CFBundleInfoDictionaryVersion</key>
+ <string>6.0</string>
+ <key>CFBundleName</key>
+ <string>${PRODUCT_NAME}</string>
+ <key>CFBundlePackageType</key>
+ <string>XPC!</string>
+ <key>CFBundleShortVersionString</key>
+ <string>${SHORT_VERSION_STRING}</string>
+ <key>CFBundleSignature</key>
+ <string>????</string>
+ <key>CFBundleVersion</key>
+ <string>${BUNDLE_VERSION}</string>
+ <key>LSFileQuarantineEnabled</key>
+ <true/>
+ <key>NSPrincipalClass</key>
+ <string>NSApplication</string>
+ <key>WebKitEntryPoint</key>
+ <string>NetworkServiceInitializer</string>
+ <key>LSUIElement</key>
+ <true/>
+ <key>XPCService</key>
+ <dict>
+ <key>ServiceType</key>
+ <string>Application</string>
+ <key>JoinExistingSession</key>
+ <true/>
+ <key>RunLoopType</key>
+ <string>NSRunLoop</string>
+ <key>_MultipleInstances</key>
+ <true/>
+ <key>EnvironmentVariables</key>
+ <dict>
+ <key>DYLD_INSERT_LIBRARIES</key>
+ <string>$(WEBKIT2_FRAMEWORKS_DIR)/WebKit2.framework/NetworkProcess.app/Contents/MacOS/SecItemShim.dylib</string>
+ </dict>
+ </dict>
+</dict>
+</plist>
diff --git a/Source/WebKit2/NetworkProcess/EntryPoint/mac/XPCService/NetworkServiceEntryPoint.mm b/Source/WebKit2/NetworkProcess/EntryPoint/mac/XPCService/NetworkServiceEntryPoint.mm
new file mode 100644
index 000000000..1c6ab641a
--- /dev/null
+++ b/Source/WebKit2/NetworkProcess/EntryPoint/mac/XPCService/NetworkServiceEntryPoint.mm
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 2013 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.
+ */
+
+#import "config.h"
+
+#if HAVE(XPC)
+
+#import "EnvironmentUtilities.h"
+#import "NetworkProcess.h"
+#import "WKBase.h"
+#import "XPCServiceEntryPoint.h"
+
+using namespace WebKit;
+
+extern "C" WK_EXPORT void NetworkServiceInitializer(xpc_connection_t connection, xpc_object_t initializerMessage);
+
+void NetworkServiceInitializer(xpc_connection_t connection, xpc_object_t initializerMessage)
+{
+ // Remove the SecItemShim from the DYLD_INSERT_LIBRARIES environment variable so any processes spawned by
+ // the this process don't try to insert the shim and crash.
+ EnvironmentUtilities::stripValuesEndingWithString("DYLD_INSERT_LIBRARIES", "/SecItemShim.dylib");
+
+ XPCServiceInitializer<NetworkProcess, XPCServiceInitializerDelegate>(connection, initializerMessage);
+}
+
+#endif // HAVE(XPC)
diff --git a/Source/WebKit2/NetworkProcess/FileAPI/NetworkBlobRegistry.cpp b/Source/WebKit2/NetworkProcess/FileAPI/NetworkBlobRegistry.cpp
new file mode 100644
index 000000000..1e60d401b
--- /dev/null
+++ b/Source/WebKit2/NetworkProcess/FileAPI/NetworkBlobRegistry.cpp
@@ -0,0 +1,117 @@
+/*
+ * Copyright (C) 2013 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 "NetworkBlobRegistry.h"
+
+#if ENABLE(BLOB) && ENABLE(NETWORK_PROCESS)
+
+#include "SandboxExtension.h"
+#include <WebCore/BlobRegistryImpl.h>
+#include <wtf/MainThread.h>
+
+using namespace WebCore;
+
+namespace WebKit {
+
+NetworkBlobRegistry& NetworkBlobRegistry::shared()
+{
+ ASSERT(isMainThread());
+ DEFINE_STATIC_LOCAL(NetworkBlobRegistry, registry, ());
+ return registry;
+}
+
+NetworkBlobRegistry::NetworkBlobRegistry()
+{
+}
+
+void NetworkBlobRegistry::registerBlobURL(NetworkConnectionToWebProcess* connection, const KURL& url, PassOwnPtr<BlobData> data, const Vector<RefPtr<SandboxExtension>>& newSandboxExtensions)
+{
+ ASSERT(!m_sandboxExtensions.contains(url.string()));
+
+ // Combine new extensions for File items and existing extensions for inner Blob items.
+ Vector<RefPtr<SandboxExtension>> sandboxExtensions = newSandboxExtensions;
+ const BlobDataItemList& items = data->items();
+ for (size_t i = 0, count = items.size(); i < count; ++i) {
+ if (items[i].type == BlobDataItem::Blob)
+ sandboxExtensions.appendVector(m_sandboxExtensions.get(items[i].url.string()));
+ }
+
+ blobRegistry().registerBlobURL(url, data);
+
+ if (!sandboxExtensions.isEmpty())
+ m_sandboxExtensions.add(url.string(), sandboxExtensions);
+
+ ASSERT(!m_blobsForConnection.get(connection).contains(url));
+ BlobForConnectionMap::iterator mapIterator = m_blobsForConnection.find(connection);
+ if (mapIterator == m_blobsForConnection.end())
+ mapIterator = m_blobsForConnection.add(connection, HashSet<KURL>()).iterator;
+ mapIterator->value.add(url);
+}
+
+void NetworkBlobRegistry::registerBlobURL(NetworkConnectionToWebProcess* connection, const WebCore::KURL& url, const WebCore::KURL& srcURL)
+{
+ blobRegistry().registerBlobURL(url, srcURL);
+ SandboxExtensionMap::iterator iter = m_sandboxExtensions.find(srcURL.string());
+ if (iter != m_sandboxExtensions.end())
+ m_sandboxExtensions.add(url.string(), iter->value);
+
+ ASSERT(m_blobsForConnection.contains(connection));
+ ASSERT(m_blobsForConnection.find(connection)->value.contains(srcURL));
+ m_blobsForConnection.find(connection)->value.add(url);
+}
+
+void NetworkBlobRegistry::unregisterBlobURL(NetworkConnectionToWebProcess* connection, const WebCore::KURL& url)
+{
+ blobRegistry().unregisterBlobURL(url);
+ m_sandboxExtensions.remove(url.string());
+
+ ASSERT(m_blobsForConnection.contains(connection));
+ ASSERT(m_blobsForConnection.find(connection)->value.contains(url));
+ m_blobsForConnection.find(connection)->value.remove(url);
+}
+
+void NetworkBlobRegistry::connectionToWebProcessDidClose(NetworkConnectionToWebProcess* connection)
+{
+ if (!m_blobsForConnection.contains(connection))
+ return;
+
+ HashSet<KURL>& blobsForConnection = m_blobsForConnection.find(connection)->value;
+ for (HashSet<KURL>::iterator iter = blobsForConnection.begin(), end = blobsForConnection.end(); iter != end; ++iter) {
+ blobRegistry().unregisterBlobURL(*iter);
+ m_sandboxExtensions.remove(*iter);
+ }
+
+ m_blobsForConnection.remove(connection);
+}
+
+const Vector<RefPtr<SandboxExtension>> NetworkBlobRegistry::sandboxExtensions(const WebCore::KURL& url)
+{
+ return m_sandboxExtensions.get(url.string());
+}
+
+}
+
+#endif
diff --git a/Source/WebKit2/NetworkProcess/FileAPI/NetworkBlobRegistry.h b/Source/WebKit2/NetworkProcess/FileAPI/NetworkBlobRegistry.h
new file mode 100644
index 000000000..6d71bbfc9
--- /dev/null
+++ b/Source/WebKit2/NetworkProcess/FileAPI/NetworkBlobRegistry.h
@@ -0,0 +1,72 @@
+/*
+ * Copyright (C) 2013 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 NetworkBlobRegistry_h
+#define NetworkBlobRegistry_h
+
+#if ENABLE(BLOB) && ENABLE(NETWORK_PROCESS)
+
+#include <WebCore/KURLHash.h>
+#include <wtf/HashMap.h>
+#include <wtf/HashSet.h>
+
+namespace WebCore {
+class BlobData;
+}
+
+namespace WebKit {
+
+class NetworkConnectionToWebProcess;
+class SandboxExtension;
+
+class NetworkBlobRegistry {
+WTF_MAKE_NONCOPYABLE(NetworkBlobRegistry);
+public:
+ NetworkBlobRegistry();
+ static NetworkBlobRegistry& shared();
+
+ void registerBlobURL(NetworkConnectionToWebProcess*, const WebCore::KURL&, PassOwnPtr<WebCore::BlobData>, const Vector<RefPtr<SandboxExtension>>&);
+ void registerBlobURL(NetworkConnectionToWebProcess*, const WebCore::KURL&, const WebCore::KURL& srcURL);
+ void unregisterBlobURL(NetworkConnectionToWebProcess*, const WebCore::KURL&);
+
+ void connectionToWebProcessDidClose(NetworkConnectionToWebProcess*);
+
+ const Vector<RefPtr<SandboxExtension>> sandboxExtensions(const WebCore::KURL&);
+
+private:
+ ~NetworkBlobRegistry();
+
+ typedef HashMap<String, Vector<RefPtr<SandboxExtension>>> SandboxExtensionMap;
+ SandboxExtensionMap m_sandboxExtensions;
+
+ typedef HashMap<NetworkConnectionToWebProcess*, HashSet<WebCore::KURL>> BlobForConnectionMap;
+ BlobForConnectionMap m_blobsForConnection;
+};
+
+}
+
+#endif // ENABLE(BLOB) && ENABLE(NETWORK_PROCESS)
+
+#endif // NetworkBlobRegistry_h
diff --git a/Source/WebKit2/NetworkProcess/HostRecord.cpp b/Source/WebKit2/NetworkProcess/HostRecord.cpp
index 7bc96175f..e7ce34b0b 100644
--- a/Source/WebKit2/NetworkProcess/HostRecord.cpp
+++ b/Source/WebKit2/NetworkProcess/HostRecord.cpp
@@ -32,6 +32,8 @@
#include "NetworkResourceLoadParameters.h"
#include "NetworkResourceLoadScheduler.h"
#include "NetworkResourceLoader.h"
+#include "SyncNetworkResourceLoader.h"
+#include <wtf/MainThread.h>
#if ENABLE(NETWORK_PROCESS)
@@ -48,46 +50,71 @@ HostRecord::HostRecord(const String& name, int maxRequestsInFlight)
HostRecord::~HostRecord()
{
#ifndef NDEBUG
- ASSERT(m_resourceIdentifiersLoading.isEmpty());
+ ASSERT(m_loadersInProgress.isEmpty());
for (unsigned p = 0; p <= ResourceLoadPriorityHighest; p++)
ASSERT(m_loadersPending[p].isEmpty());
#endif
}
-void HostRecord::schedule(PassRefPtr<NetworkResourceLoader> loader)
+void HostRecord::scheduleResourceLoader(PassRefPtr<SchedulableLoader> loader)
{
- m_loadersPending[loader->priority()].append(loader);
+ ASSERT(isMainThread());
+
+ loader->setHostRecord(this);
+
+ if (loader->isSynchronous())
+ m_syncLoadersPending.append(loader);
+ else
+ m_loadersPending[loader->priority()].append(loader);
}
-void HostRecord::addLoadInProgress(ResourceLoadIdentifier identifier)
+void HostRecord::addLoaderInProgress(SchedulableLoader* loader)
{
- m_resourceIdentifiersLoading.add(identifier);
+ ASSERT(isMainThread());
+
+ m_loadersInProgress.add(loader);
+ loader->setHostRecord(this);
}
-void HostRecord::remove(ResourceLoadIdentifier identifier)
+inline bool removeLoaderFromQueue(SchedulableLoader* loader, LoaderQueue& queue)
{
- // FIXME (NetworkProcess): Due to IPC race conditions, it's possible this HostRecord will be asked to remove the same identifer twice.
- // It would be nice to know the identifier has already been removed and treat it as a no-op.
+ LoaderQueue::iterator end = queue.end();
+ for (LoaderQueue::iterator it = queue.begin(); it != end; ++it) {
+ if (it->get() == loader) {
+ loader->setHostRecord(0);
+ queue.remove(it);
+ return true;
+ }
+ }
+ return false;
+}
+
+void HostRecord::removeLoader(SchedulableLoader* loader)
+{
+ ASSERT(isMainThread());
- if (m_resourceIdentifiersLoading.contains(identifier)) {
- m_resourceIdentifiersLoading.remove(identifier);
+ // FIXME (NetworkProcess): Due to IPC race conditions, it's possible this HostRecord will be asked to remove the same loader twice.
+ // It would be nice to know the loader has already been removed and treat it as a no-op.
+
+ SchedulableLoaderSet::iterator i = m_loadersInProgress.find(loader);
+ if (i != m_loadersInProgress.end()) {
+ i->get()->setHostRecord(0);
+ m_loadersInProgress.remove(i);
return;
}
+
+ if (removeLoaderFromQueue(loader, m_syncLoadersPending))
+ return;
- for (int priority = ResourceLoadPriorityHighest; priority >= ResourceLoadPriorityLowest; --priority) {
- LoaderQueue::iterator end = m_loadersPending[priority].end();
- for (LoaderQueue::iterator it = m_loadersPending[priority].begin(); it != end; ++it) {
- if (it->get()->identifier() == identifier) {
- m_loadersPending[priority].remove(it);
- return;
- }
- }
+ for (int priority = ResourceLoadPriorityHighest; priority >= ResourceLoadPriorityLowest; --priority) {
+ if (removeLoaderFromQueue(loader, m_loadersPending[priority]))
+ return;
}
}
bool HostRecord::hasRequests() const
{
- if (!m_resourceIdentifiersLoading.isEmpty())
+ if (!m_loadersInProgress.isEmpty())
return true;
for (unsigned p = 0; p <= ResourceLoadPriorityHighest; p++) {
@@ -98,12 +125,105 @@ bool HostRecord::hasRequests() const
return false;
}
-bool HostRecord::limitRequests(ResourceLoadPriority priority, bool serialLoadingEnabled) const
+uint64_t HostRecord::pendingRequestCount() const
+{
+ uint64_t count = 0;
+
+ for (unsigned p = 0; p <= ResourceLoadPriorityHighest; p++)
+ count += m_loadersPending[p].size();
+
+ return count;
+}
+
+uint64_t HostRecord::activeLoadCount() const
+{
+ return m_loadersInProgress.size();
+}
+
+void HostRecord::servePendingRequestsForQueue(LoaderQueue& queue, ResourceLoadPriority priority)
+{
+ // We only enforce the connection limit for http(s) hosts, which are the only ones with names.
+ bool shouldLimitRequests = !name().isNull();
+
+ // For non-named hosts - everything but http(s) - we should only enforce the limit if the document
+ // isn't done parsing and we don't know all stylesheets yet.
+
+ // FIXME (NetworkProcess): The above comment about document parsing and stylesheets is a holdover
+ // from the WebCore::ResourceLoadScheduler.
+ // The behavior described was at one time important for WebCore's single threadedness.
+ // It's possible that we don't care about it with the NetworkProcess.
+ // We should either decide it's not important and change the above comment, or decide it is
+ // still important and somehow account for it.
+
+ // Very low priority loaders are only handled when no other loaders are in progress.
+ if (shouldLimitRequests && priority == ResourceLoadPriorityVeryLow && !m_loadersInProgress.isEmpty())
+ return;
+
+ while (!queue.isEmpty()) {
+ RefPtr<SchedulableLoader> loader = queue.first();
+ ASSERT(loader->hostRecord() == this);
+
+ // This request might be from WebProcess we've lost our connection to.
+ // If so we should just skip it.
+ if (!loader->connectionToWebProcess()) {
+ removeLoader(loader.get());
+ continue;
+ }
+
+ if (shouldLimitRequests && limitsRequests(priority, loader.get()))
+ return;
+
+ m_loadersInProgress.add(loader);
+ queue.removeFirst();
+
+ LOG(NetworkScheduling, "(NetworkProcess) HostRecord::servePendingRequestsForQueue - Starting load of %s\n", loader->request().url().string().utf8().data());
+ loader->start();
+ }
+}
+
+void HostRecord::servePendingRequests(ResourceLoadPriority minimumPriority)
{
- if (priority == ResourceLoadPriorityVeryLow && !m_resourceIdentifiersLoading.isEmpty())
+ LOG(NetworkScheduling, "(NetworkProcess) HostRecord::servePendingRequests Host name='%s'", name().utf8().data());
+
+ // We serve synchronous requests before any other requests to improve responsiveness in any
+ // WebProcess that is waiting on a synchronous load.
+ servePendingRequestsForQueue(m_syncLoadersPending, ResourceLoadPriorityHighest);
+
+ for (int priority = ResourceLoadPriorityHighest; priority >= minimumPriority; --priority)
+ servePendingRequestsForQueue(m_loadersPending[priority], (ResourceLoadPriority)priority);
+}
+
+bool HostRecord::limitsRequests(ResourceLoadPriority priority, SchedulableLoader* loader) const
+{
+ ASSERT(loader);
+ ASSERT(loader->connectionToWebProcess());
+
+ if (priority == ResourceLoadPriorityVeryLow && !m_loadersInProgress.isEmpty())
+ return true;
+
+ if (loader->connectionToWebProcess()->isSerialLoadingEnabled() && m_loadersInProgress.size() >= 1)
+ return true;
+
+ // If we're exactly at the limit for requests in flight, and this loader is asynchronous, then we're done serving new requests.
+ // The synchronous loader exception handles the case where a sync XHR is made while 6 other requests are already in flight.
+ if (m_loadersInProgress.size() == m_maxRequestsInFlight && !loader->isSynchronous())
return true;
- return m_resourceIdentifiersLoading.size() >= (serialLoadingEnabled ? 1 : m_maxRequestsInFlight);
+ // If we're already past the limit of the number of loaders in flight, we won't even serve new synchronous requests right now.
+ if (m_loadersInProgress.size() > m_maxRequestsInFlight) {
+#ifndef NDEBUG
+ // If we have more loaders in progress than we should, at least one of them had better be synchronous.
+ SchedulableLoaderSet::iterator i = m_loadersInProgress.begin();
+ SchedulableLoaderSet::iterator end = m_loadersInProgress.end();
+ for (; i != end; ++i) {
+ if (i->get()->isSynchronous())
+ break;
+ }
+ ASSERT(i != end);
+#endif
+ return true;
+ }
+ return false;
}
} // namespace WebKit
diff --git a/Source/WebKit2/NetworkProcess/HostRecord.h b/Source/WebKit2/NetworkProcess/HostRecord.h
index 1b21376de..058208975 100644
--- a/Source/WebKit2/NetworkProcess/HostRecord.h
+++ b/Source/WebKit2/NetworkProcess/HostRecord.h
@@ -28,36 +28,52 @@
#if ENABLE(NETWORK_PROCESS)
-#include <WebCore/ResourceRequest.h>
+#include <WebCore/ResourceLoadPriority.h>
#include <wtf/Deque.h>
#include <wtf/HashSet.h>
+#include <wtf/RefCounted.h>
#include <wtf/text/WTFString.h>
namespace WebKit {
class NetworkResourceLoader;
+class SchedulableLoader;
+class SyncNetworkResourceLoader;
+
+typedef Deque<RefPtr<SchedulableLoader>> LoaderQueue;
typedef uint64_t ResourceLoadIdentifier;
-class HostRecord {
- WTF_MAKE_NONCOPYABLE(HostRecord); WTF_MAKE_FAST_ALLOCATED;
+class HostRecord : public RefCounted<HostRecord> {
public:
- HostRecord(const String& name, int maxRequestsInFlight);
+ static PassRefPtr<HostRecord> create(const String& name, int maxRequestsInFlight)
+ {
+ return adoptRef(new HostRecord(name, maxRequestsInFlight));
+ }
+
~HostRecord();
const String& name() const { return m_name; }
- void schedule(PassRefPtr<NetworkResourceLoader>);
- void addLoadInProgress(ResourceLoadIdentifier);
- void remove(ResourceLoadIdentifier);
+
+ void scheduleResourceLoader(PassRefPtr<SchedulableLoader>);
+ void addLoaderInProgress(SchedulableLoader*);
+ void removeLoader(SchedulableLoader*);
bool hasRequests() const;
- bool limitRequests(WebCore::ResourceLoadPriority, bool serialLoadingEnabled) const;
+ void servePendingRequests(WebCore::ResourceLoadPriority);
- typedef Deque<RefPtr<NetworkResourceLoader> > LoaderQueue;
- LoaderQueue& loadersPending(WebCore::ResourceLoadPriority priority) { return m_loadersPending[priority]; }
+ uint64_t pendingRequestCount() const;
+ uint64_t activeLoadCount() const;
+
+private:
+ HostRecord(const String& name, int maxRequestsInFlight);
+
+ void servePendingRequestsForQueue(LoaderQueue&, WebCore::ResourceLoadPriority);
+ bool limitsRequests(WebCore::ResourceLoadPriority, SchedulableLoader*) const;
-private:
LoaderQueue m_loadersPending[WebCore::ResourceLoadPriorityHighest + 1];
- typedef HashSet<ResourceLoadIdentifier> ResourceLoadIdentifierSet;
- ResourceLoadIdentifierSet m_resourceIdentifiersLoading;
+ LoaderQueue m_syncLoadersPending;
+
+ typedef HashSet<RefPtr<SchedulableLoader>> SchedulableLoaderSet;
+ SchedulableLoaderSet m_loadersInProgress;
const String m_name;
int m_maxRequestsInFlight;
diff --git a/Source/WebKit2/NetworkProcess/NetworkConnectionToWebProcess.cpp b/Source/WebKit2/NetworkProcess/NetworkConnectionToWebProcess.cpp
index f07165107..b21815418 100644
--- a/Source/WebKit2/NetworkProcess/NetworkConnectionToWebProcess.cpp
+++ b/Source/WebKit2/NetworkProcess/NetworkConnectionToWebProcess.cpp
@@ -26,10 +26,17 @@
#include "config.h"
#include "NetworkConnectionToWebProcess.h"
+#include "BlobRegistrationData.h"
#include "ConnectionStack.h"
+#include "NetworkBlobRegistry.h"
+#include "NetworkConnectionToWebProcessMessages.h"
#include "NetworkProcess.h"
+#include "NetworkResourceLoadParameters.h"
#include "NetworkResourceLoader.h"
+#include "NetworkResourceLoaderMessages.h"
#include "RemoteNetworkingContext.h"
+#include "SyncNetworkResourceLoader.h"
+#include <WebCore/BlobData.h>
#include <WebCore/PlatformCookieJar.h>
#include <WebCore/ResourceLoaderOptions.h>
#include <WebCore/ResourceRequest.h>
@@ -56,42 +63,29 @@ NetworkConnectionToWebProcess::NetworkConnectionToWebProcess(CoreIPC::Connection
NetworkConnectionToWebProcess::~NetworkConnectionToWebProcess()
{
- ASSERT(!m_connection);
- ASSERT(m_observers.isEmpty());
-}
-
-void NetworkConnectionToWebProcess::registerObserver(NetworkConnectionToWebProcessObserver* observer)
-{
- ASSERT(!m_observers.contains(observer));
- m_observers.add(observer);
-}
-
-void NetworkConnectionToWebProcess::unregisterObserver(NetworkConnectionToWebProcessObserver* observer)
-{
- ASSERT(m_observers.contains(observer));
- m_observers.remove(observer);
}
-void NetworkConnectionToWebProcess::didReceiveMessage(CoreIPC::Connection* connection, CoreIPC::MessageID messageID, CoreIPC::MessageDecoder& decoder)
+void NetworkConnectionToWebProcess::didReceiveMessage(CoreIPC::Connection* connection, CoreIPC::MessageDecoder& decoder)
{
- if (messageID.is<CoreIPC::MessageClassNetworkConnectionToWebProcess>()) {
- didReceiveNetworkConnectionToWebProcessMessage(connection, messageID, decoder);
+ if (decoder.messageReceiverName() == Messages::NetworkConnectionToWebProcess::messageReceiverName()) {
+ didReceiveNetworkConnectionToWebProcessMessage(connection, decoder);
return;
}
-
- if (messageID.is<CoreIPC::MessageClassNetworkResourceLoader>()) {
- NetworkResourceLoader* loader = NetworkProcess::shared().networkResourceLoadScheduler().networkResourceLoaderForIdentifier(decoder.destinationID());
- if (loader)
- loader->didReceiveNetworkResourceLoaderMessage(connection, messageID, decoder);
+
+ if (decoder.messageReceiverName() == Messages::NetworkResourceLoader::messageReceiverName()) {
+ HashMap<ResourceLoadIdentifier, RefPtr<NetworkResourceLoader>>::iterator loaderIterator = m_networkResourceLoaders.find(decoder.destinationID());
+ if (loaderIterator != m_networkResourceLoaders.end())
+ loaderIterator->value->didReceiveNetworkResourceLoaderMessage(connection, decoder);
return;
}
+
ASSERT_NOT_REACHED();
}
-void NetworkConnectionToWebProcess::didReceiveSyncMessage(CoreIPC::Connection* connection, CoreIPC::MessageID messageID, CoreIPC::MessageDecoder& decoder, OwnPtr<CoreIPC::MessageEncoder>& reply)
+void NetworkConnectionToWebProcess::didReceiveSyncMessage(CoreIPC::Connection* connection, CoreIPC::MessageDecoder& decoder, OwnPtr<CoreIPC::MessageEncoder>& reply)
{
- if (messageID.is<CoreIPC::MessageClassNetworkConnectionToWebProcess>()) {
- didReceiveSyncNetworkConnectionToWebProcessMessage(connection, messageID, decoder, reply);
+ if (decoder.messageReceiverName() == Messages::NetworkConnectionToWebProcess::messageReceiverName()) {
+ didReceiveSyncNetworkConnectionToWebProcessMessage(connection, decoder, reply);
return;
}
ASSERT_NOT_REACHED();
@@ -99,39 +93,55 @@ void NetworkConnectionToWebProcess::didReceiveSyncMessage(CoreIPC::Connection* c
void NetworkConnectionToWebProcess::didClose(CoreIPC::Connection*)
{
- // Protect ourself as we might be otherwise be deleted during this function
+ // Protect ourself as we might be otherwise be deleted during this function.
RefPtr<NetworkConnectionToWebProcess> protector(this);
+
+ HashMap<ResourceLoadIdentifier, RefPtr<NetworkResourceLoader>>::iterator end = m_networkResourceLoaders.end();
+ for (HashMap<ResourceLoadIdentifier, RefPtr<NetworkResourceLoader>>::iterator i = m_networkResourceLoaders.begin(); i != end; ++i)
+ i->value->abort();
+
+ HashMap<ResourceLoadIdentifier, RefPtr<SyncNetworkResourceLoader>>::iterator syncEnd = m_syncNetworkResourceLoaders.end();
+ for (HashMap<ResourceLoadIdentifier, RefPtr<SyncNetworkResourceLoader>>::iterator i = m_syncNetworkResourceLoaders.begin(); i != syncEnd; ++i)
+ i->value->abort();
+
+ NetworkBlobRegistry::shared().connectionToWebProcessDidClose(this);
+
+ m_networkResourceLoaders.clear();
NetworkProcess::shared().removeNetworkConnectionToWebProcess(this);
-
- Vector<NetworkConnectionToWebProcessObserver*> observers;
- copyToVector(m_observers, observers);
- for (size_t i = 0; i < observers.size(); ++i)
- observers[i]->connectionToWebProcessDidClose(this);
-
- // FIXME (NetworkProcess): We might consider actively clearing out all requests for this connection.
- // But that might not be necessary as the observer mechanism used above is much more direct.
-
- m_connection = 0;
}
void NetworkConnectionToWebProcess::didReceiveInvalidMessage(CoreIPC::Connection*, CoreIPC::StringReference, CoreIPC::StringReference)
{
}
-void NetworkConnectionToWebProcess::scheduleResourceLoad(const NetworkResourceLoadParameters& loadParameters, ResourceLoadIdentifier& resourceLoadIdentifier)
+void NetworkConnectionToWebProcess::scheduleResourceLoad(const NetworkResourceLoadParameters& loadParameters)
{
- resourceLoadIdentifier = NetworkProcess::shared().networkResourceLoadScheduler().scheduleResourceLoad(loadParameters, this);
+ RefPtr<NetworkResourceLoader> loader = NetworkResourceLoader::create(loadParameters, this);
+ m_networkResourceLoaders.add(loadParameters.identifier, loader);
+ NetworkProcess::shared().networkResourceLoadScheduler().scheduleLoader(loader.get());
}
-void NetworkConnectionToWebProcess::addLoadInProgress(const KURL& url, ResourceLoadIdentifier& identifier)
+void NetworkConnectionToWebProcess::performSynchronousLoad(const NetworkResourceLoadParameters& loadParameters, PassRefPtr<Messages::NetworkConnectionToWebProcess::PerformSynchronousLoad::DelayedReply> reply)
{
- identifier = NetworkProcess::shared().networkResourceLoadScheduler().addLoadInProgress(url);
+ RefPtr<SyncNetworkResourceLoader> loader = SyncNetworkResourceLoader::create(loadParameters, this, reply);
+ m_syncNetworkResourceLoaders.add(loadParameters.identifier, loader);
+ NetworkProcess::shared().networkResourceLoadScheduler().scheduleLoader(loader.get());
}
void NetworkConnectionToWebProcess::removeLoadIdentifier(ResourceLoadIdentifier identifier)
{
- NetworkProcess::shared().networkResourceLoadScheduler().removeLoadIdentifier(identifier);
+ RefPtr<SchedulableLoader> loader = m_networkResourceLoaders.take(identifier);
+ if (!loader)
+ loader = m_syncNetworkResourceLoaders.take(identifier);
+
+ // It's possible we have no loader for this identifier if the NetworkProcess crashed and this was a respawned NetworkProcess.
+ if (!loader)
+ return;
+
+ // Abort the load now, as the WebProcess won't be able to respond to messages any more which might lead
+ // to leaked loader resources (connections, threads, etc).
+ loader->abort();
}
void NetworkConnectionToWebProcess::servePendingRequests(uint32_t resourceLoadPriority)
@@ -139,75 +149,95 @@ void NetworkConnectionToWebProcess::servePendingRequests(uint32_t resourceLoadPr
NetworkProcess::shared().networkResourceLoadScheduler().servePendingRequests(static_cast<ResourceLoadPriority>(resourceLoadPriority));
}
-void NetworkConnectionToWebProcess::suspendPendingRequests()
+void NetworkConnectionToWebProcess::setSerialLoadingEnabled(bool enabled)
{
- NetworkProcess::shared().networkResourceLoadScheduler().suspendPendingRequests();
+ m_serialLoadingEnabled = enabled;
}
-void NetworkConnectionToWebProcess::resumePendingRequests()
+static NetworkStorageSession& storageSession(bool privateBrowsingEnabled)
{
- NetworkProcess::shared().networkResourceLoadScheduler().resumePendingRequests();
+ if (privateBrowsingEnabled) {
+ NetworkStorageSession* privateSession = RemoteNetworkingContext::privateBrowsingSession();
+ if (privateSession)
+ return *privateSession;
+ // Some requests with private browsing mode requested may still be coming shortly after NetworkProcess was told to destroy its session.
+ // FIXME: Find a way to track private browsing sessions more rigorously.
+ LOG_ERROR("Private browsing was requested, but there was no session for it. Please file a bug unless you just disabled private browsing, in which case it's an expected race.");
+ }
+ return NetworkStorageSession::defaultStorageSession();
}
-void NetworkConnectionToWebProcess::setSerialLoadingEnabled(bool enabled)
+void NetworkConnectionToWebProcess::startDownload(bool privateBrowsingEnabled, uint64_t downloadID, const ResourceRequest& request)
{
- m_serialLoadingEnabled = enabled;
+ // FIXME: Do something with the private browsing flag.
+ NetworkProcess::shared().downloadManager().startDownload(downloadID, request);
}
-void NetworkConnectionToWebProcess::cookiesForDOM(const KURL& firstParty, const KURL& url, String& result)
+void NetworkConnectionToWebProcess::convertMainResourceLoadToDownload(uint64_t mainResourceLoadIdentifier, uint64_t downloadID, const ResourceRequest& request, const ResourceResponse& response)
{
- // FIXME (NetworkProcess): Use a correct storage session.
- result = WebCore::cookiesForDOM(RemoteNetworkingContext::create(false, false).get(), firstParty, url);
+ if (!mainResourceLoadIdentifier) {
+ NetworkProcess::shared().downloadManager().startDownload(downloadID, request);
+ return;
+ }
+
+ NetworkResourceLoader* loader = m_networkResourceLoaders.get(mainResourceLoadIdentifier);
+ NetworkProcess::shared().downloadManager().convertHandleToDownload(downloadID, loader->handle(), request, response);
+
+ // Unblock the URL connection operation queue.
+ loader->handle()->continueDidReceiveResponse();
+
+ loader->didConvertHandleToDownload();
+}
+
+void NetworkConnectionToWebProcess::cookiesForDOM(bool privateBrowsingEnabled, const KURL& firstParty, const KURL& url, String& result)
+{
+ result = WebCore::cookiesForDOM(storageSession(privateBrowsingEnabled), firstParty, url);
}
-void NetworkConnectionToWebProcess::setCookiesFromDOM(const KURL& firstParty, const KURL& url, const String& cookieString)
+void NetworkConnectionToWebProcess::setCookiesFromDOM(bool privateBrowsingEnabled, const KURL& firstParty, const KURL& url, const String& cookieString)
{
- // FIXME (NetworkProcess): Use a correct storage session.
- WebCore::setCookiesFromDOM(RemoteNetworkingContext::create(false, false).get(), firstParty, url, cookieString);
+ WebCore::setCookiesFromDOM(storageSession(privateBrowsingEnabled), firstParty, url, cookieString);
}
-void NetworkConnectionToWebProcess::cookiesEnabled(const KURL& firstParty, const KURL& url, bool& result)
+void NetworkConnectionToWebProcess::cookiesEnabled(bool privateBrowsingEnabled, const KURL& firstParty, const KURL& url, bool& result)
{
- // FIXME (NetworkProcess): Use a correct storage session.
- result = WebCore::cookiesEnabled(RemoteNetworkingContext::create(false, false).get(), firstParty, url);
+ result = WebCore::cookiesEnabled(storageSession(privateBrowsingEnabled), firstParty, url);
}
-void NetworkConnectionToWebProcess::cookieRequestHeaderFieldValue(const KURL& firstParty, const KURL& url, String& result)
+void NetworkConnectionToWebProcess::cookieRequestHeaderFieldValue(bool privateBrowsingEnabled, const KURL& firstParty, const KURL& url, String& result)
{
- // FIXME (NetworkProcess): Use a correct storage session.
- result = WebCore::cookieRequestHeaderFieldValue(0, firstParty, url);
+ result = WebCore::cookieRequestHeaderFieldValue(storageSession(privateBrowsingEnabled), firstParty, url);
}
-void NetworkConnectionToWebProcess::getRawCookies(const KURL& firstParty, const KURL& url, Vector<Cookie>& result)
+void NetworkConnectionToWebProcess::getRawCookies(bool privateBrowsingEnabled, const KURL& firstParty, const KURL& url, Vector<Cookie>& result)
{
- // FIXME (NetworkProcess): Use a correct storage session.
- WebCore::getRawCookies(RemoteNetworkingContext::create(false, false).get(), firstParty, url, result);
+ WebCore::getRawCookies(storageSession(privateBrowsingEnabled), firstParty, url, result);
}
-void NetworkConnectionToWebProcess::deleteCookie(const KURL& url, const String& cookieName)
+void NetworkConnectionToWebProcess::deleteCookie(bool privateBrowsingEnabled, const KURL& url, const String& cookieName)
{
- // FIXME (NetworkProcess): Use a correct storage session.
- WebCore::deleteCookie(RemoteNetworkingContext::create(false, false).get(), url, cookieName);
+ WebCore::deleteCookie(storageSession(privateBrowsingEnabled), url, cookieName);
}
-void NetworkConnectionToWebProcess::getHostnamesWithCookies(Vector<String>& hostnames)
+void NetworkConnectionToWebProcess::registerBlobURL(const KURL& url, const BlobRegistrationData& data)
{
- // FIXME (NetworkProcess): Use a correct storage session.
- HashSet<String> hostnamesSet;
- WebCore::getHostnamesWithCookies(RemoteNetworkingContext::create(false, false).get(), hostnamesSet);
- WTF::copyToVector(hostnamesSet, hostnames);
+ Vector<RefPtr<SandboxExtension>> extensions;
+ for (size_t i = 0, count = data.sandboxExtensions().size(); i < count; ++i) {
+ if (RefPtr<SandboxExtension> extension = SandboxExtension::create(data.sandboxExtensions()[i]))
+ extensions.append(extension);
+ }
+
+ NetworkBlobRegistry::shared().registerBlobURL(this, url, data.releaseData(), extensions);
}
-void NetworkConnectionToWebProcess::deleteCookiesForHostname(const String& hostname)
+void NetworkConnectionToWebProcess::registerBlobURLFromURL(const KURL& url, const KURL& srcURL)
{
- // FIXME (NetworkProcess): Use a correct storage session.
- WebCore::deleteCookiesForHostname(RemoteNetworkingContext::create(false, false).get(), hostname);
+ NetworkBlobRegistry::shared().registerBlobURL(this, url, srcURL);
}
-void NetworkConnectionToWebProcess::deleteAllCookies()
+void NetworkConnectionToWebProcess::unregisterBlobURL(const KURL& url)
{
- // FIXME (NetworkProcess): Use a correct storage session.
- WebCore::deleteAllCookies(RemoteNetworkingContext::create(false, false).get());
+ NetworkBlobRegistry::shared().unregisterBlobURL(this, url);
}
} // namespace WebKit
diff --git a/Source/WebKit2/NetworkProcess/NetworkConnectionToWebProcess.h b/Source/WebKit2/NetworkProcess/NetworkConnectionToWebProcess.h
index 042a7dd00..e63215812 100644
--- a/Source/WebKit2/NetworkProcess/NetworkConnectionToWebProcess.h
+++ b/Source/WebKit2/NetworkProcess/NetworkConnectionToWebProcess.h
@@ -28,6 +28,7 @@
#if ENABLE(NETWORK_PROCESS)
+#include "BlockingResponseMap.h"
#include "Connection.h"
#include "NetworkConnectionToWebProcessMessages.h"
#include <WebCore/ResourceLoadPriority.h>
@@ -40,24 +41,18 @@ class ResourceRequest;
namespace WebKit {
+class BlobRegistrationData;
class NetworkConnectionToWebProcess;
+class NetworkResourceLoader;
+class SyncNetworkResourceLoader;
typedef uint64_t ResourceLoadIdentifier;
-class NetworkConnectionToWebProcessObserver {
-public:
- virtual ~NetworkConnectionToWebProcessObserver() { }
- virtual void connectionToWebProcessDidClose(NetworkConnectionToWebProcess*) = 0;
-};
-
class NetworkConnectionToWebProcess : public RefCounted<NetworkConnectionToWebProcess>, CoreIPC::Connection::Client {
public:
static PassRefPtr<NetworkConnectionToWebProcess> create(CoreIPC::Connection::Identifier);
virtual ~NetworkConnectionToWebProcess();
CoreIPC::Connection* connection() const { return m_connection.get(); }
-
- void registerObserver(NetworkConnectionToWebProcessObserver*);
- void unregisterObserver(NetworkConnectionToWebProcessObserver*);
bool isSerialLoadingEnabled() const { return m_serialLoadingEnabled; }
@@ -65,37 +60,41 @@ private:
NetworkConnectionToWebProcess(CoreIPC::Connection::Identifier);
// CoreIPC::Connection::Client
- virtual void didReceiveMessage(CoreIPC::Connection*, CoreIPC::MessageID, CoreIPC::MessageDecoder&);
- virtual void didReceiveSyncMessage(CoreIPC::Connection*, CoreIPC::MessageID, CoreIPC::MessageDecoder&, OwnPtr<CoreIPC::MessageEncoder>&);
+ virtual void didReceiveMessage(CoreIPC::Connection*, CoreIPC::MessageDecoder&);
+ virtual void didReceiveSyncMessage(CoreIPC::Connection*, CoreIPC::MessageDecoder&, OwnPtr<CoreIPC::MessageEncoder>&);
virtual void didClose(CoreIPC::Connection*);
virtual void didReceiveInvalidMessage(CoreIPC::Connection*, CoreIPC::StringReference messageReceiverName, CoreIPC::StringReference messageName);
// Message handlers.
- void didReceiveNetworkConnectionToWebProcessMessage(CoreIPC::Connection*, CoreIPC::MessageID, CoreIPC::MessageDecoder&);
- void didReceiveSyncNetworkConnectionToWebProcessMessage(CoreIPC::Connection*, CoreIPC::MessageID, CoreIPC::MessageDecoder&, OwnPtr<CoreIPC::MessageEncoder>&);
+ void didReceiveNetworkConnectionToWebProcessMessage(CoreIPC::Connection*, CoreIPC::MessageDecoder&);
+ void didReceiveSyncNetworkConnectionToWebProcessMessage(CoreIPC::Connection*, CoreIPC::MessageDecoder&, OwnPtr<CoreIPC::MessageEncoder>&);
- void scheduleResourceLoad(const NetworkResourceLoadParameters&, ResourceLoadIdentifier&);
- void addLoadInProgress(const WebCore::KURL&, ResourceLoadIdentifier&);
+ void scheduleResourceLoad(const NetworkResourceLoadParameters&);
+ void performSynchronousLoad(const NetworkResourceLoadParameters&, PassRefPtr<Messages::NetworkConnectionToWebProcess::PerformSynchronousLoad::DelayedReply>);
+
void removeLoadIdentifier(ResourceLoadIdentifier);
void crossOriginRedirectReceived(ResourceLoadIdentifier, const WebCore::KURL& redirectURL);
void servePendingRequests(uint32_t resourceLoadPriority);
- void suspendPendingRequests();
- void resumePendingRequests();
void setSerialLoadingEnabled(bool);
- void cookiesForDOM(const WebCore::KURL& firstParty, const WebCore::KURL&, String& result);
- void setCookiesFromDOM(const WebCore::KURL& firstParty, const WebCore::KURL&, const String&);
- void cookiesEnabled(const WebCore::KURL& firstParty, const WebCore::KURL&, bool& result);
- void cookieRequestHeaderFieldValue(const WebCore::KURL& firstParty, const WebCore::KURL&, String& result);
- void getRawCookies(const WebCore::KURL& firstParty, const WebCore::KURL&, Vector<WebCore::Cookie>&);
- void deleteCookie(const WebCore::KURL&, const String& cookieName);
- void getHostnamesWithCookies(Vector<String>& hostnames);
- void deleteCookiesForHostname(const String& hostname);
- void deleteAllCookies();
+ void startDownload(bool privateBrowsingEnabled, uint64_t downloadID, const WebCore::ResourceRequest&);
+ void convertMainResourceLoadToDownload(uint64_t mainResourceLoadIdentifier, uint64_t downloadID, const WebCore::ResourceRequest&, const WebCore::ResourceResponse&);
+
+ void cookiesForDOM(bool privateBrowsingEnabled, const WebCore::KURL& firstParty, const WebCore::KURL&, String& result);
+ void setCookiesFromDOM(bool privateBrowsingEnabled, const WebCore::KURL& firstParty, const WebCore::KURL&, const String&);
+ void cookiesEnabled(bool privateBrowsingEnabled, const WebCore::KURL& firstParty, const WebCore::KURL&, bool& result);
+ void cookieRequestHeaderFieldValue(bool privateBrowsingEnabled, const WebCore::KURL& firstParty, const WebCore::KURL&, String& result);
+ void getRawCookies(bool privateBrowsingEnabled, const WebCore::KURL& firstParty, const WebCore::KURL&, Vector<WebCore::Cookie>&);
+ void deleteCookie(bool privateBrowsingEnabled, const WebCore::KURL&, const String& cookieName);
+
+ void registerBlobURL(const WebCore::KURL&, const BlobRegistrationData&);
+ void registerBlobURLFromURL(const WebCore::KURL&, const WebCore::KURL& srcURL);
+ void unregisterBlobURL(const WebCore::KURL&);
RefPtr<CoreIPC::Connection> m_connection;
-
- HashSet<NetworkConnectionToWebProcessObserver*> m_observers;
-
+
+ HashMap<ResourceLoadIdentifier, RefPtr<NetworkResourceLoader>> m_networkResourceLoaders;
+ HashMap<ResourceLoadIdentifier, RefPtr<SyncNetworkResourceLoader>> m_syncNetworkResourceLoaders;
+
bool m_serialLoadingEnabled;
};
diff --git a/Source/WebKit2/NetworkProcess/NetworkConnectionToWebProcess.messages.in b/Source/WebKit2/NetworkProcess/NetworkConnectionToWebProcess.messages.in
index d6c5f65b8..afae1a230 100644
--- a/Source/WebKit2/NetworkProcess/NetworkConnectionToWebProcess.messages.in
+++ b/Source/WebKit2/NetworkProcess/NetworkConnectionToWebProcess.messages.in
@@ -22,32 +22,29 @@
#if ENABLE(NETWORK_PROCESS)
-messages -> NetworkConnectionToWebProcess {
+messages -> NetworkConnectionToWebProcess LegacyReceiver {
- // FIXME (NetworkProcess): At least some of these synchronous messages are synchronous due to the requirement
- // that we synchronously get an identifier for new ResourceLoaders as they are created.
- // There's possible ResourceLoader identifier refactoring that can remove that requirement.
- // We might also have the NetworkProcess divvy up identifiers in blocks to each WebProcess beforehand.
- ScheduleResourceLoad(WebKit::NetworkResourceLoadParameters resourceLoadParameters) -> (uint64_t resourceLoadIdentifier)
- AddLoadInProgress(WebCore::KURL url) -> (uint64_t resourceLoadIdentifier)
+ ScheduleResourceLoad(WebKit::NetworkResourceLoadParameters resourceLoadParameters)
+ PerformSynchronousLoad(WebKit::NetworkResourceLoadParameters resourceLoadParameters) -> (WebCore::ResourceError error, WebCore::ResourceResponse response, CoreIPC::DataReference data) Delayed
RemoveLoadIdentifier(uint64_t resourceLoadIdentifier)
ServePendingRequests(uint32_t resourceLoadPriority)
-
- SuspendPendingRequests() -> ()
- ResumePendingRequests() -> ()
SetSerialLoadingEnabled(bool enabled) -> ()
- CookiesForDOM(WebCore::KURL firstParty, WebCore::KURL url) -> (WTF::String result)
- SetCookiesFromDOM(WebCore::KURL firstParty, WebCore::KURL url, WTF::String cookieString)
- CookiesEnabled(WebCore::KURL firstParty, WebCore::KURL url) -> (bool enabled)
- CookieRequestHeaderFieldValue(WebCore::KURL firstParty, WebCore::KURL url) -> (WTF::String result)
- GetRawCookies(WebCore::KURL firstParty, WebCore::KURL url) -> (WTF::Vector<WebCore::Cookie> cookies)
- DeleteCookie(WebCore::KURL url, WTF::String cookieName)
- GetHostnamesWithCookies() -> (WTF::Vector<WTF::String> hostnames)
- DeleteCookiesForHostname(WTF::String hostname)
- DeleteAllCookies()
+ StartDownload(bool privateBrowsingEnabled, uint64_t downloadID, WebCore::ResourceRequest request)
+ ConvertMainResourceLoadToDownload(uint64_t mainResourceLoadIdentifier, uint64_t downloadID, WebCore::ResourceRequest request, WebCore::ResourceResponse response)
+
+ CookiesForDOM(bool privateBrowsingEnabled, WebCore::KURL firstParty, WebCore::KURL url) -> (WTF::String result)
+ SetCookiesFromDOM(bool privateBrowsingEnabled, WebCore::KURL firstParty, WebCore::KURL url, WTF::String cookieString)
+ CookiesEnabled(bool privateBrowsingEnabled, WebCore::KURL firstParty, WebCore::KURL url) -> (bool enabled)
+ CookieRequestHeaderFieldValue(bool privateBrowsingEnabled, WebCore::KURL firstParty, WebCore::KURL url) -> (WTF::String result)
+ GetRawCookies(bool privateBrowsingEnabled, WebCore::KURL firstParty, WebCore::KURL url) -> (WTF::Vector<WebCore::Cookie> cookies)
+ DeleteCookie(bool privateBrowsingEnabled, WebCore::KURL url, WTF::String cookieName)
+
+ RegisterBlobURL(WebCore::KURL url, WebKit::BlobRegistrationData data)
+ RegisterBlobURLFromURL(WebCore::KURL url, WebCore::KURL srcURL)
+ UnregisterBlobURL(WebCore::KURL url)
}
#endif // ENABLE(NETWORK_PROCESS)
diff --git a/Source/WebKit2/NetworkProcess/NetworkProcess.cpp b/Source/WebKit2/NetworkProcess/NetworkProcess.cpp
index 634333559..917ddc5c1 100644
--- a/Source/WebKit2/NetworkProcess/NetworkProcess.cpp
+++ b/Source/WebKit2/NetworkProcess/NetworkProcess.cpp
@@ -30,12 +30,27 @@
#include "ArgumentCoders.h"
#include "Attachment.h"
+#include "AuthenticationManager.h"
+#include "CustomProtocolManager.h"
+#include "Logging.h"
#include "NetworkConnectionToWebProcess.h"
+#include "NetworkProcessCreationParameters.h"
+#include "NetworkProcessPlatformStrategies.h"
#include "NetworkProcessProxyMessages.h"
+#include "RemoteNetworkingContext.h"
+#include "SchedulableLoader.h"
+#include "StatisticsData.h"
+#include "WebContextMessages.h"
+#include "WebCookieManager.h"
+#include <WebCore/InitializeLogging.h>
#include <WebCore/ResourceRequest.h>
#include <WebCore/RunLoop.h>
#include <wtf/text/CString.h>
+#if USE(SECURITY_FRAMEWORK)
+#include "SecItemShim.h"
+#endif
+
using namespace WebCore;
namespace WebKit {
@@ -47,20 +62,32 @@ NetworkProcess& NetworkProcess::shared()
}
NetworkProcess::NetworkProcess()
+ : m_hasSetCacheModel(false)
+ , m_cacheModel(CacheModelDocumentViewer)
+#if PLATFORM(MAC)
+ , m_clearCacheDispatchGroup(0)
+#endif
{
+ NetworkProcessPlatformStrategies::initialize();
+
+ addSupplement<AuthenticationManager>();
+ addSupplement<WebCookieManager>();
+ addSupplement<CustomProtocolManager>();
}
NetworkProcess::~NetworkProcess()
{
}
-void NetworkProcess::initialize(CoreIPC::Connection::Identifier serverIdentifier, WebCore::RunLoop* runLoop)
+AuthenticationManager& NetworkProcess::authenticationManager()
{
- ASSERT(!m_uiConnection);
+ return *supplement<AuthenticationManager>();
+}
- m_uiConnection = CoreIPC::Connection::createClientConnection(serverIdentifier, this, runLoop);
- m_uiConnection->setDidCloseOnConnectionWorkQueueCallback(didCloseOnConnectionWorkQueue);
- m_uiConnection->open();
+DownloadManager& NetworkProcess::downloadManager()
+{
+ DEFINE_STATIC_LOCAL(DownloadManager, downloadManager, (this));
+ return downloadManager;
}
void NetworkProcess::removeNetworkConnectionToWebProcess(NetworkConnectionToWebProcess* connection)
@@ -73,17 +100,26 @@ void NetworkProcess::removeNetworkConnectionToWebProcess(NetworkConnectionToWebP
bool NetworkProcess::shouldTerminate()
{
- return true;
+ // Network process keeps session cookies and credentials, so it should never terminate (as long as UI process connection is alive).
+ return false;
}
-void NetworkProcess::didReceiveMessage(CoreIPC::Connection* connection, CoreIPC::MessageID messageID, CoreIPC::MessageDecoder& decoder)
+void NetworkProcess::didReceiveMessage(CoreIPC::Connection* connection, CoreIPC::MessageDecoder& decoder)
{
- didReceiveNetworkProcessMessage(connection, messageID, decoder);
+ if (messageReceiverMap().dispatchMessage(connection, decoder))
+ return;
+
+ didReceiveNetworkProcessMessage(connection, decoder);
+}
+
+void NetworkProcess::didReceiveSyncMessage(CoreIPC::Connection* connection, CoreIPC::MessageDecoder& decoder, OwnPtr<CoreIPC::MessageEncoder>& replyEncoder)
+{
+ messageReceiverMap().dispatchSyncMessage(connection, decoder, replyEncoder);
}
void NetworkProcess::didClose(CoreIPC::Connection*)
{
- // The UIProcess just crashed.
+ // The UIProcess just exited.
RunLoop::current()->stop();
}
@@ -92,13 +128,57 @@ void NetworkProcess::didReceiveInvalidMessage(CoreIPC::Connection*, CoreIPC::Str
RunLoop::current()->stop();
}
-void NetworkProcess::syncMessageSendTimedOut(CoreIPC::Connection*)
+void NetworkProcess::didCreateDownload()
+{
+ disableTermination();
+}
+
+void NetworkProcess::didDestroyDownload()
+{
+ enableTermination();
+}
+
+CoreIPC::Connection* NetworkProcess::downloadProxyConnection()
{
+ return parentProcessConnection();
+}
+
+AuthenticationManager& NetworkProcess::downloadsAuthenticationManager()
+{
+ return authenticationManager();
}
void NetworkProcess::initializeNetworkProcess(const NetworkProcessCreationParameters& parameters)
{
- platformInitialize(parameters);
+ platformInitializeNetworkProcess(parameters);
+
+ setCacheModel(static_cast<uint32_t>(parameters.cacheModel));
+
+#if PLATFORM(MAC) || USE(CFNETWORK)
+ RemoteNetworkingContext::setPrivateBrowsingStorageSessionIdentifierBase(parameters.uiProcessBundleIdentifier);
+#endif
+
+ if (parameters.privateBrowsingEnabled)
+ RemoteNetworkingContext::ensurePrivateBrowsingSession();
+
+ NetworkProcessSupplementMap::const_iterator it = m_supplements.begin();
+ NetworkProcessSupplementMap::const_iterator end = m_supplements.end();
+ for (; it != end; ++it)
+ it->value->initialize(parameters);
+}
+
+void NetworkProcess::initializeConnection(CoreIPC::Connection* connection)
+{
+ ChildProcess::initializeConnection(connection);
+
+#if USE(SECURITY_FRAMEWORK)
+ SecItemShim::shared().initializeConnection(connection);
+#endif
+
+ NetworkProcessSupplementMap::const_iterator it = m_supplements.begin();
+ NetworkProcessSupplementMap::const_iterator end = m_supplements.end();
+ for (; it != end; ++it)
+ it->value->initializeConnection(connection);
}
void NetworkProcess::createNetworkConnectionToWebProcess()
@@ -113,12 +193,79 @@ void NetworkProcess::createNetworkConnectionToWebProcess()
m_webProcessConnections.append(connection.release());
CoreIPC::Attachment clientPort(listeningPort, MACH_MSG_TYPE_MAKE_SEND);
- m_uiConnection->send(Messages::NetworkProcessProxy::DidCreateNetworkConnectionToWebProcess(clientPort), 0);
+ parentProcessConnection()->send(Messages::NetworkProcessProxy::DidCreateNetworkConnectionToWebProcess(clientPort), 0);
#else
notImplemented();
#endif
}
+void NetworkProcess::ensurePrivateBrowsingSession()
+{
+ RemoteNetworkingContext::ensurePrivateBrowsingSession();
+}
+
+void NetworkProcess::destroyPrivateBrowsingSession()
+{
+ RemoteNetworkingContext::destroyPrivateBrowsingSession();
+}
+
+void NetworkProcess::downloadRequest(uint64_t downloadID, const ResourceRequest& request)
+{
+ downloadManager().startDownload(downloadID, request);
+}
+
+void NetworkProcess::cancelDownload(uint64_t downloadID)
+{
+ downloadManager().cancelDownload(downloadID);
+}
+
+void NetworkProcess::setCacheModel(uint32_t cm)
+{
+ CacheModel cacheModel = static_cast<CacheModel>(cm);
+
+ if (!m_hasSetCacheModel || cacheModel != m_cacheModel) {
+ m_hasSetCacheModel = true;
+ m_cacheModel = cacheModel;
+ platformSetCacheModel(cacheModel);
+ }
+}
+
+void NetworkProcess::getNetworkProcessStatistics(uint64_t callbackID)
+{
+ NetworkResourceLoadScheduler& scheduler = NetworkProcess::shared().networkResourceLoadScheduler();
+
+ StatisticsData data;
+
+ data.statisticsNumbers.set("HostsPendingCount", scheduler.hostsPendingCount());
+ data.statisticsNumbers.set("HostsActiveCount", scheduler.hostsActiveCount());
+ data.statisticsNumbers.set("LoadsPendingCount", scheduler.loadsPendingCount());
+ data.statisticsNumbers.set("LoadsActiveCount", scheduler.loadsActiveCount());
+ data.statisticsNumbers.set("DownloadsActiveCount", shared().downloadManager().activeDownloadCount());
+ data.statisticsNumbers.set("OutstandingAuthenticationChallengesCount", shared().authenticationManager().outstandingAuthenticationChallengeCount());
+
+ parentProcessConnection()->send(Messages::WebContext::DidGetStatistics(data, callbackID), 0);
+}
+
+void NetworkProcess::terminate()
+{
+ platformTerminate();
+ ChildProcess::terminate();
+}
+
+#if !PLATFORM(MAC)
+void NetworkProcess::initializeProcess(const ChildProcessInitializationParameters&)
+{
+}
+
+void NetworkProcess::initializeProcessName(const ChildProcessInitializationParameters&)
+{
+}
+
+void NetworkProcess::initializeSandbox(const ChildProcessInitializationParameters&, SandboxInitializationParameters&)
+{
+}
+#endif
+
} // namespace WebKit
#endif // ENABLE(NETWORK_PROCESS)
diff --git a/Source/WebKit2/NetworkProcess/NetworkProcess.h b/Source/WebKit2/NetworkProcess/NetworkProcess.h
index 66a1185e9..00f4068cf 100644
--- a/Source/WebKit2/NetworkProcess/NetworkProcess.h
+++ b/Source/WebKit2/NetworkProcess/NetworkProcess.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2012 Apple Inc. All rights reserved.
+ * Copyright (C) 2012, 2013 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -28,7 +28,10 @@
#if ENABLE(NETWORK_PROCESS)
+#include "CacheModel.h"
#include "ChildProcess.h"
+#include "DownloadManager.h"
+#include "MessageReceiverMap.h"
#include "NetworkResourceLoadScheduler.h"
#include <wtf/Forward.h>
@@ -38,47 +41,98 @@ namespace WebCore {
namespace WebKit {
+class AuthenticationManager;
class NetworkConnectionToWebProcess;
+class NetworkProcessSupplement;
+class PlatformCertificateInfo;
struct NetworkProcessCreationParameters;
-class NetworkProcess : ChildProcess {
+class NetworkProcess : public ChildProcess, private DownloadManager::Client {
WTF_MAKE_NONCOPYABLE(NetworkProcess);
public:
static NetworkProcess& shared();
- void initialize(CoreIPC::Connection::Identifier, WebCore::RunLoop*);
+ template <typename T>
+ T* supplement()
+ {
+ return static_cast<T*>(m_supplements.get(T::supplementName()));
+ }
+
+ template <typename T>
+ void addSupplement()
+ {
+ m_supplements.add(T::supplementName(), adoptPtr<NetworkProcessSupplement>(new T(this)));
+ }
void removeNetworkConnectionToWebProcess(NetworkConnectionToWebProcess*);
NetworkResourceLoadScheduler& networkResourceLoadScheduler() { return m_networkResourceLoadScheduler; }
+ AuthenticationManager& authenticationManager();
+ DownloadManager& downloadManager();
+
private:
NetworkProcess();
~NetworkProcess();
- void platformInitialize(const NetworkProcessCreationParameters&);
+ void platformInitializeNetworkProcess(const NetworkProcessCreationParameters&);
+
+ virtual void terminate() OVERRIDE;
+ void platformTerminate();
// ChildProcess
- virtual bool shouldTerminate();
+ virtual void initializeProcess(const ChildProcessInitializationParameters&) OVERRIDE;
+ virtual void initializeProcessName(const ChildProcessInitializationParameters&) OVERRIDE;
+ virtual void initializeSandbox(const ChildProcessInitializationParameters&, SandboxInitializationParameters&) OVERRIDE;
+ virtual void initializeConnection(CoreIPC::Connection*) OVERRIDE;
+ virtual bool shouldTerminate() OVERRIDE;
// CoreIPC::Connection::Client
- virtual void didReceiveMessage(CoreIPC::Connection*, CoreIPC::MessageID, CoreIPC::MessageDecoder&);
- virtual void didClose(CoreIPC::Connection*);
- virtual void didReceiveInvalidMessage(CoreIPC::Connection*, CoreIPC::StringReference messageReceiverName, CoreIPC::StringReference messageName);
- virtual void syncMessageSendTimedOut(CoreIPC::Connection*);
+ virtual void didReceiveMessage(CoreIPC::Connection*, CoreIPC::MessageDecoder&) OVERRIDE;
+ virtual void didReceiveSyncMessage(CoreIPC::Connection*, CoreIPC::MessageDecoder&, OwnPtr<CoreIPC::MessageEncoder>&);
+ virtual void didClose(CoreIPC::Connection*) OVERRIDE;
+ virtual void didReceiveInvalidMessage(CoreIPC::Connection*, CoreIPC::StringReference messageReceiverName, CoreIPC::StringReference messageName) OVERRIDE;
+
+ // DownloadManager::Client
+ virtual void didCreateDownload() OVERRIDE;
+ virtual void didDestroyDownload() OVERRIDE;
+ virtual CoreIPC::Connection* downloadProxyConnection() OVERRIDE;
+ virtual AuthenticationManager& downloadsAuthenticationManager() OVERRIDE;
// Message Handlers
- void didReceiveNetworkProcessMessage(CoreIPC::Connection*, CoreIPC::MessageID, CoreIPC::MessageDecoder&);
+ void didReceiveNetworkProcessMessage(CoreIPC::Connection*, CoreIPC::MessageDecoder&);
void initializeNetworkProcess(const NetworkProcessCreationParameters&);
void createNetworkConnectionToWebProcess();
-
- // The connection to the UI process.
- RefPtr<CoreIPC::Connection> m_uiConnection;
+ void ensurePrivateBrowsingSession();
+ void destroyPrivateBrowsingSession();
+ void downloadRequest(uint64_t downloadID, const WebCore::ResourceRequest&);
+ void cancelDownload(uint64_t downloadID);
+ void setCacheModel(uint32_t);
+ void allowSpecificHTTPSCertificateForHost(const PlatformCertificateInfo&, const String& host);
+ void getNetworkProcessStatistics(uint64_t callbackID);
+ void clearCacheForAllOrigins(uint32_t cachesToClear);
+
+ // Platform Helpers
+ void platformSetCacheModel(CacheModel);
// Connections to WebProcesses.
- Vector<RefPtr<NetworkConnectionToWebProcess> > m_webProcessConnections;
+ Vector<RefPtr<NetworkConnectionToWebProcess>> m_webProcessConnections;
NetworkResourceLoadScheduler m_networkResourceLoadScheduler;
+
+ String m_diskCacheDirectory;
+ bool m_hasSetCacheModel;
+ CacheModel m_cacheModel;
+
+ typedef HashMap<const char*, OwnPtr<NetworkProcessSupplement>, PtrHash<const char*>> NetworkProcessSupplementMap;
+ NetworkProcessSupplementMap m_supplements;
+
+#if PLATFORM(MAC)
+ // FIXME: We'd like to be able to do this without the #ifdef, but WorkQueue + BinarySemaphore isn't good enough since
+ // multiple requests to clear the cache can come in before previous requests complete, and we need to wait for all of them.
+ // In the future using WorkQueue and a counting semaphore would work, as would WorkQueue supporting the libdispatch concept of "work groups".
+ dispatch_group_t m_clearCacheDispatchGroup;
+#endif
};
} // namespace WebKit
diff --git a/Source/WebKit2/NetworkProcess/NetworkProcess.messages.in b/Source/WebKit2/NetworkProcess/NetworkProcess.messages.in
index d243bd44f..a5fcbc7be 100644
--- a/Source/WebKit2/NetworkProcess/NetworkProcess.messages.in
+++ b/Source/WebKit2/NetworkProcess/NetworkProcess.messages.in
@@ -22,16 +22,28 @@
#if ENABLE(NETWORK_PROCESS)
-messages -> NetworkProcess {
+messages -> NetworkProcess LegacyReceiver {
# Initializes the network process.
InitializeNetworkProcess(WebKit::NetworkProcessCreationParameters processCreationParameters)
# Creates a connection for communication with a WebProcess
CreateNetworkConnectionToWebProcess()
+ EnsurePrivateBrowsingSession()
+ DestroyPrivateBrowsingSession()
+
+ DownloadRequest(uint64_t downloadID, WebCore::ResourceRequest request)
+ CancelDownload(uint64_t downloadID)
+
#if PLATFORM(MAC)
- SetApplicationIsOccluded(bool flag)
+ SetProcessSuppressionEnabled(bool flag)
#endif
+
+ AllowSpecificHTTPSCertificateForHost(WebKit::PlatformCertificateInfo certificate, WTF::String host)
+
+ GetNetworkProcessStatistics(uint64_t callbackID)
+
+ ClearCacheForAllOrigins(uint32_t cachesToClear)
}
#endif // ENABLE(NETWORK_PROCESS)
diff --git a/Source/WebKit2/NetworkProcess/NetworkProcessPlatformStrategies.cpp b/Source/WebKit2/NetworkProcess/NetworkProcessPlatformStrategies.cpp
new file mode 100644
index 000000000..dcf758877
--- /dev/null
+++ b/Source/WebKit2/NetworkProcess/NetworkProcessPlatformStrategies.cpp
@@ -0,0 +1,101 @@
+/*
+ * Copyright (C) 2013 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 "NetworkProcessPlatformStrategies.h"
+
+#include <WebCore/BlobRegistryImpl.h>
+
+using namespace WebCore;
+
+namespace WebKit {
+
+void NetworkProcessPlatformStrategies::initialize()
+{
+ DEFINE_STATIC_LOCAL(NetworkProcessPlatformStrategies, platformStrategies, ());
+ setPlatformStrategies(&platformStrategies);
+}
+
+CookiesStrategy* NetworkProcessPlatformStrategies::createCookiesStrategy()
+{
+ return 0;
+}
+
+DatabaseStrategy* NetworkProcessPlatformStrategies::createDatabaseStrategy()
+{
+ return 0;
+}
+
+LoaderStrategy* NetworkProcessPlatformStrategies::createLoaderStrategy()
+{
+ return this;
+}
+
+PasteboardStrategy* NetworkProcessPlatformStrategies::createPasteboardStrategy()
+{
+ return 0;
+}
+
+PluginStrategy* NetworkProcessPlatformStrategies::createPluginStrategy()
+{
+ return 0;
+}
+
+SharedWorkerStrategy* NetworkProcessPlatformStrategies::createSharedWorkerStrategy()
+{
+ return 0;
+}
+
+StorageStrategy* NetworkProcessPlatformStrategies::createStorageStrategy()
+{
+ return 0;
+}
+
+VisitedLinkStrategy* NetworkProcessPlatformStrategies::createVisitedLinkStrategy()
+{
+ return 0;
+}
+
+ResourceLoadScheduler* NetworkProcessPlatformStrategies::resourceLoadScheduler()
+{
+ ASSERT_NOT_REACHED();
+ return 0;
+}
+
+void NetworkProcessPlatformStrategies::loadResourceSynchronously(NetworkingContext*, unsigned long resourceLoadIdentifier, const ResourceRequest&, StoredCredentials, ClientCredentialPolicy, ResourceError&, ResourceResponse&, Vector<char>& data)
+{
+ ASSERT_NOT_REACHED();
+}
+
+#if ENABLE(BLOB)
+BlobRegistry* NetworkProcessPlatformStrategies::createBlobRegistry()
+{
+ return new BlobRegistryImpl;
+}
+
+#endif
+
+
+}
diff --git a/Source/WebKit2/NetworkProcess/NetworkProcessPlatformStrategies.h b/Source/WebKit2/NetworkProcess/NetworkProcessPlatformStrategies.h
new file mode 100644
index 000000000..818ccebb1
--- /dev/null
+++ b/Source/WebKit2/NetworkProcess/NetworkProcessPlatformStrategies.h
@@ -0,0 +1,60 @@
+/*
+ * Copyright (C) 2013 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 NetworkProcessPlatformStrategies_h
+#define NetworkProcessPlatformStrategies_h
+
+#include <WebCore/LoaderStrategy.h>
+#include <WebCore/PlatformStrategies.h>
+
+namespace WebKit {
+
+class NetworkProcessPlatformStrategies : public WebCore::PlatformStrategies, private WebCore::LoaderStrategy {
+public:
+ static void initialize();
+
+private:
+ // WebCore::PlatformStrategies
+ virtual WebCore::CookiesStrategy* createCookiesStrategy() OVERRIDE;
+ virtual WebCore::DatabaseStrategy* createDatabaseStrategy() OVERRIDE;
+ virtual WebCore::LoaderStrategy* createLoaderStrategy() OVERRIDE;
+ virtual WebCore::PasteboardStrategy* createPasteboardStrategy() OVERRIDE;
+ virtual WebCore::PluginStrategy* createPluginStrategy() OVERRIDE;
+ virtual WebCore::SharedWorkerStrategy* createSharedWorkerStrategy() OVERRIDE;
+ virtual WebCore::StorageStrategy* createStorageStrategy() OVERRIDE;
+ virtual WebCore::VisitedLinkStrategy* createVisitedLinkStrategy() OVERRIDE;
+
+ // WebCore::LoaderStrategy
+ virtual WebCore::ResourceLoadScheduler* resourceLoadScheduler() OVERRIDE;
+ virtual void loadResourceSynchronously(WebCore::NetworkingContext*, unsigned long resourceLoadIdentifier, const WebCore::ResourceRequest&, WebCore::StoredCredentials, WebCore::ClientCredentialPolicy, WebCore::ResourceError&, WebCore::ResourceResponse&, Vector<char>& data) OVERRIDE;
+#if ENABLE(BLOB)
+ virtual WebCore::BlobRegistry* createBlobRegistry() OVERRIDE;
+#endif
+};
+
+} // namespace WebKit
+
+
+#endif // NetworkProcessPlatformStrategies_h
diff --git a/Source/WebKit2/NetworkProcess/NetworkResourceLoadScheduler.cpp b/Source/WebKit2/NetworkProcess/NetworkResourceLoadScheduler.cpp
index 8a5d7a139..9aebcc699 100644
--- a/Source/WebKit2/NetworkProcess/NetworkResourceLoadScheduler.cpp
+++ b/Source/WebKit2/NetworkProcess/NetworkResourceLoadScheduler.cpp
@@ -3,10 +3,10 @@
#include "HostRecord.h"
#include "Logging.h"
-#include "NetworkConnectionToWebProcess.h"
-#include "NetworkProcessconnectionMessages.h"
+#include "NetworkProcess.h"
#include "NetworkResourceLoadParameters.h"
#include "NetworkResourceLoader.h"
+#include "SyncNetworkResourceLoader.h"
#include <wtf/MainThread.h>
#include <wtf/text/CString.h>
@@ -17,15 +17,13 @@ using namespace WebCore;
namespace WebKit {
static const unsigned maxRequestsInFlightForNonHTTPProtocols = 20;
-static unsigned maxRequestsInFlightPerHost;
-static ResourceLoadIdentifier s_currentResourceLoadIdentifier;
NetworkResourceLoadScheduler::NetworkResourceLoadScheduler()
- : m_nonHTTPProtocolHost(new HostRecord(String(), maxRequestsInFlightForNonHTTPProtocols))
+ : m_nonHTTPProtocolHost(HostRecord::create(String(), maxRequestsInFlightForNonHTTPProtocols))
, m_requestTimer(this, &NetworkResourceLoadScheduler::requestTimerFired)
{
- maxRequestsInFlightPerHost = platformInitializeMaximumHTTPConnectionCountPerHost();
+ platformInitializeMaximumHTTPConnectionCountPerHost();
}
void NetworkResourceLoadScheduler::scheduleServePendingRequests()
@@ -39,223 +37,190 @@ void NetworkResourceLoadScheduler::requestTimerFired(WebCore::Timer<NetworkResou
servePendingRequests();
}
-ResourceLoadIdentifier NetworkResourceLoadScheduler::scheduleResourceLoad(const NetworkResourceLoadParameters& loadParameters, NetworkConnectionToWebProcess* connection)
+void NetworkResourceLoadScheduler::scheduleLoader(PassRefPtr<SchedulableLoader> loader)
{
- ResourceLoadPriority priority = loadParameters.priority();
- const ResourceRequest& resourceRequest = loadParameters.request();
-
- ResourceLoadIdentifier identifier = ++s_currentResourceLoadIdentifier;
- RefPtr<NetworkResourceLoader> loader = NetworkResourceLoader::create(loadParameters, identifier, connection);
-
- m_resourceLoaders.add(identifier, loader);
-
- LOG(NetworkScheduling, "(NetworkProcess) NetworkResourceLoadScheduler::scheduleNetworkResourceRequest resource %llu '%s'", identifier, resourceRequest.url().string().utf8().data());
+ ResourceLoadPriority priority = loader->priority();
+ const ResourceRequest& resourceRequest = loader->request();
+
+ LOG(NetworkScheduling, "(NetworkProcess) NetworkResourceLoadScheduler::scheduleLoader resource '%s'", resourceRequest.url().string().utf8().data());
HostRecord* host = hostForURL(resourceRequest.url(), CreateIfNotFound);
bool hadRequests = host->hasRequests();
- host->schedule(loader);
- m_identifiers.add(identifier, host);
+ host->scheduleResourceLoader(loader);
if (priority > ResourceLoadPriorityLow || !resourceRequest.url().protocolIsInHTTPFamily() || (priority == ResourceLoadPriorityLow && !hadRequests)) {
// Try to request important resources immediately.
- servePendingRequestsForHost(host, priority);
- return identifier;
+ host->servePendingRequests(priority);
+ return;
}
// Handle asynchronously so early low priority requests don't get scheduled before later high priority ones.
scheduleServePendingRequests();
- return identifier;
-}
-
-ResourceLoadIdentifier NetworkResourceLoadScheduler::addLoadInProgress(const WebCore::KURL& url)
-{
- ResourceLoadIdentifier identifier = ++s_currentResourceLoadIdentifier;
-
- LOG(NetworkScheduling, "(NetworkProcess) NetworkResourceLoadScheduler::addLoadInProgress resource %llu with url '%s'", identifier, url.string().utf8().data());
-
- HostRecord* host = hostForURL(url, CreateIfNotFound);
- host->addLoadInProgress(identifier);
- m_identifiers.add(identifier, host);
-
- return identifier;
}
HostRecord* NetworkResourceLoadScheduler::hostForURL(const WebCore::KURL& url, CreateHostPolicy createHostPolicy)
{
if (!url.protocolIsInHTTPFamily())
- return m_nonHTTPProtocolHost;
+ return m_nonHTTPProtocolHost.get();
m_hosts.checkConsistency();
String hostName = url.host();
HostRecord* host = m_hosts.get(hostName);
if (!host && createHostPolicy == CreateIfNotFound) {
- host = new HostRecord(hostName, maxRequestsInFlightPerHost);
- m_hosts.add(hostName, host);
+ RefPtr<HostRecord> newHost = HostRecord::create(hostName, m_maxRequestsInFlightPerHost);
+ host = newHost.get();
+ m_hosts.add(hostName, newHost.release());
}
return host;
}
-void NetworkResourceLoadScheduler::removeLoadIdentifier(ResourceLoadIdentifier identifier)
+void NetworkResourceLoadScheduler::removeLoader(SchedulableLoader* loader)
{
ASSERT(isMainThread());
- ASSERT(identifier);
+ ASSERT(loader);
- LOG(NetworkScheduling, "(NetworkProcess) NetworkResourceLoadScheduler::removeLoadIdentifier removing load identifier %llu", identifier);
+ LOG(NetworkScheduling, "(NetworkProcess) NetworkResourceLoadScheduler::removeLoadIdentifier removing loader %s", loader->request().url().string().utf8().data());
- HostRecord* host = m_identifiers.take(identifier);
+ HostRecord* host = loader->hostRecord();
// Due to a race condition the WebProcess might have messaged the NetworkProcess to remove this identifier
// after the NetworkProcess has already removed it internally.
// In this situation we might not have a HostRecord to clean up.
if (host)
- host->remove(identifier);
-
- m_resourceLoaders.remove(identifier);
+ host->removeLoader(loader);
scheduleServePendingRequests();
}
-NetworkResourceLoader* NetworkResourceLoadScheduler::networkResourceLoaderForIdentifier(ResourceLoadIdentifier identifier)
-{
- ASSERT(m_resourceLoaders.get(identifier));
- return m_resourceLoaders.get(identifier).get();
-}
-
-void NetworkResourceLoadScheduler::receivedRedirect(ResourceLoadIdentifier identifier, const WebCore::KURL& redirectURL)
+void NetworkResourceLoadScheduler::receivedRedirect(SchedulableLoader* loader, const WebCore::KURL& redirectURL)
{
ASSERT(isMainThread());
- LOG(NetworkScheduling, "(NetworkProcess) NetworkResourceLoadScheduler::receivedRedirect resource %llu redirected to '%s'", identifier, redirectURL.string().utf8().data());
+ LOG(NetworkScheduling, "(NetworkProcess) NetworkResourceLoadScheduler::receivedRedirect loader originally for '%s' redirected to '%s'", loader->request().url().string().utf8().data(), redirectURL.string().utf8().data());
+
+ HostRecord* oldHost = loader->hostRecord();
+
+ // The load may have been cancelled while the message was in flight from network thread to main thread.
+ if (!oldHost)
+ return;
- HostRecord* oldHost = m_identifiers.get(identifier);
HostRecord* newHost = hostForURL(redirectURL, CreateIfNotFound);
- ASSERT(oldHost);
if (oldHost->name() == newHost->name())
return;
-
- newHost->addLoadInProgress(identifier);
- m_identifiers.set(identifier, newHost);
- oldHost->remove(identifier);
+ oldHost->removeLoader(loader);
+ newHost->addLoaderInProgress(loader);
}
void NetworkResourceLoadScheduler::servePendingRequests(ResourceLoadPriority minimumPriority)
{
- if (m_suspendPendingRequestsCount)
- return;
-
- LOG(NetworkScheduling, "(NetworkProcess) NetworkResourceLoadScheduler::servePendingRequests Serving requests for up to %i hosts", m_hosts.size());
+ LOG(NetworkScheduling, "(NetworkProcess) NetworkResourceLoadScheduler::servePendingRequests Serving requests for up to %i hosts with minimum priority %i", m_hosts.size(), minimumPriority);
m_requestTimer.stop();
- servePendingRequestsForHost(m_nonHTTPProtocolHost, minimumPriority);
+ m_nonHTTPProtocolHost->servePendingRequests(minimumPriority);
m_hosts.checkConsistency();
- Vector<HostRecord*> hostsToServe;
+ Vector<RefPtr<HostRecord>> hostsToServe;
copyValuesToVector(m_hosts, hostsToServe);
size_t size = hostsToServe.size();
for (size_t i = 0; i < size; ++i) {
- HostRecord* host = hostsToServe[i];
+ HostRecord* host = hostsToServe[i].get();
if (host->hasRequests())
- servePendingRequestsForHost(host, minimumPriority);
+ host->servePendingRequests(minimumPriority);
else
- delete m_hosts.take(host->name());
+ m_hosts.remove(host->name());
}
}
-void NetworkResourceLoadScheduler::servePendingRequestsForHost(HostRecord* host, ResourceLoadPriority minimumPriority)
+static bool removeScheduledLoadersCalled = false;
+
+void NetworkResourceLoadScheduler::removeScheduledLoaders(void* context)
{
- LOG(NetworkScheduling, "NetworkResourceLoadScheduler::servePendingRequests Host name='%s'", host->name().utf8().data());
-
- for (int priority = ResourceLoadPriorityHighest; priority >= minimumPriority; --priority) {
- HostRecord::LoaderQueue& loadersPending = host->loadersPending(ResourceLoadPriority(priority));
-
- while (!loadersPending.isEmpty()) {
- RefPtr<NetworkResourceLoader> loader = loadersPending.first();
-
- // This request might be from WebProcess we've lost our connection to.
- // If so we should just skip it.
- if (!loader->connectionToWebProcess()) {
- loadersPending.removeFirst();
- continue;
- }
-
- // For named hosts - which are only http(s) hosts - we should always enforce the connection limit.
- // For non-named hosts - everything but http(s) - we should only enforce the limit if the document
- // isn't done parsing and we don't know all stylesheets yet.
-
- // FIXME (NetworkProcess): The above comment about document parsing and stylesheets is a holdover
- // from the WebCore::ResourceLoadScheduler.
- // The behavior described was at one time important for WebCore's single threadedness.
- // It's possible that we don't care about it with the NetworkProcess.
- // We should either decide it's not important and change the above comment, or decide it is
- // still important and somehow account for it.
-
- bool shouldLimitRequests = !host->name().isNull();
- if (shouldLimitRequests && host->limitRequests(ResourceLoadPriority(priority), loader->connectionToWebProcess()->isSerialLoadingEnabled()))
- return;
-
- loadersPending.removeFirst();
- host->addLoadInProgress(loader->identifier());
-
- loader->start();
- }
+ ASSERT(isMainThread());
+ ASSERT(removeScheduledLoadersCalled);
+
+ NetworkResourceLoadScheduler* scheduler = static_cast<NetworkResourceLoadScheduler*>(context);
+ scheduler->removeScheduledLoaders();
+}
+
+void NetworkResourceLoadScheduler::removeScheduledLoaders()
+{
+ Vector<RefPtr<SchedulableLoader>> loadersToRemove;
+ {
+ MutexLocker locker(m_loadersToRemoveMutex);
+ loadersToRemove = m_loadersToRemove;
+ m_loadersToRemove.clear();
+ removeScheduledLoadersCalled = false;
}
+
+ for (size_t i = 0; i < loadersToRemove.size(); ++i)
+ removeLoader(loadersToRemove[i].get());
}
-void NetworkResourceLoadScheduler::suspendPendingRequests()
+void NetworkResourceLoadScheduler::scheduleRemoveLoader(SchedulableLoader* loader)
{
- ++m_suspendPendingRequestsCount;
+ MutexLocker locker(m_loadersToRemoveMutex);
+
+ m_loadersToRemove.append(loader);
+
+ if (!removeScheduledLoadersCalled) {
+ removeScheduledLoadersCalled = true;
+ callOnMainThread(NetworkResourceLoadScheduler::removeScheduledLoaders, this);
+ }
}
-void NetworkResourceLoadScheduler::resumePendingRequests()
+uint64_t NetworkResourceLoadScheduler::hostsPendingCount() const
{
- ASSERT(m_suspendPendingRequestsCount);
- --m_suspendPendingRequestsCount;
- if (m_suspendPendingRequestsCount)
- return;
+ uint64_t count = m_nonHTTPProtocolHost->pendingRequestCount() ? 1 : 0;
- if (!m_hosts.isEmpty() || m_nonHTTPProtocolHost->hasRequests())
- scheduleServePendingRequests();
-}
+ HostMap::const_iterator end = m_hosts.end();
+ for (HostMap::const_iterator i = m_hosts.begin(); i != end; ++i) {
+ if (i->value->pendingRequestCount())
+ ++count;
+ }
-static bool removeScheduledLoadIdentifiersCalled = false;
+ return count;
+}
-void NetworkResourceLoadScheduler::removeScheduledLoadIdentifiers(void* context)
+uint64_t NetworkResourceLoadScheduler::loadsPendingCount() const
{
- ASSERT(isMainThread());
- ASSERT(removeScheduledLoadIdentifiersCalled);
+ uint64_t count = m_nonHTTPProtocolHost->pendingRequestCount();
- NetworkResourceLoadScheduler* scheduler = static_cast<NetworkResourceLoadScheduler*>(context);
- scheduler->removeScheduledLoadIdentifiers();
+ HostMap::const_iterator end = m_hosts.end();
+ for (HostMap::const_iterator i = m_hosts.begin(); i != end; ++i)
+ count += i->value->pendingRequestCount();
+
+ return count;
}
-void NetworkResourceLoadScheduler::removeScheduledLoadIdentifiers()
+uint64_t NetworkResourceLoadScheduler::hostsActiveCount() const
{
- Vector<ResourceLoadIdentifier> identifiers;
- {
- MutexLocker locker(m_identifiersToRemoveMutex);
- copyToVector(m_identifiersToRemove, identifiers);
- m_identifiersToRemove.clear();
- removeScheduledLoadIdentifiersCalled = false;
+ uint64_t count = 0;
+
+ if (m_nonHTTPProtocolHost->activeLoadCount())
+ count = 1;
+
+ HostMap::const_iterator end = m_hosts.end();
+ for (HostMap::const_iterator i = m_hosts.begin(); i != end; ++i) {
+ if (i->value->activeLoadCount())
+ ++count;
}
-
- for (size_t i = 0; i < identifiers.size(); ++i)
- removeLoadIdentifier(identifiers[i]);
+
+ return count;
}
-void NetworkResourceLoadScheduler::scheduleRemoveLoadIdentifier(ResourceLoadIdentifier identifier)
+uint64_t NetworkResourceLoadScheduler::loadsActiveCount() const
{
- MutexLocker locker(m_identifiersToRemoveMutex);
-
- m_identifiersToRemove.add(identifier);
-
- if (!removeScheduledLoadIdentifiersCalled) {
- removeScheduledLoadIdentifiersCalled = true;
- callOnMainThread(NetworkResourceLoadScheduler::removeScheduledLoadIdentifiers, this);
- }
+ uint64_t count = m_nonHTTPProtocolHost->activeLoadCount();
+
+ HostMap::const_iterator end = m_hosts.end();
+ for (HostMap::const_iterator i = m_hosts.begin(); i != end; ++i)
+ count += i->value->activeLoadCount();
+
+ return count;
}
} // namespace WebKit
diff --git a/Source/WebKit2/NetworkProcess/NetworkResourceLoadScheduler.h b/Source/WebKit2/NetworkProcess/NetworkResourceLoadScheduler.h
index 85a19cd24..dfe710268 100644
--- a/Source/WebKit2/NetworkProcess/NetworkResourceLoadScheduler.h
+++ b/Source/WebKit2/NetworkProcess/NetworkResourceLoadScheduler.h
@@ -26,20 +26,22 @@
#ifndef NetworkResourceLoadScheduler_h
#define NetworkResourceLoadScheduler_h
-#include "NetworkResourceLoader.h"
-#include <WebCore/ResourceLoaderOptions.h>
-#include <WebCore/ResourceRequest.h>
+#include <WebCore/ResourceLoadPriority.h>
#include <WebCore/Timer.h>
+#include <wtf/HashMap.h>
#include <wtf/HashSet.h>
+#include <wtf/text/StringHash.h>
#if ENABLE(NETWORK_PROCESS)
+namespace WebCore {
+class KURL;
+}
+
namespace WebKit {
class HostRecord;
-class NetworkResourceLoadParameters;
-class NetworkConnectionToWebProcess;
-typedef uint64_t ResourceLoadIdentifier;
+class SchedulableLoader;
class NetworkResourceLoadScheduler {
WTF_MAKE_NONCOPYABLE(NetworkResourceLoadScheduler); WTF_MAKE_FAST_ALLOCATED;
@@ -47,24 +49,23 @@ class NetworkResourceLoadScheduler {
public:
NetworkResourceLoadScheduler();
- // Adds the request to the queue for its host and create a unique identifier for it.
- ResourceLoadIdentifier scheduleResourceLoad(const NetworkResourceLoadParameters&, NetworkConnectionToWebProcess*);
-
- // Creates a unique identifier for an already-in-progress load.
- ResourceLoadIdentifier addLoadInProgress(const WebCore::KURL&);
+ // Adds the request to the queue for its host.
+ void scheduleLoader(PassRefPtr<SchedulableLoader>);
// Called by the WebProcess when a ResourceLoader is being cleaned up.
- void removeLoadIdentifier(ResourceLoadIdentifier);
+ void removeLoader(SchedulableLoader*);
// Called within the NetworkProcess on a background thread when a resource load has finished.
- void scheduleRemoveLoadIdentifier(ResourceLoadIdentifier);
+ void scheduleRemoveLoader(SchedulableLoader*);
- void receivedRedirect(ResourceLoadIdentifier, const WebCore::KURL& redirectURL);
+ void receivedRedirect(SchedulableLoader*, const WebCore::KURL& redirectURL);
void servePendingRequests(WebCore::ResourceLoadPriority = WebCore::ResourceLoadPriorityVeryLow);
- void suspendPendingRequests();
- void resumePendingRequests();
-
- NetworkResourceLoader* networkResourceLoaderForIdentifier(ResourceLoadIdentifier);
+
+ // For NetworkProcess statistics reporting.
+ uint64_t hostsPendingCount() const;
+ uint64_t loadsPendingCount() const;
+ uint64_t hostsActiveCount() const;
+ uint64_t loadsActiveCount() const;
private:
enum CreateHostPolicy {
@@ -77,30 +78,27 @@ private:
void scheduleServePendingRequests();
void requestTimerFired(WebCore::Timer<NetworkResourceLoadScheduler>*);
- void servePendingRequestsForHost(HostRecord*, WebCore::ResourceLoadPriority);
+ void platformInitializeMaximumHTTPConnectionCountPerHost();
- unsigned platformInitializeMaximumHTTPConnectionCountPerHost();
+ static void removeScheduledLoaders(void* context);
+ void removeScheduledLoaders();
- static void removeScheduledLoadIdentifiers(void* context);
- void removeScheduledLoadIdentifiers();
-
- HashMap<ResourceLoadIdentifier, RefPtr<NetworkResourceLoader> > m_resourceLoaders;
-
- typedef HashMap<String, HostRecord*, StringHash> HostMap;
+ typedef HashMap<String, RefPtr<HostRecord>, StringHash> HostMap;
HostMap m_hosts;
- typedef HashMap<ResourceLoadIdentifier, HostRecord*> IdentifierHostMap;
- IdentifierHostMap m_identifiers;
+ typedef HashSet<RefPtr<SchedulableLoader>> SchedulableLoaderSet;
+ SchedulableLoaderSet m_loaders;
- HostRecord* m_nonHTTPProtocolHost;
+ RefPtr<HostRecord> m_nonHTTPProtocolHost;
- unsigned m_suspendPendingRequestsCount;
bool m_isSerialLoadingEnabled;
WebCore::Timer<NetworkResourceLoadScheduler> m_requestTimer;
- Mutex m_identifiersToRemoveMutex;
- HashSet<ResourceLoadIdentifier> m_identifiersToRemove;
+ Mutex m_loadersToRemoveMutex;
+ Vector<RefPtr<SchedulableLoader>> m_loadersToRemove;
+
+ unsigned m_maxRequestsInFlightPerHost;
};
} // namespace WebKit
diff --git a/Source/WebKit2/NetworkProcess/NetworkResourceLoader.cpp b/Source/WebKit2/NetworkProcess/NetworkResourceLoader.cpp
index 80aa813ac..5ad12d324 100644
--- a/Source/WebKit2/NetworkProcess/NetworkResourceLoader.cpp
+++ b/Source/WebKit2/NetworkProcess/NetworkResourceLoader.cpp
@@ -28,354 +28,323 @@
#if ENABLE(NETWORK_PROCESS)
-#include "BlockingResponseMap.h"
+#include "AuthenticationManager.h"
#include "DataReference.h"
#include "Logging.h"
#include "NetworkConnectionToWebProcess.h"
#include "NetworkProcess.h"
+#include "NetworkProcessConnectionMessages.h"
#include "NetworkResourceLoadParameters.h"
+#include "PlatformCertificateInfo.h"
#include "RemoteNetworkingContext.h"
+#include "ShareableResource.h"
#include "SharedMemory.h"
#include "WebCoreArgumentCoders.h"
+#include "WebErrors.h"
#include "WebResourceLoaderMessages.h"
#include <WebCore/NotImplemented.h>
#include <WebCore/ResourceBuffer.h>
#include <WebCore/ResourceHandle.h>
+#include <wtf/CurrentTime.h>
#include <wtf/MainThread.h>
using namespace WebCore;
namespace WebKit {
-NetworkResourceLoader::NetworkResourceLoader(const NetworkResourceLoadParameters& requestParameters, ResourceLoadIdentifier identifier, NetworkConnectionToWebProcess* connection)
- : m_requestParameters(requestParameters)
- , m_identifier(identifier)
- , m_connection(connection)
+NetworkResourceLoader::NetworkResourceLoader(const NetworkResourceLoadParameters& loadParameters, NetworkConnectionToWebProcess* connection)
+ : SchedulableLoader(loadParameters, connection)
+ , m_bytesReceived(0)
+ , m_handleConvertedToDownload(false)
{
ASSERT(isMainThread());
- connection->registerObserver(this);
}
NetworkResourceLoader::~NetworkResourceLoader()
{
ASSERT(isMainThread());
-
- if (m_connection)
- m_connection->unregisterObserver(this);
-}
-
-CoreIPC::Connection* NetworkResourceLoader::connection() const
-{
- return m_connection->connection();
-}
-
-ResourceLoadPriority NetworkResourceLoader::priority() const
-{
- return m_requestParameters.priority();
+ ASSERT(!m_handle);
}
void NetworkResourceLoader::start()
{
ASSERT(isMainThread());
- // Explicit ref() balanced by a deref() in NetworkResourceLoader::stop()
+ // Explicit ref() balanced by a deref() in NetworkResourceLoader::resourceHandleStopped()
ref();
// FIXME (NetworkProcess): Create RemoteNetworkingContext with actual settings.
- m_networkingContext = RemoteNetworkingContext::create(false, false);
+ m_networkingContext = RemoteNetworkingContext::create(false, false, inPrivateBrowsingMode(), shouldClearReferrerOnHTTPSToHTTPRedirect());
+
+ consumeSandboxExtensions();
// FIXME (NetworkProcess): Pass an actual value for defersLoading
- m_handle = ResourceHandle::create(m_networkingContext.get(), m_requestParameters.request(), this, false /* defersLoading */, m_requestParameters.contentSniffingPolicy() == SniffContent);
+ m_handle = ResourceHandle::create(m_networkingContext.get(), request(), this, false /* defersLoading */, contentSniffingPolicy() == SniffContent);
}
-static bool stopRequestsCalled = false;
-
-static Mutex& requestsToStopMutex()
+void NetworkResourceLoader::cleanup()
{
- DEFINE_STATIC_LOCAL(Mutex, mutex, ());
- return mutex;
-}
+ ASSERT(isMainThread());
-static HashSet<NetworkResourceLoader*>& requestsToStop()
-{
- DEFINE_STATIC_LOCAL(HashSet<NetworkResourceLoader*>, requests, ());
- return requests;
-}
+ invalidateSandboxExtensions();
-void NetworkResourceLoader::scheduleStopOnMainThread()
-{
- MutexLocker locker(requestsToStopMutex());
+ if (FormData* formData = request().httpBody())
+ formData->removeGeneratedFilesIfNeeded();
+
+ // Tell the scheduler about this finished loader soon so it can start more network requests.
+ NetworkProcess::shared().networkResourceLoadScheduler().scheduleRemoveLoader(this);
- requestsToStop().add(this);
- if (!stopRequestsCalled) {
- stopRequestsCalled = true;
- callOnMainThread(NetworkResourceLoader::performStops, 0);
+ if (m_handle) {
+ // Explicit deref() balanced by a ref() in NetworkResourceLoader::start()
+ // This might cause the NetworkResourceLoader to be destroyed and therefore we do it last.
+ m_handle = 0;
+ deref();
}
}
-void NetworkResourceLoader::performStops(void*)
+template<typename U> bool NetworkResourceLoader::sendAbortingOnFailure(const U& message, unsigned messageSendFlags)
{
- ASSERT(stopRequestsCalled);
-
- Vector<NetworkResourceLoader*> requests;
- {
- MutexLocker locker(requestsToStopMutex());
- copyToVector(requestsToStop(), requests);
- requestsToStop().clear();
- stopRequestsCalled = false;
- }
-
- for (size_t i = 0; i < requests.size(); ++i)
- requests[i]->stop();
+ bool result = messageSenderConnection()->send(message, messageSenderDestinationID(), messageSendFlags);
+ if (!result)
+ abort();
+ return result;
}
-void NetworkResourceLoader::stop()
+void NetworkResourceLoader::didConvertHandleToDownload()
{
- ASSERT(isMainThread());
-
- // Remove this load identifier soon so we can start more network requests.
- NetworkProcess::shared().networkResourceLoadScheduler().scheduleRemoveLoadIdentifier(m_identifier);
-
- // Explicit deref() balanced by a ref() in NetworkResourceLoader::stop()
- // This might cause the NetworkResourceLoader to be destroyed and therefore we do it last.
- deref();
+ ASSERT(m_handle);
+ m_handleConvertedToDownload = true;
}
-void NetworkResourceLoader::connectionToWebProcessDidClose(NetworkConnectionToWebProcess* connection)
+void NetworkResourceLoader::abort()
{
- ASSERT_ARG(connection, connection == m_connection.get());
- m_connection->unregisterObserver(this);
- m_connection = 0;
+ ASSERT(isMainThread());
+
+ if (m_handle && !m_handleConvertedToDownload)
+ m_handle->cancel();
+
+ cleanup();
}
-void NetworkResourceLoader::didReceiveResponse(ResourceHandle*, const ResourceResponse& response)
+void NetworkResourceLoader::didReceiveResponseAsync(ResourceHandle* handle, const ResourceResponse& response)
{
+ ASSERT_UNUSED(handle, handle == m_handle);
+
// FIXME (NetworkProcess): Cache the response.
- send(Messages::WebResourceLoader::DidReceiveResponse(response));
+ if (FormData* formData = request().httpBody())
+ formData->removeGeneratedFilesIfNeeded();
+
+ sendAbortingOnFailure(Messages::WebResourceLoader::DidReceiveResponseWithCertificateInfo(response, PlatformCertificateInfo(response), isLoadingMainResource()));
+
+ // m_handle will be 0 if the request got aborted above.
+ if (!m_handle)
+ return;
+
+ if (!isLoadingMainResource()) {
+ // For main resources, the web process is responsible for sending back a NetworkResourceLoader::ContinueDidReceiveResponse message.
+ m_handle->continueDidReceiveResponse();
+ }
}
void NetworkResourceLoader::didReceiveData(ResourceHandle*, const char* data, int length, int encodedDataLength)
{
+ // The NetworkProcess should never get a didReceiveData callback.
+ // We should always be using didReceiveBuffer.
+ ASSERT_NOT_REACHED();
+}
+
+void NetworkResourceLoader::didReceiveBuffer(ResourceHandle* handle, PassRefPtr<SharedBuffer> buffer, int encodedDataLength)
+{
+ ASSERT_UNUSED(handle, handle == m_handle);
+
// FIXME (NetworkProcess): For the memory cache we'll also need to cache the response data here.
// Such buffering will need to be thread safe, as this callback is happening on a background thread.
- CoreIPC::DataReference dataReference(reinterpret_cast<const uint8_t*>(data), length);
- send(Messages::WebResourceLoader::DidReceiveData(dataReference, encodedDataLength, false));
+ m_bytesReceived += buffer->size();
+
+#if __MAC_OS_X_VERSION_MIN_REQUIRED >= 1090
+ ShareableResource::Handle shareableResourceHandle;
+ tryGetShareableHandleFromSharedBuffer(shareableResourceHandle, buffer.get());
+ if (!shareableResourceHandle.isNull()) {
+ // Since we're delivering this resource by ourselves all at once, we'll abort the resource handle since we don't need anymore callbacks from ResourceHandle.
+ abort();
+ send(Messages::WebResourceLoader::DidReceiveResource(shareableResourceHandle, currentTime()));
+ return;
+ }
+#endif // __MAC_OS_X_VERSION_MIN_REQUIRED >= 1090
+
+ CoreIPC::DataReference dataReference(reinterpret_cast<const uint8_t*>(buffer->data()), buffer->size());
+ sendAbortingOnFailure(Messages::WebResourceLoader::DidReceiveData(dataReference, encodedDataLength));
}
-void NetworkResourceLoader::didFinishLoading(ResourceHandle*, double finishTime)
+void NetworkResourceLoader::didFinishLoading(ResourceHandle* handle, double finishTime)
{
+ ASSERT_UNUSED(handle, handle == m_handle);
+
// FIXME (NetworkProcess): For the memory cache we'll need to update the finished status of the cached resource here.
// Such bookkeeping will need to be thread safe, as this callback is happening on a background thread.
send(Messages::WebResourceLoader::DidFinishResourceLoad(finishTime));
- scheduleStopOnMainThread();
+
+ cleanup();
}
-void NetworkResourceLoader::didFail(ResourceHandle*, const ResourceError& error)
+void NetworkResourceLoader::didFail(ResourceHandle* handle, const ResourceError& error)
{
+ ASSERT_UNUSED(handle, handle == m_handle);
+
// FIXME (NetworkProcess): For the memory cache we'll need to update the finished status of the cached resource here.
// Such bookkeeping will need to be thread safe, as this callback is happening on a background thread.
send(Messages::WebResourceLoader::DidFailResourceLoad(error));
- scheduleStopOnMainThread();
+ cleanup();
}
-static BlockingResponseMap<ResourceRequest*>& willSendRequestResponseMap()
+void NetworkResourceLoader::willSendRequestAsync(ResourceHandle* handle, const ResourceRequest& request, const ResourceResponse& redirectResponse)
{
- AtomicallyInitializedStatic(BlockingResponseMap<ResourceRequest*>&, responseMap = *new BlockingResponseMap<ResourceRequest*>);
- return responseMap;
-}
+ ASSERT_UNUSED(handle, handle == m_handle);
-static uint64_t generateWillSendRequestID()
-{
- static int64_t uniqueWillSendRequestID;
- return atomicIncrement(&uniqueWillSendRequestID);
-}
-
-void NetworkResourceLoader::willSendRequest(ResourceHandle*, ResourceRequest& request, const ResourceResponse& redirectResponse)
-{
- // We only expect to get the willSendRequest callback from ResourceHandle as the result of a redirect
+ // We only expect to get the willSendRequest callback from ResourceHandle as the result of a redirect.
ASSERT(!redirectResponse.isNull());
+ ASSERT(isMainThread());
- uint64_t requestID = generateWillSendRequestID();
-
- send(Messages::WebResourceLoader::WillSendRequest(requestID, request, redirectResponse));
-
- OwnPtr<ResourceRequest> newRequest = willSendRequestResponseMap().waitForResponse(requestID);
- request = *newRequest;
+ m_suggestedRequestForWillSendRequest = request;
- RunLoop::main()->dispatch(WTF::bind(&NetworkResourceLoadScheduler::receivedRedirect, &NetworkProcess::shared().networkResourceLoadScheduler(), m_identifier, request.url()));
+ // This message is DispatchMessageEvenWhenWaitingForSyncReply to avoid a situation where the NetworkProcess is deadlocked waiting for 6 connections
+ // to complete while the WebProcess is waiting for a 7th to complete.
+ sendAbortingOnFailure(Messages::WebResourceLoader::WillSendRequest(request, redirectResponse), CoreIPC::DispatchMessageEvenWhenWaitingForSyncReply);
}
-void NetworkResourceLoader::willSendRequestHandled(uint64_t requestID, const WebCore::ResourceRequest& newRequest)
+void NetworkResourceLoader::continueWillSendRequest(const ResourceRequest& newRequest)
{
- willSendRequestResponseMap().didReceiveResponse(requestID, adoptPtr(new ResourceRequest(newRequest)));
-}
+ m_suggestedRequestForWillSendRequest.updateFromDelegatePreservingOldHTTPBody(newRequest.nsURLRequest(DoNotUpdateHTTPBody));
-// FIXME (NetworkProcess): Many of the following ResourceHandleClient methods definitely need implementations. A few will not.
-// Once we know what they are they can be removed.
+ RunLoop::main()->dispatch(bind(&NetworkResourceLoadScheduler::receivedRedirect, &NetworkProcess::shared().networkResourceLoadScheduler(), this, m_suggestedRequestForWillSendRequest.url()));
+ m_handle->continueWillSendRequest(m_suggestedRequestForWillSendRequest);
-void NetworkResourceLoader::didSendData(WebCore::ResourceHandle*, unsigned long long /*bytesSent*/, unsigned long long /*totalBytesToBeSent*/)
-{
- notImplemented();
+ m_suggestedRequestForWillSendRequest = ResourceRequest();
}
-void NetworkResourceLoader::didReceiveCachedMetadata(WebCore::ResourceHandle*, const char*, int)
+void NetworkResourceLoader::continueDidReceiveResponse()
{
- notImplemented();
-}
+ // FIXME: Remove this check once BlobResourceHandle implements didReceiveResponseAsync correctly.
+ // Currently, it does not wait for response, so the load is likely to finish before continueDidReceiveResponse.
+ if (!m_handle)
+ return;
-void NetworkResourceLoader::wasBlocked(WebCore::ResourceHandle*)
-{
- notImplemented();
+ m_handle->continueDidReceiveResponse();
}
-void NetworkResourceLoader::cannotShowURL(WebCore::ResourceHandle*)
+void NetworkResourceLoader::didSendData(ResourceHandle* handle, unsigned long long bytesSent, unsigned long long totalBytesToBeSent)
{
- notImplemented();
-}
+ ASSERT_UNUSED(handle, handle == m_handle);
-void NetworkResourceLoader::willCacheResponse(WebCore::ResourceHandle*, WebCore::CacheStoragePolicy&)
-{
- notImplemented();
+ send(Messages::WebResourceLoader::DidSendData(bytesSent, totalBytesToBeSent));
}
-bool NetworkResourceLoader::shouldUseCredentialStorage(ResourceHandle*)
+void NetworkResourceLoader::wasBlocked(ResourceHandle* handle)
{
- // When the WebProcess is handling loading a client is consulted each time this shouldUseCredentialStorage question is asked.
- // In NetworkProcess mode we ask the WebProcess client up front once and then reuse the cached answer.
+ ASSERT_UNUSED(handle, handle == m_handle);
- return m_requestParameters.allowStoredCredentials() == AllowStoredCredentials;
+ didFail(handle, WebKit::blockedError(request()));
}
-void NetworkResourceLoader::didReceiveAuthenticationChallenge(ResourceHandle*, const AuthenticationChallenge& challenge)
+void NetworkResourceLoader::cannotShowURL(ResourceHandle* handle)
{
- ASSERT(!m_currentAuthenticationChallenge);
- m_currentAuthenticationChallenge = adoptPtr(new AuthenticationChallenge(challenge));
+ ASSERT_UNUSED(handle, handle == m_handle);
- send(Messages::WebResourceLoader::DidReceiveAuthenticationChallenge(*m_currentAuthenticationChallenge));
+ didFail(handle, WebKit::cannotShowURLError(request()));
}
-void NetworkResourceLoader::didCancelAuthenticationChallenge(ResourceHandle*, const AuthenticationChallenge& challenge)
+bool NetworkResourceLoader::shouldUseCredentialStorage(ResourceHandle* handle)
{
- ASSERT(m_currentAuthenticationChallenge);
- ASSERT(m_currentAuthenticationChallenge->identifier() == challenge.identifier());
+ ASSERT_UNUSED(handle, handle == m_handle || !m_handle); // m_handle will be 0 if called from ResourceHandle::start().
- send(Messages::WebResourceLoader::DidCancelAuthenticationChallenge(*m_currentAuthenticationChallenge));
+ // When the WebProcess is handling loading a client is consulted each time this shouldUseCredentialStorage question is asked.
+ // In NetworkProcess mode we ask the WebProcess client up front once and then reuse the cached answer.
- m_currentAuthenticationChallenge.clear();
-}
+ // We still need this sync version, because ResourceHandle itself uses it internally, even when the delegate uses an async one.
-void NetworkResourceLoader::receivedCancellation(ResourceHandle*, const AuthenticationChallenge& challenge)
-{
- receivedAuthenticationCancellation(challenge);
+ return allowStoredCredentials() == AllowStoredCredentials;
}
-void NetworkResourceLoader::receivedAuthenticationCredential(const AuthenticationChallenge& challenge, const Credential& credential)
+void NetworkResourceLoader::shouldUseCredentialStorageAsync(ResourceHandle* handle)
{
- ASSERT(m_currentAuthenticationChallenge);
- ASSERT(m_currentAuthenticationChallenge->authenticationClient());
+ ASSERT_UNUSED(handle, handle == m_handle);
- if (m_currentAuthenticationChallenge->identifier() != challenge.identifier())
- return;
-
- m_currentAuthenticationChallenge->authenticationClient()->receivedCredential(*m_currentAuthenticationChallenge, credential);
- m_currentAuthenticationChallenge.clear();
+ handle->continueShouldUseCredentialStorage(shouldUseCredentialStorage(handle));
}
-void NetworkResourceLoader::receivedRequestToContinueWithoutAuthenticationCredential(const AuthenticationChallenge& challenge)
+void NetworkResourceLoader::didReceiveAuthenticationChallenge(ResourceHandle* handle, const AuthenticationChallenge& challenge)
{
- ASSERT(m_currentAuthenticationChallenge);
- ASSERT(m_currentAuthenticationChallenge->authenticationClient());
+ ASSERT_UNUSED(handle, handle == m_handle);
- if (m_currentAuthenticationChallenge->identifier() != challenge.identifier())
+ // FIXME (http://webkit.org/b/115291): Since we go straight to the UI process for authentication we don't get WebCore's
+ // cross-origin check before asking the client for credentials.
+ // Therefore we are too permissive in the case where the ClientCredentialPolicy is DoNotAskClientForCrossOriginCredentials.
+ if (clientCredentialPolicy() == DoNotAskClientForAnyCredentials) {
+ challenge.authenticationClient()->receivedRequestToContinueWithoutCredential(challenge);
return;
+ }
- m_currentAuthenticationChallenge->authenticationClient()->receivedRequestToContinueWithoutCredential(*m_currentAuthenticationChallenge);
- m_currentAuthenticationChallenge.clear();
+ NetworkProcess::shared().authenticationManager().didReceiveAuthenticationChallenge(webPageID(), webFrameID(), challenge);
}
-void NetworkResourceLoader::receivedAuthenticationCancellation(const AuthenticationChallenge& challenge)
+void NetworkResourceLoader::didCancelAuthenticationChallenge(ResourceHandle* handle, const AuthenticationChallenge& challenge)
{
- ASSERT(m_currentAuthenticationChallenge);
- ASSERT(m_currentAuthenticationChallenge->authenticationClient());
-
- if (m_currentAuthenticationChallenge->identifier() != challenge.identifier())
- return;
+ ASSERT_UNUSED(handle, handle == m_handle);
- m_currentAuthenticationChallenge->authenticationClient()->receivedCancellation(*m_currentAuthenticationChallenge);
- m_currentAuthenticationChallenge.clear();
+ // This function is probably not needed (see <rdar://problem/8960124>).
+ notImplemented();
}
-#if USE(PROTECTION_SPACE_AUTH_CALLBACK)
-static BlockingBoolResponseMap& canAuthenticateAgainstProtectionSpaceResponseMap()
+CoreIPC::Connection* NetworkResourceLoader::messageSenderConnection()
{
- AtomicallyInitializedStatic(BlockingBoolResponseMap&, responseMap = *new BlockingBoolResponseMap);
- return responseMap;
+ return connectionToWebProcess()->connection();
}
-static uint64_t generateCanAuthenticateAgainstProtectionSpaceID()
+uint64_t NetworkResourceLoader::messageSenderDestinationID()
{
- static int64_t uniqueCanAuthenticateAgainstProtectionSpaceID;
- return atomicIncrement(&uniqueCanAuthenticateAgainstProtectionSpaceID);
+ return identifier();
}
-bool NetworkResourceLoader::canAuthenticateAgainstProtectionSpace(ResourceHandle*, const ProtectionSpace& protectionSpace)
+#if USE(PROTECTION_SPACE_AUTH_CALLBACK)
+void NetworkResourceLoader::canAuthenticateAgainstProtectionSpaceAsync(ResourceHandle* handle, const ProtectionSpace& protectionSpace)
{
- uint64_t requestID = generateCanAuthenticateAgainstProtectionSpaceID();
-
- send(Messages::WebResourceLoader::CanAuthenticateAgainstProtectionSpace(requestID, protectionSpace));
+ ASSERT(isMainThread());
+ ASSERT_UNUSED(handle, handle == m_handle);
- return canAuthenticateAgainstProtectionSpaceResponseMap().waitForResponse(requestID);
+ // This message is DispatchMessageEvenWhenWaitingForSyncReply to avoid a situation where the NetworkProcess is deadlocked
+ // waiting for 6 connections to complete while the WebProcess is waiting for a 7th to complete.
+ sendAbortingOnFailure(Messages::WebResourceLoader::CanAuthenticateAgainstProtectionSpace(protectionSpace), CoreIPC::DispatchMessageEvenWhenWaitingForSyncReply);
}
-void NetworkResourceLoader::canAuthenticateAgainstProtectionSpaceHandled(uint64_t requestID, bool canAuthenticate)
+void NetworkResourceLoader::continueCanAuthenticateAgainstProtectionSpace(bool result)
{
- canAuthenticateAgainstProtectionSpaceResponseMap().didReceiveResponse(requestID, canAuthenticate);
+ m_handle->continueCanAuthenticateAgainstProtectionSpace(result);
}
+
#endif
-#if HAVE(NETWORK_CFDATA_ARRAY_CALLBACK)
+#if USE(NETWORK_CFDATA_ARRAY_CALLBACK)
bool NetworkResourceLoader::supportsDataArray()
{
notImplemented();
return false;
}
-void NetworkResourceLoader::didReceiveDataArray(WebCore::ResourceHandle*, CFArrayRef)
+void NetworkResourceLoader::didReceiveDataArray(ResourceHandle*, CFArrayRef)
{
+ ASSERT_NOT_REACHED();
notImplemented();
}
#endif
#if PLATFORM(MAC)
-#if USE(CFNETWORK)
-CFCachedURLResponseRef NetworkResourceLoader::willCacheResponse(WebCore::ResourceHandle*, CFCachedURLResponseRef response)
-{
- notImplemented();
- return response;
-}
-#else
-NSCachedURLResponse* NetworkResourceLoader::willCacheResponse(WebCore::ResourceHandle*, NSCachedURLResponse* response)
-{
- notImplemented();
- return response;
-}
-#endif
-
-void NetworkResourceLoader::willStopBufferingData(WebCore::ResourceHandle*, const char*, int)
+void NetworkResourceLoader::willStopBufferingData(ResourceHandle*, const char*, int)
{
notImplemented();
}
#endif // PLATFORM(MAC)
-#if ENABLE(BLOB)
-WebCore::AsyncFileStream* NetworkResourceLoader::createAsyncFileStream(WebCore::FileStreamClient*)
-{
- notImplemented();
- return 0;
-}
-#endif
-
} // namespace WebKit
#endif // ENABLE(NETWORK_PROCESS)
diff --git a/Source/WebKit2/NetworkProcess/NetworkResourceLoader.h b/Source/WebKit2/NetworkProcess/NetworkResourceLoader.h
index bbfbc5dfe..798cccf20 100644
--- a/Source/WebKit2/NetworkProcess/NetworkResourceLoader.h
+++ b/Source/WebKit2/NetworkProcess/NetworkResourceLoader.h
@@ -29,107 +29,109 @@
#if ENABLE(NETWORK_PROCESS)
#include "MessageSender.h"
-#include "NetworkConnectionToWebProcess.h"
-#include "NetworkResourceLoadParameters.h"
-#include <WebCore/AuthenticationChallenge.h>
+#include "SchedulableLoader.h"
+#include "ShareableResource.h"
#include <WebCore/ResourceHandleClient.h>
-#include <WebCore/ResourceLoaderOptions.h>
-#include <WebCore/ResourceRequest.h>
+#include <WebCore/RunLoop.h>
+
+typedef const struct _CFCachedURLResponse* CFCachedURLResponseRef;
namespace WebCore {
class ResourceBuffer;
class ResourceHandle;
+class ResourceRequest;
}
namespace WebKit {
+class NetworkConnectionToWebProcess;
class RemoteNetworkingContext;
-typedef uint64_t ResourceLoadIdentifier;
-class NetworkResourceLoader : public RefCounted<NetworkResourceLoader>, public NetworkConnectionToWebProcessObserver, public WebCore::ResourceHandleClient, public CoreIPC::MessageSender<NetworkResourceLoader> {
+class NetworkResourceLoader : public SchedulableLoader, public WebCore::ResourceHandleClient, public CoreIPC::MessageSender {
public:
- static RefPtr<NetworkResourceLoader> create(const NetworkResourceLoadParameters& parameters, ResourceLoadIdentifier identifier, NetworkConnectionToWebProcess* connection)
+ static RefPtr<NetworkResourceLoader> create(const NetworkResourceLoadParameters& parameters, NetworkConnectionToWebProcess* connection)
{
- return adoptRef(new NetworkResourceLoader(parameters, identifier, connection));
+ return adoptRef(new NetworkResourceLoader(parameters, connection));
}
~NetworkResourceLoader();
- // Used by MessageSender.
- CoreIPC::Connection* connection() const;
- uint64_t destinationID() const { return identifier(); }
-
- void didReceiveNetworkResourceLoaderMessage(CoreIPC::Connection*, CoreIPC::MessageID, CoreIPC::MessageDecoder&);
-
- void start();
+ WebCore::ResourceHandle* handle() const { return m_handle.get(); }
+ void didConvertHandleToDownload();
- virtual void connectionToWebProcessDidClose(NetworkConnectionToWebProcess*) OVERRIDE;
-
- ResourceLoadIdentifier identifier() const { return m_identifier; }
- WebCore::ResourceLoadPriority priority() const;
-
- NetworkConnectionToWebProcess* connectionToWebProcess() { return m_connection.get(); }
+ virtual void start() OVERRIDE;
+ virtual void abort() OVERRIDE;
// ResourceHandleClient methods
- virtual void willSendRequest(WebCore::ResourceHandle*, WebCore::ResourceRequest&, const WebCore::ResourceResponse& /*redirectResponse*/) OVERRIDE;
- virtual void didSendData(WebCore::ResourceHandle*, unsigned long long /*bytesSent*/, unsigned long long /*totalBytesToBeSent*/) OVERRIDE;
- virtual void didReceiveResponse(WebCore::ResourceHandle*, const WebCore::ResourceResponse&) OVERRIDE;
- virtual void didReceiveData(WebCore::ResourceHandle*, const char*, int, int /*encodedDataLength*/) OVERRIDE;
- virtual void didReceiveCachedMetadata(WebCore::ResourceHandle*, const char*, int) OVERRIDE;
- virtual void didFinishLoading(WebCore::ResourceHandle*, double /*finishTime*/) OVERRIDE;
+ virtual void willSendRequestAsync(WebCore::ResourceHandle*, const WebCore::ResourceRequest&, const WebCore::ResourceResponse& redirectResponse) OVERRIDE;
+ virtual void didSendData(WebCore::ResourceHandle*, unsigned long long bytesSent, unsigned long long totalBytesToBeSent) OVERRIDE;
+ virtual void didReceiveResponseAsync(WebCore::ResourceHandle*, const WebCore::ResourceResponse&) OVERRIDE;
+ virtual void didReceiveData(WebCore::ResourceHandle*, const char*, int, int encodedDataLength) OVERRIDE;
+ virtual void didReceiveBuffer(WebCore::ResourceHandle*, PassRefPtr<WebCore::SharedBuffer>, int encodedDataLength) OVERRIDE;
+ virtual void didFinishLoading(WebCore::ResourceHandle*, double finishTime) OVERRIDE;
virtual void didFail(WebCore::ResourceHandle*, const WebCore::ResourceError&) OVERRIDE;
virtual void wasBlocked(WebCore::ResourceHandle*) OVERRIDE;
virtual void cannotShowURL(WebCore::ResourceHandle*) OVERRIDE;
- virtual void willCacheResponse(WebCore::ResourceHandle*, WebCore::CacheStoragePolicy&) OVERRIDE;
virtual bool shouldUseCredentialStorage(WebCore::ResourceHandle*) OVERRIDE;
+ virtual void shouldUseCredentialStorageAsync(WebCore::ResourceHandle*) OVERRIDE;
virtual void didReceiveAuthenticationChallenge(WebCore::ResourceHandle*, const WebCore::AuthenticationChallenge&) OVERRIDE;
virtual void didCancelAuthenticationChallenge(WebCore::ResourceHandle*, const WebCore::AuthenticationChallenge&) OVERRIDE;
- virtual void receivedCancellation(WebCore::ResourceHandle*, const WebCore::AuthenticationChallenge&) OVERRIDE;
+ virtual bool usesAsyncCallbacks() OVERRIDE { return true; }
#if USE(PROTECTION_SPACE_AUTH_CALLBACK)
- virtual bool canAuthenticateAgainstProtectionSpace(WebCore::ResourceHandle*, const WebCore::ProtectionSpace&) OVERRIDE;
+ virtual void canAuthenticateAgainstProtectionSpaceAsync(WebCore::ResourceHandle*, const WebCore::ProtectionSpace&) OVERRIDE;
#endif
-#if HAVE(NETWORK_CFDATA_ARRAY_CALLBACK)
+#if USE(NETWORK_CFDATA_ARRAY_CALLBACK)
virtual bool supportsDataArray() OVERRIDE;
virtual void didReceiveDataArray(WebCore::ResourceHandle*, CFArrayRef) OVERRIDE;
#endif
#if PLATFORM(MAC)
-#if USE(CFNETWORK)
- virtual CFCachedURLResponseRef willCacheResponse(WebCore::ResourceHandle*, CFCachedURLResponseRef) OVERRIDE;
-#else
- virtual NSCachedURLResponse* willCacheResponse(WebCore::ResourceHandle*, NSCachedURLResponse*) OVERRIDE;
-#endif
+ static size_t fileBackedResourceMinimumSize();
+ virtual void willCacheResponseAsync(WebCore::ResourceHandle*, NSCachedURLResponse *) OVERRIDE;
virtual void willStopBufferingData(WebCore::ResourceHandle*, const char*, int) OVERRIDE;
#endif // PLATFORM(MAC)
-#if ENABLE(BLOB)
- virtual WebCore::AsyncFileStream* createAsyncFileStream(WebCore::FileStreamClient*) OVERRIDE;
+ // Message handlers.
+ void didReceiveNetworkResourceLoaderMessage(CoreIPC::Connection*, CoreIPC::MessageDecoder&);
+
+#if __MAC_OS_X_VERSION_MIN_REQUIRED >= 1090
+ static void tryGetShareableHandleFromCFURLCachedResponse(ShareableResource::Handle&, CFCachedURLResponseRef);
#endif
private:
- NetworkResourceLoader(const NetworkResourceLoadParameters&, ResourceLoadIdentifier, NetworkConnectionToWebProcess*);
+ NetworkResourceLoader(const NetworkResourceLoadParameters&, NetworkConnectionToWebProcess*);
- void willSendRequestHandled(uint64_t requestID, const WebCore::ResourceRequest&);
- void canAuthenticateAgainstProtectionSpaceHandled(uint64_t requestID, bool canAuthenticate);
- void receivedAuthenticationCredential(const WebCore::AuthenticationChallenge&, const WebCore::Credential&);
- void receivedRequestToContinueWithoutAuthenticationCredential(const WebCore::AuthenticationChallenge&);
- void receivedAuthenticationCancellation(const WebCore::AuthenticationChallenge&);
-
- void scheduleStopOnMainThread();
- static void performStops(void*);
+ // CoreIPC::MessageSender
+ virtual CoreIPC::Connection* messageSenderConnection() OVERRIDE;
+ virtual uint64_t messageSenderDestinationID() OVERRIDE;
+
+ void continueWillSendRequest(const WebCore::ResourceRequest& newRequest);
+ void continueDidReceiveResponse();
+#if USE(PROTECTION_SPACE_AUTH_CALLBACK)
+ void continueCanAuthenticateAgainstProtectionSpace(bool);
+#endif
- void stop();
+ void cleanup();
+
+ void platformDidReceiveResponse(const WebCore::ResourceResponse&);
- NetworkResourceLoadParameters m_requestParameters;
- ResourceLoadIdentifier m_identifier;
+ template<typename U> bool sendAbortingOnFailure(const U& message, unsigned messageSendFlags = 0);
RefPtr<RemoteNetworkingContext> m_networkingContext;
- RefPtr<WebCore::ResourceHandle> m_handle;
- RefPtr<NetworkConnectionToWebProcess> m_connection;
-
- OwnPtr<WebCore::AuthenticationChallenge> m_currentAuthenticationChallenge;
+ RefPtr<WebCore::ResourceHandle> m_handle;
+
+ // Keep the suggested request around while asynchronously asking to update it, because some parts of the request don't survive IPC.
+ WebCore::ResourceRequest m_suggestedRequestForWillSendRequest;
+
+ uint64_t m_bytesReceived;
+
+ bool m_handleConvertedToDownload;
+
+#if __MAC_OS_X_VERSION_MIN_REQUIRED >= 1090
+ static void tryGetShareableHandleFromSharedBuffer(ShareableResource::Handle&, WebCore::SharedBuffer*);
+#endif
};
} // namespace WebKit
diff --git a/Source/WebKit2/NetworkProcess/NetworkResourceLoader.messages.in b/Source/WebKit2/NetworkProcess/NetworkResourceLoader.messages.in
index c6c0f0bbe..00706af43 100644
--- a/Source/WebKit2/NetworkProcess/NetworkResourceLoader.messages.in
+++ b/Source/WebKit2/NetworkProcess/NetworkResourceLoader.messages.in
@@ -1,4 +1,4 @@
-# Copyright (C) 2012 Apple Inc. All rights reserved.
+# Copyright (C) 2013 Apple Inc. All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
@@ -20,15 +20,9 @@
# 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 -> NetworkResourceLoader LegacyReceiver {
-messages -> NetworkResourceLoader {
- WillSendRequestHandled(uint64_t requestID, WebCore::ResourceRequest newRequest)
- CanAuthenticateAgainstProtectionSpaceHandled(uint64_t requestID, bool canAuthenticate)
-
- ReceivedAuthenticationCredential(WebCore::AuthenticationChallenge challenge, WebCore::Credential credential)
- ReceivedRequestToContinueWithoutAuthenticationCredential(WebCore::AuthenticationChallenge challenge)
- ReceivedAuthenticationCancellation(WebCore::AuthenticationChallenge challenge)
+ ContinueWillSendRequest(WebCore::ResourceRequest request)
+ ContinueDidReceiveResponse()
+ ContinueCanAuthenticateAgainstProtectionSpace(bool canAuthenticate)
}
-
-#endif // ENABLE(NETWORK_PROCESS)
diff --git a/Source/WebKit2/NetworkProcess/SchedulableLoader.cpp b/Source/WebKit2/NetworkProcess/SchedulableLoader.cpp
new file mode 100644
index 000000000..ae7b20397
--- /dev/null
+++ b/Source/WebKit2/NetworkProcess/SchedulableLoader.cpp
@@ -0,0 +1,118 @@
+/*
+ * Copyright (C) 2013 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 "SchedulableLoader.h"
+
+#if ENABLE(NETWORK_PROCESS)
+
+#include "NetworkBlobRegistry.h"
+#include "NetworkConnectionToWebProcess.h"
+#include "NetworkResourceLoadParameters.h"
+#include <WebCore/FormData.h>
+
+using namespace WebCore;
+
+namespace WebKit {
+
+SchedulableLoader::SchedulableLoader(const NetworkResourceLoadParameters& parameters, NetworkConnectionToWebProcess* connection)
+ : m_identifier(parameters.identifier)
+ , m_webPageID(parameters.webPageID)
+ , m_webFrameID(parameters.webFrameID)
+ , m_request(parameters.request)
+ , m_priority(parameters.priority)
+ , m_contentSniffingPolicy(parameters.contentSniffingPolicy)
+ , m_allowStoredCredentials(parameters.allowStoredCredentials)
+ , m_clientCredentialPolicy(parameters.clientCredentialPolicy)
+ , m_inPrivateBrowsingMode(parameters.inPrivateBrowsingMode)
+ , m_shouldClearReferrerOnHTTPSToHTTPRedirect(parameters.shouldClearReferrerOnHTTPSToHTTPRedirect)
+ , m_isLoadingMainResource(parameters.isMainResource)
+ , m_sandboxExtensionsAreConsumed(false)
+ , m_connection(connection)
+{
+ // Either this loader has both a webPageID and webFrameID, or it is not allowed to ask the client for authentication credentials.
+ // FIXME: This is necessary because of the existence of EmptyFrameLoaderClient in WebCore.
+ // Once bug 116233 is resolved, this ASSERT can just be "m_webPageID && m_webFrameID"
+ ASSERT((m_webPageID && m_webFrameID) || m_clientCredentialPolicy == DoNotAskClientForAnyCredentials);
+
+ for (size_t i = 0, count = parameters.requestBodySandboxExtensions.size(); i < count; ++i) {
+ if (RefPtr<SandboxExtension> extension = SandboxExtension::create(parameters.requestBodySandboxExtensions[i]))
+ m_requestBodySandboxExtensions.append(extension);
+ }
+
+#if ENABLE(BLOB)
+ if (m_request.httpBody()) {
+ const Vector<FormDataElement>& elements = m_request.httpBody()->elements();
+ for (size_t i = 0, count = elements.size(); i < count; ++i) {
+ if (elements[i].m_type == FormDataElement::encodedBlob) {
+ Vector<RefPtr<SandboxExtension>> blobElementExtensions = NetworkBlobRegistry::shared().sandboxExtensions(elements[i].m_url);
+ m_requestBodySandboxExtensions.appendVector(blobElementExtensions);
+ }
+ }
+ }
+
+ if (m_request.url().protocolIs("blob")) {
+ ASSERT(!SandboxExtension::create(parameters.resourceSandboxExtension));
+ m_resourceSandboxExtensions = NetworkBlobRegistry::shared().sandboxExtensions(m_request.url());
+ } else
+#endif
+ if (RefPtr<SandboxExtension> resourceSandboxExtension = SandboxExtension::create(parameters.resourceSandboxExtension))
+ m_resourceSandboxExtensions.append(resourceSandboxExtension);
+}
+
+SchedulableLoader::~SchedulableLoader()
+{
+ ASSERT(!m_hostRecord);
+}
+
+void SchedulableLoader::consumeSandboxExtensions()
+{
+ for (size_t i = 0, count = m_requestBodySandboxExtensions.size(); i < count; ++i)
+ m_requestBodySandboxExtensions[i]->consume();
+
+ for (size_t i = 0, count = m_resourceSandboxExtensions.size(); i < count; ++i)
+ m_resourceSandboxExtensions[i]->consume();
+
+ m_sandboxExtensionsAreConsumed = true;
+}
+
+void SchedulableLoader::invalidateSandboxExtensions()
+{
+ if (m_sandboxExtensionsAreConsumed) {
+ for (size_t i = 0, count = m_requestBodySandboxExtensions.size(); i < count; ++i)
+ m_requestBodySandboxExtensions[i]->revoke();
+ for (size_t i = 0, count = m_resourceSandboxExtensions.size(); i < count; ++i)
+ m_resourceSandboxExtensions[i]->revoke();
+ }
+
+ m_requestBodySandboxExtensions.clear();
+ m_resourceSandboxExtensions.clear();
+
+ m_sandboxExtensionsAreConsumed = false;
+}
+
+} // namespace WebKit
+
+#endif // ENABLE(NETWORK_PROCESS)
diff --git a/Source/WebKit2/NetworkProcess/SchedulableLoader.h b/Source/WebKit2/NetworkProcess/SchedulableLoader.h
new file mode 100644
index 000000000..81ff5e5ce
--- /dev/null
+++ b/Source/WebKit2/NetworkProcess/SchedulableLoader.h
@@ -0,0 +1,102 @@
+/*
+ * Copyright (C) 2013 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 SchedulableLoader_h
+#define SchedulableLoader_h
+
+#include "HostRecord.h"
+#include <WebCore/ResourceLoaderOptions.h>
+#include <WebCore/ResourceRequest.h>
+#include <wtf/MainThread.h>
+#include <wtf/RefCounted.h>
+
+#if ENABLE(NETWORK_PROCESS)
+
+namespace WebKit {
+
+class NetworkConnectionToWebProcess;
+class NetworkResourceLoadParameters;
+class SandboxExtension;
+
+class SchedulableLoader : public RefCounted<SchedulableLoader> {
+public:
+ virtual ~SchedulableLoader();
+
+ ResourceLoadIdentifier identifier() const { return m_identifier; }
+ uint64_t webPageID() const { return m_webPageID; }
+ uint64_t webFrameID() const { return m_webFrameID; }
+ const WebCore::ResourceRequest& request() const { return m_request; }
+ WebCore::ResourceLoadPriority priority() const { return m_priority; }
+ WebCore::ContentSniffingPolicy contentSniffingPolicy() const { return m_contentSniffingPolicy; }
+ WebCore::StoredCredentials allowStoredCredentials() const { return m_allowStoredCredentials; }
+ WebCore::ClientCredentialPolicy clientCredentialPolicy() const { return m_clientCredentialPolicy; }
+ bool inPrivateBrowsingMode() const { return m_inPrivateBrowsingMode; }
+ bool isLoadingMainResource() const { return m_isLoadingMainResource; }
+
+ NetworkConnectionToWebProcess* connectionToWebProcess() const { return m_connection.get(); }
+
+ virtual void start() = 0;
+ virtual void abort() = 0;
+
+ virtual bool isSynchronous() { return false; }
+
+ void setHostRecord(HostRecord* hostRecord) { ASSERT(isMainThread()); m_hostRecord = hostRecord; }
+ HostRecord* hostRecord() const { ASSERT(isMainThread()); return m_hostRecord.get(); }
+
+protected:
+ SchedulableLoader(const NetworkResourceLoadParameters&, NetworkConnectionToWebProcess*);
+
+ void consumeSandboxExtensions();
+ void invalidateSandboxExtensions();
+
+ bool shouldClearReferrerOnHTTPSToHTTPRedirect() const { return m_shouldClearReferrerOnHTTPSToHTTPRedirect; }
+
+private:
+ ResourceLoadIdentifier m_identifier;
+ uint64_t m_webPageID;
+ uint64_t m_webFrameID;
+ WebCore::ResourceRequest m_request;
+ WebCore::ResourceLoadPriority m_priority;
+ WebCore::ContentSniffingPolicy m_contentSniffingPolicy;
+ WebCore::StoredCredentials m_allowStoredCredentials;
+ WebCore::ClientCredentialPolicy m_clientCredentialPolicy;
+ bool m_inPrivateBrowsingMode;
+ bool m_shouldClearReferrerOnHTTPSToHTTPRedirect;
+ bool m_isLoadingMainResource;
+
+ Vector<RefPtr<SandboxExtension>> m_requestBodySandboxExtensions;
+ Vector<RefPtr<SandboxExtension>> m_resourceSandboxExtensions;
+ bool m_sandboxExtensionsAreConsumed;
+
+ RefPtr<NetworkConnectionToWebProcess> m_connection;
+
+ RefPtr<HostRecord> m_hostRecord;
+};
+
+} // namespace WebKit
+
+#endif // ENABLE(NETWORK_PROCESS)
+
+#endif // SchedulableLoader_h
diff --git a/Source/WebKit2/NetworkProcess/SyncNetworkResourceLoader.cpp b/Source/WebKit2/NetworkProcess/SyncNetworkResourceLoader.cpp
new file mode 100644
index 000000000..02b05ed7d
--- /dev/null
+++ b/Source/WebKit2/NetworkProcess/SyncNetworkResourceLoader.cpp
@@ -0,0 +1,87 @@
+/*
+ * Copyright (C) 2013 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 "SyncNetworkResourceLoader.h"
+
+#if ENABLE(NETWORK_PROCESS)
+
+#include "DataReference.h"
+#include "NetworkProcess.h"
+#include "RemoteNetworkingContext.h"
+#include <WebCore/ResourceError.h>
+#include <WebCore/ResourceHandle.h>
+#include <WebCore/ResourceResponse.h>
+#include <wtf/MainThread.h>
+
+using namespace WebCore;
+
+namespace WebKit {
+
+SyncNetworkResourceLoader::SyncNetworkResourceLoader(const NetworkResourceLoadParameters& parameters, NetworkConnectionToWebProcess* connection, PassRefPtr<Messages::NetworkConnectionToWebProcess::PerformSynchronousLoad::DelayedReply> reply)
+ : SchedulableLoader(parameters, connection)
+ , m_delayedReply(reply)
+{
+}
+
+void SyncNetworkResourceLoader::start()
+{
+ // FIXME (NetworkProcess): This is called on the NetworkProcess main thread, blocking any other requests from being scheduled.
+ // This should move to a background thread, but we'd either need to be sure that:
+ // A - ResourceHandle::loadResourceSynchronously is safe to run on a background thread.
+ // B - Write custom loading logic that is known to be safe on a background thread.
+
+ ASSERT(isMainThread());
+
+ ResourceError error;
+ ResourceResponse response;
+ Vector<char> data;
+
+ // FIXME (NetworkProcess): Create RemoteNetworkingContext with actual settings.
+ RefPtr<RemoteNetworkingContext> networkingContext = RemoteNetworkingContext::create(false, false, inPrivateBrowsingMode(), shouldClearReferrerOnHTTPSToHTTPRedirect());
+
+ consumeSandboxExtensions();
+
+ ResourceHandle::loadResourceSynchronously(networkingContext.get(), request(), allowStoredCredentials(), error, response, data);
+
+ cleanup();
+
+ m_delayedReply->send(error, response, CoreIPC::DataReference((uint8_t*)data.data(), data.size()));
+}
+
+void SyncNetworkResourceLoader::abort()
+{
+ cleanup();
+}
+
+void SyncNetworkResourceLoader::cleanup()
+{
+ invalidateSandboxExtensions();
+ NetworkProcess::shared().networkResourceLoadScheduler().scheduleRemoveLoader(this);
+}
+
+} // namespace WebKit
+
+#endif // ENABLE(NETWORK_PROCESS)
diff --git a/Source/WebKit2/NetworkProcess/SyncNetworkResourceLoader.h b/Source/WebKit2/NetworkProcess/SyncNetworkResourceLoader.h
new file mode 100644
index 000000000..a60929b76
--- /dev/null
+++ b/Source/WebKit2/NetworkProcess/SyncNetworkResourceLoader.h
@@ -0,0 +1,61 @@
+/*
+ * Copyright (C) 2013 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 SyncNetworkResourceLoader_h
+#define SyncNetworkResourceLoader_h
+
+#include "NetworkConnectionToWebProcessMessages.h"
+#include "SchedulableLoader.h"
+#include <wtf/RefCounted.h>
+
+#if ENABLE(NETWORK_PROCESS)
+
+namespace WebKit {
+
+class SyncNetworkResourceLoader : public SchedulableLoader {
+public:
+ static PassRefPtr<SyncNetworkResourceLoader> create(const NetworkResourceLoadParameters& parameters, NetworkConnectionToWebProcess* connection, PassRefPtr<Messages::NetworkConnectionToWebProcess::PerformSynchronousLoad::DelayedReply> reply)
+ {
+ return adoptRef(new SyncNetworkResourceLoader(parameters, connection, reply));
+ }
+
+ virtual void start() OVERRIDE;
+ virtual void abort() OVERRIDE;
+
+ virtual bool isSynchronous() OVERRIDE { return true; }
+
+private:
+ SyncNetworkResourceLoader(const NetworkResourceLoadParameters&, NetworkConnectionToWebProcess*, PassRefPtr<Messages::NetworkConnectionToWebProcess::PerformSynchronousLoad::DelayedReply>);
+
+ void cleanup();
+
+ RefPtr<Messages::NetworkConnectionToWebProcess::PerformSynchronousLoad::DelayedReply> m_delayedReply;
+};
+
+} // namespace WebKit
+
+#endif // ENABLE(NETWORK_PROCESS)
+
+#endif // SyncNetworkResourceLoader_h
diff --git a/Source/WebKit2/NetworkProcess/mac/DiskCacheMonitor.h b/Source/WebKit2/NetworkProcess/mac/DiskCacheMonitor.h
new file mode 100644
index 000000000..c137995e5
--- /dev/null
+++ b/Source/WebKit2/NetworkProcess/mac/DiskCacheMonitor.h
@@ -0,0 +1,60 @@
+/*
+ * Copyright (C) 2013 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 DiskCacheMonitor_h
+#define DiskCacheMonitor_h
+
+#include "MessageSender.h"
+#include <WebCore/ResourceRequest.h>
+#include <WebCore/RunLoop.h>
+
+typedef const struct _CFCachedURLResponse* CFCachedURLResponseRef;
+
+namespace WebKit {
+
+class NetworkConnectionToWebProcess;
+class NetworkResourceLoader;
+
+class DiskCacheMonitor : public CoreIPC::MessageSender {
+public:
+ static void monitorFileBackingStoreCreation(CFCachedURLResponseRef, NetworkResourceLoader*);
+
+ const WebCore::ResourceRequest& resourceRequest() const { return m_resourceRequest; }
+
+private:
+ DiskCacheMonitor(CFCachedURLResponseRef, NetworkResourceLoader*);
+
+ // CoreIPC::MessageSender
+ virtual CoreIPC::Connection* messageSenderConnection() OVERRIDE;
+ virtual uint64_t messageSenderDestinationID() OVERRIDE;
+
+ RefPtr<NetworkConnectionToWebProcess> m_connectionToWebProcess;
+ WebCore::ResourceRequest m_resourceRequest;
+};
+
+
+} // namespace WebKit
+
+#endif // DiskCacheMonitor_h
diff --git a/Source/WebKit2/NetworkProcess/mac/DiskCacheMonitor.mm b/Source/WebKit2/NetworkProcess/mac/DiskCacheMonitor.mm
new file mode 100644
index 000000000..34c81e61d
--- /dev/null
+++ b/Source/WebKit2/NetworkProcess/mac/DiskCacheMonitor.mm
@@ -0,0 +1,109 @@
+/*
+ * Copyright (C) 2013 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.
+ */
+
+#import "config.h"
+#import "DiskCacheMonitor.h"
+
+#import "NetworkConnectionToWebProcess.h"
+#import "NetworkProcessConnectionMessages.h"
+#import "NetworkResourceLoader.h"
+#import "WebCoreArgumentCoders.h"
+
+#ifdef __has_include
+#if __has_include(<CFNetwork/CFURLCachePriv.h>)
+#include <CFNetwork/CFURLCachePriv.h>
+#endif
+#endif
+
+#if __MAC_OS_X_VERSION_MIN_REQUIRED >= 1090
+
+typedef void (^CFCachedURLResponseCallBackBlock)(CFCachedURLResponseRef);
+extern "C" void _CFCachedURLResponseSetBecameFileBackedCallBackBlock(CFCachedURLResponseRef, CFCachedURLResponseCallBackBlock, dispatch_queue_t);
+
+using namespace WebCore;
+
+namespace WebKit {
+
+// The maximum number of seconds we'll try to wait for a resource to be disk cached before we forget the request.
+static const double diskCacheMonitorTimeout = 20;
+
+void DiskCacheMonitor::monitorFileBackingStoreCreation(CFCachedURLResponseRef cachedResponse, NetworkResourceLoader* loader)
+{
+ if (!cachedResponse)
+ return;
+
+ ASSERT(loader);
+
+ new DiskCacheMonitor(cachedResponse, loader); // Balanced by adoptPtr in the blocks setup in the constructor, one of which is guaranteed to run.
+}
+
+DiskCacheMonitor::DiskCacheMonitor(CFCachedURLResponseRef cachedResponse, NetworkResourceLoader* loader)
+ : m_connectionToWebProcess(loader->connectionToWebProcess())
+ , m_resourceRequest(loader->request())
+{
+ ASSERT(isMainThread());
+
+ // Set up a delayed callback to cancel this monitor if the resource hasn't been cached yet.
+ __block DiskCacheMonitor* rawMonitor = this;
+
+ dispatch_after(dispatch_time(DISPATCH_TIME_NOW, NSEC_PER_SEC * diskCacheMonitorTimeout), dispatch_get_main_queue(), ^{
+ adoptPtr(rawMonitor); // Balanced by `new DiskCacheMonitor` in monitorFileBackingStoreCreation.
+ rawMonitor = 0;
+ });
+
+ // Set up the disk caching callback to create the ShareableResource and send it to the WebProcess.
+ CFCachedURLResponseCallBackBlock block = ^(CFCachedURLResponseRef cachedResponse)
+ {
+ // If the monitor isn't there then it timed out before this resource was cached to disk.
+ if (!rawMonitor)
+ return;
+
+ OwnPtr<DiskCacheMonitor> monitor = adoptPtr(rawMonitor); // Balanced by `new DiskCacheMonitor` in monitorFileBackingStoreCreation.
+ rawMonitor = 0;
+
+ ShareableResource::Handle handle;
+ NetworkResourceLoader::tryGetShareableHandleFromCFURLCachedResponse(handle, cachedResponse);
+ if (handle.isNull())
+ return;
+
+ monitor->send(Messages::NetworkProcessConnection::DidCacheResource(monitor->resourceRequest(), handle));
+ };
+
+ _CFCachedURLResponseSetBecameFileBackedCallBackBlock(cachedResponse, block, dispatch_get_main_queue());
+}
+
+CoreIPC::Connection* DiskCacheMonitor::messageSenderConnection()
+{
+ return m_connectionToWebProcess->connection();
+}
+
+uint64_t DiskCacheMonitor::messageSenderDestinationID()
+{
+ return 0;
+}
+
+} // namespace WebKit
+
+#endif // #if __MAC_OS_X_VERSION_MIN_REQUIRED >= 1090
diff --git a/Source/WebKit2/NetworkProcess/mac/NetworkProcessMac.mm b/Source/WebKit2/NetworkProcess/mac/NetworkProcessMac.mm
index e635acb19..3e96fa4dc 100644
--- a/Source/WebKit2/NetworkProcess/mac/NetworkProcessMac.mm
+++ b/Source/WebKit2/NetworkProcess/mac/NetworkProcessMac.mm
@@ -29,22 +29,203 @@
#if ENABLE(NETWORK_PROCESS)
#import "NetworkProcessCreationParameters.h"
+#import "NetworkResourceLoader.h"
+#import "PlatformCertificateInfo.h"
+#import "ResourceCachesToClear.h"
+#import "SandboxExtension.h"
+#import "SandboxInitializationParameters.h"
+#import "StringUtilities.h"
+#import <WebCore/FileSystem.h>
#import <WebCore/LocalizedStrings.h>
#import <WebKitSystemInterface.h>
+#import <mach/host_info.h>
+#import <mach/mach.h>
+#import <mach/mach_error.h>
+#import <sysexits.h>
#import <wtf/text/WTFString.h>
+#if USE(SECURITY_FRAMEWORK)
+#import "SecItemShim.h"
+#endif
+
+#if __MAC_OS_X_VERSION_MIN_REQUIRED >= 1090
+typedef struct _CFURLCache* CFURLCacheRef;
+extern "C" CFURLCacheRef CFURLCacheCopySharedURLCache();
+extern "C" void _CFURLCacheSetMinSizeForVMCachedResource(CFURLCacheRef, CFIndex);
+#endif
+
using namespace WebCore;
+@interface NSURLRequest (Details)
++ (void)setAllowsSpecificHTTPSCertificate:(NSArray *)allow forHost:(NSString *)host;
+@end
+
namespace WebKit {
-void NetworkProcess::platformInitialize(const NetworkProcessCreationParameters& parameters)
+void NetworkProcess::initializeProcess(const ChildProcessInitializationParameters&)
{
- NSString *applicationName = [NSString stringWithFormat:WEB_UI_STRING("%@ Networking", "visible name of the network process. The argument is the application name."),
- (NSString *)parameters.parentProcessName];
-
+ // Having a window server connection in this process would result in spin logs (<rdar://problem/13239119>).
+ setApplicationIsDaemon();
+}
+
+void NetworkProcess::initializeProcessName(const ChildProcessInitializationParameters& parameters)
+{
+ NSString *applicationName = [NSString stringWithFormat:WEB_UI_STRING("%@ Networking", "visible name of the network process. The argument is the application name."), (NSString *)parameters.uiProcessName];
WKSetVisibleApplicationName((CFStringRef)applicationName);
}
+#if __MAC_OS_X_VERSION_MIN_REQUIRED >= 1070
+static void overrideSystemProxies(const String& httpProxy, const String& httpsProxy)
+{
+ NSMutableDictionary *proxySettings = [NSMutableDictionary dictionary];
+
+ if (!httpProxy.isNull()) {
+ KURL httpProxyURL(KURL(), httpProxy);
+ if (httpProxyURL.isValid()) {
+ [proxySettings setObject:nsStringFromWebCoreString(httpProxyURL.host()) forKey:(NSString *)kCFNetworkProxiesHTTPProxy];
+ if (httpProxyURL.hasPort()) {
+ NSNumber *port = [NSNumber numberWithInt:httpProxyURL.port()];
+ [proxySettings setObject:port forKey:(NSString *)kCFNetworkProxiesHTTPPort];
+ }
+ }
+ else
+ NSLog(@"Malformed HTTP Proxy URL '%s'. Expected 'http://<hostname>[:<port>]'\n", httpProxy.utf8().data());
+ }
+
+ if (!httpsProxy.isNull()) {
+ KURL httpsProxyURL(KURL(), httpsProxy);
+ if (httpsProxyURL.isValid()) {
+ [proxySettings setObject:nsStringFromWebCoreString(httpsProxyURL.host()) forKey:(NSString *)kCFNetworkProxiesHTTPSProxy];
+ if (httpsProxyURL.hasPort()) {
+ NSNumber *port = [NSNumber numberWithInt:httpsProxyURL.port()];
+ [proxySettings setObject:port forKey:(NSString *)kCFNetworkProxiesHTTPSPort];
+ }
+ } else
+ NSLog(@"Malformed HTTPS Proxy URL '%s'. Expected 'https://<hostname>[:<port>]'\n", httpsProxy.utf8().data());
+ }
+
+ if ([proxySettings count] > 0)
+ WKCFNetworkSetOverrideSystemProxySettings((CFDictionaryRef)proxySettings);
+}
+#endif // __MAC_OS_X_VERSION_MIN_REQUIRED >= 1070
+
+void NetworkProcess::platformInitializeNetworkProcess(const NetworkProcessCreationParameters& parameters)
+{
+ m_diskCacheDirectory = parameters.diskCacheDirectory;
+
+ if (!m_diskCacheDirectory.isNull()) {
+ SandboxExtension::consumePermanently(parameters.diskCacheDirectoryExtensionHandle);
+ [NSURLCache setSharedURLCache:adoptNS([[NSURLCache alloc]
+ initWithMemoryCapacity:parameters.nsURLCacheMemoryCapacity
+ diskCapacity:parameters.nsURLCacheDiskCapacity
+ diskPath:parameters.diskCacheDirectory]).get()];
+ }
+
+#if USE(SECURITY_FRAMEWORK)
+ SecItemShim::shared().initialize(this);
+#endif
+
+#if __MAC_OS_X_VERSION_MIN_REQUIRED >= 1070
+ if (!parameters.httpProxy.isNull() || !parameters.httpsProxy.isNull())
+ overrideSystemProxies(parameters.httpProxy, parameters.httpsProxy);
+#endif
+
+#if __MAC_OS_X_VERSION_MIN_REQUIRED >= 1090
+ RetainPtr<CFURLCacheRef> cache = adoptCF(CFURLCacheCopySharedURLCache());
+ if (!cache)
+ return;
+
+ _CFURLCacheSetMinSizeForVMCachedResource(cache.get(), NetworkResourceLoader::fileBackedResourceMinimumSize());
+#endif
+}
+
+static uint64_t memorySize()
+{
+ static host_basic_info_data_t hostInfo;
+
+ static dispatch_once_t once;
+ dispatch_once(&once, ^() {
+ mach_port_t host = mach_host_self();
+ mach_msg_type_number_t count = HOST_BASIC_INFO_COUNT;
+ kern_return_t r = host_info(host, HOST_BASIC_INFO, (host_info_t)&hostInfo, &count);
+ mach_port_deallocate(mach_task_self(), host);
+
+ if (r != KERN_SUCCESS)
+ LOG_ERROR("%s : host_info(%d) : %s.\n", __FUNCTION__, r, mach_error_string(r));
+ });
+
+ return hostInfo.max_mem;
+}
+
+static uint64_t volumeFreeSize(const String& path)
+{
+ NSDictionary *fileSystemAttributesDictionary = [[NSFileManager defaultManager] attributesOfFileSystemForPath:(NSString *)path error:NULL];
+ return [[fileSystemAttributesDictionary objectForKey:NSFileSystemFreeSize] unsignedLongLongValue];
+}
+
+void NetworkProcess::platformSetCacheModel(CacheModel cacheModel)
+{
+
+ // As a fudge factor, use 1000 instead of 1024, in case the reported byte
+ // count doesn't align exactly to a megabyte boundary.
+ uint64_t memSize = memorySize() / 1024 / 1000;
+ uint64_t diskFreeSize = volumeFreeSize(m_diskCacheDirectory) / 1024 / 1000;
+
+ unsigned cacheTotalCapacity = 0;
+ unsigned cacheMinDeadCapacity = 0;
+ unsigned cacheMaxDeadCapacity = 0;
+ double deadDecodedDataDeletionInterval = 0;
+ unsigned pageCacheCapacity = 0;
+ unsigned long urlCacheMemoryCapacity = 0;
+ unsigned long urlCacheDiskCapacity = 0;
+
+ calculateCacheSizes(cacheModel, memSize, diskFreeSize,
+ cacheTotalCapacity, cacheMinDeadCapacity, cacheMaxDeadCapacity, deadDecodedDataDeletionInterval,
+ pageCacheCapacity, urlCacheMemoryCapacity, urlCacheDiskCapacity);
+
+
+ NSURLCache *nsurlCache = [NSURLCache sharedURLCache];
+ [nsurlCache setMemoryCapacity:urlCacheMemoryCapacity];
+ [nsurlCache setDiskCapacity:std::max<unsigned long>(urlCacheDiskCapacity, [nsurlCache diskCapacity])]; // Don't shrink a big disk cache, since that would cause churn.
+}
+
+void NetworkProcess::allowSpecificHTTPSCertificateForHost(const PlatformCertificateInfo& certificateInfo, const String& host)
+{
+ [NSURLRequest setAllowsSpecificHTTPSCertificate:(NSArray *)certificateInfo.certificateChain() forHost:(NSString *)host];
+}
+
+void NetworkProcess::initializeSandbox(const ChildProcessInitializationParameters& parameters, SandboxInitializationParameters& sandboxParameters)
+{
+ // Need to overide the default, because service has a different bundle ID.
+ NSBundle *webkit2Bundle = [NSBundle bundleForClass:NSClassFromString(@"WKView")];
+ sandboxParameters.setOverrideSandboxProfilePath([webkit2Bundle pathForResource:@"com.apple.WebKit.NetworkProcess" ofType:@"sb"]);
+
+ ChildProcess::initializeSandbox(parameters, sandboxParameters);
+}
+
+void NetworkProcess::clearCacheForAllOrigins(uint32_t cachesToClear)
+{
+ ResourceCachesToClear resourceCachesToClear = static_cast<ResourceCachesToClear>(cachesToClear);
+ if (resourceCachesToClear == InMemoryResourceCachesOnly)
+ return;
+
+ if (!m_clearCacheDispatchGroup)
+ m_clearCacheDispatchGroup = dispatch_group_create();
+
+ dispatch_group_async(m_clearCacheDispatchGroup, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
+ [[NSURLCache sharedURLCache] removeAllCachedResponses];
+ });
+}
+
+void NetworkProcess::platformTerminate()
+{
+ if (m_clearCacheDispatchGroup) {
+ dispatch_group_wait(m_clearCacheDispatchGroup, DISPATCH_TIME_FOREVER);
+ dispatch_release(m_clearCacheDispatchGroup);
+ m_clearCacheDispatchGroup = 0;
+ }
+}
+
} // namespace WebKit
#endif // ENABLE(NETWORK_PROCESS)
diff --git a/Source/WebKit2/NetworkProcess/mac/NetworkProcessMainMac.mm b/Source/WebKit2/NetworkProcess/mac/NetworkProcessMainMac.mm
deleted file mode 100644
index c56f80a2a..000000000
--- a/Source/WebKit2/NetworkProcess/mac/NetworkProcessMainMac.mm
+++ /dev/null
@@ -1,99 +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.
- */
-
-#import "config.h"
-#import "NetworkProcessMain.h"
-
-#if ENABLE(NETWORK_PROCESS)
-
-#import "CommandLine.h"
-#import "EnvironmentUtilities.h"
-#import "NetworkProcess.h"
-#import <WebCore/RunLoop.h>
-#import <WebKitSystemInterface.h>
-#import <WebSystemInterface.h>
-#import <mach/mach_error.h>
-#import <runtime/InitializeThreading.h>
-#import <servers/bootstrap.h>
-#import <stdio.h>
-#import <wtf/MainThread.h>
-#import <wtf/RetainPtr.h>
-#import <wtf/text/CString.h>
-#import <wtf/text/WTFString.h>
-
-#define SHOW_CRASH_REPORTER 1
-
-using namespace WebCore;
-
-namespace WebKit {
-
-// FIXME: There is much code here that is duplicated in WebProcessMainMac.mm, we should add a shared base class where
-// we can put everything.
-
-int NetworkProcessMain(const CommandLine& commandLine)
-{
- String serviceName = commandLine["servicename"];
- if (serviceName.isEmpty())
- return EXIT_FAILURE;
-
- // Get the server port.
- mach_port_t serverPort;
- kern_return_t kr = bootstrap_look_up(bootstrap_port, serviceName.utf8().data(), &serverPort);
- if (kr) {
- WTFLogAlways("bootstrap_look_up result: %s (%x)\n", mach_error_string(kr), kr);
- return EXIT_FAILURE;
- }
-
- String localization = commandLine["localization"];
- RetainPtr<CFStringRef> cfLocalization(AdoptCF, CFStringCreateWithCharacters(0, reinterpret_cast<const UniChar*>(localization.characters()), localization.length()));
- if (cfLocalization)
- WKSetDefaultLocalization(cfLocalization.get());
-
-#if !SHOW_CRASH_REPORTER
- // Installs signal handlers that exit on a crash so that CrashReporter does not show up.
- signal(SIGILL, _exit);
- signal(SIGFPE, _exit);
- signal(SIGBUS, _exit);
- signal(SIGSEGV, _exit);
-#endif
-
- InitWebCoreSystemInterface();
- JSC::initializeThreading();
- WTF::initializeMainThread();
- RunLoop::initializeMainRunLoop();
-
- // Initialize the network process connection.
- NetworkProcess::shared().initialize(CoreIPC::Connection::Identifier(serverPort), RunLoop::main());
-
- [NSApplication sharedApplication];
-
- RunLoop::run();
-
- return 0;
-}
-
-} // namespace WebKit
-
-#endif // ENABLE(NETWORK_PROCESS)
diff --git a/Source/WebKit2/NetworkProcess/mac/NetworkResourceLoadSchedulerMac.mm b/Source/WebKit2/NetworkProcess/mac/NetworkResourceLoadSchedulerMac.mm
index 14b3657b9..15f21c47b 100644
--- a/Source/WebKit2/NetworkProcess/mac/NetworkResourceLoadSchedulerMac.mm
+++ b/Source/WebKit2/NetworkProcess/mac/NetworkResourceLoadSchedulerMac.mm
@@ -37,13 +37,15 @@ using namespace WebCore;
namespace WebKit {
-unsigned NetworkResourceLoadScheduler::platformInitializeMaximumHTTPConnectionCountPerHost()
+void NetworkResourceLoadScheduler::platformInitializeMaximumHTTPConnectionCountPerHost()
{
wkInitializeMaximumHTTPConnectionCountPerHost = WKInitializeMaximumHTTPConnectionCountPerHost;
wkSetHTTPPipeliningMaximumPriority = WKSetHTTPPipeliningMaximumPriority;
wkSetHTTPPipeliningMinimumFastLanePriority = WKSetHTTPPipeliningMinimumFastLanePriority;
- static const unsigned preferredConnectionCount = 6;
+ // Our preferred connection-per-host limit is the standard 6, but we need to let CFNetwork handle a 7th
+ // in case a synchronous XHRs is made while 6 loads are already outstanding.
+ static const unsigned preferredConnectionCount = 7;
static const unsigned unlimitedConnectionCount = 10000;
// Always set the connection count per host, even when pipelining.
@@ -60,10 +62,13 @@ unsigned NetworkResourceLoadScheduler::platformInitializeMaximumHTTPConnectionCo
wkSetHTTPPipeliningMinimumFastLanePriority(toHTTPPipeliningPriority(ResourceLoadPriorityMedium));
// When pipelining do not rate-limit requests sent from WebCore since CFNetwork handles that.
- return unlimitedConnectionCount;
+ m_maxRequestsInFlightPerHost = unlimitedConnectionCount;
+
+ return;
}
- return maximumHTTPConnectionCountPerHost;
+ // We've asked for one more connection per host than we intend to use in most cases so synch XHRs can bypass that limit.
+ m_maxRequestsInFlightPerHost = maximumHTTPConnectionCountPerHost - 1;
}
} // namespace WebKit
diff --git a/Source/WebKit2/NetworkProcess/mac/NetworkResourceLoaderMac.mm b/Source/WebKit2/NetworkProcess/mac/NetworkResourceLoaderMac.mm
new file mode 100644
index 000000000..84ea149c7
--- /dev/null
+++ b/Source/WebKit2/NetworkProcess/mac/NetworkResourceLoaderMac.mm
@@ -0,0 +1,116 @@
+/*
+ * Copyright (C) 2013 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.
+ */
+
+#import "config.h"
+#import "NetworkResourceLoader.h"
+
+#import "DiskCacheMonitor.h"
+#import "ShareableResource.h"
+#import <WebCore/ResourceHandle.h>
+#import <WebCore/SharedBuffer.h>
+
+using namespace WebCore;
+
+#ifdef __has_include
+#if __has_include(<CFNetwork/CFURLCache.h>)
+#include <CFNetwork/CFURLCache.h>
+#endif
+#if __has_include(<CFNetwork/CFURLCachePriv.h>)
+#include <CFNetwork/CFURLCachePriv.h>
+#endif
+#endif
+
+#if __MAC_OS_X_VERSION_MIN_REQUIRED >= 1090
+typedef const struct _CFURLCache* CFURLCacheRef;
+typedef const struct _CFCachedURLResponse* CFCachedURLResponseRef;
+extern "C" CFURLCacheRef CFURLCacheCopySharedURLCache();
+extern "C" CFCachedURLResponseRef CFURLCacheCopyResponseForRequest(CFURLCacheRef, CFURLRequestRef);
+extern "C" CFDataRef _CFCachedURLResponseGetMemMappedData(CFCachedURLResponseRef);
+extern "C" CFBooleanRef _CFURLCacheIsResponseDataMemMapped(CFURLCacheRef, CFDataRef);
+#endif
+
+@interface NSCachedURLResponse (NSCachedURLResponseDetails)
+-(CFCachedURLResponseRef)_CFCachedURLResponse;
+@end
+
+namespace WebKit {
+
+#if __MAC_OS_X_VERSION_MIN_REQUIRED >= 1090
+
+static void tryGetShareableHandleFromCFData(ShareableResource::Handle& handle, CFDataRef data)
+{
+ if (!data || CFDataGetLength(data) < (CFIndex)NetworkResourceLoader::fileBackedResourceMinimumSize())
+ return;
+
+ RefPtr<SharedMemory> sharedMemory = SharedMemory::createFromVMBuffer((void*)CFDataGetBytePtr(data), CFDataGetLength(data));
+ if (!sharedMemory) {
+ LOG_ERROR("Failed to create VM shared memory for cached resource.");
+ return;
+ }
+
+ size_t size = sharedMemory->size();
+ RefPtr<ShareableResource> resource = ShareableResource::create(sharedMemory.release(), 0, size);
+ resource->createHandle(handle);
+}
+
+void NetworkResourceLoader::tryGetShareableHandleFromCFURLCachedResponse(ShareableResource::Handle& handle, CFCachedURLResponseRef cachedResponse)
+{
+ CFDataRef data = _CFCachedURLResponseGetMemMappedData(cachedResponse);
+
+ tryGetShareableHandleFromCFData(handle, data);
+}
+
+void NetworkResourceLoader::tryGetShareableHandleFromSharedBuffer(ShareableResource::Handle& handle, SharedBuffer* buffer)
+{
+ RetainPtr<CFURLCacheRef> cache = adoptCF(CFURLCacheCopySharedURLCache());
+ if (!cache)
+ return;
+
+ RetainPtr<CFDataRef> data = adoptCF(buffer->createCFData());
+ if (_CFURLCacheIsResponseDataMemMapped(cache.get(), data.get()) == kCFBooleanFalse)
+ return;
+
+ tryGetShareableHandleFromCFData(handle, data.get());
+}
+#endif // __MAC_OS_X_VERSION_MIN_REQUIRED >= 1090
+
+size_t NetworkResourceLoader::fileBackedResourceMinimumSize()
+{
+ return SharedMemory::systemPageSize();
+}
+
+void NetworkResourceLoader::willCacheResponseAsync(ResourceHandle* handle, NSCachedURLResponse *nsResponse)
+{
+ ASSERT_UNUSED(handle, handle == m_handle);
+
+#if __MAC_OS_X_VERSION_MIN_REQUIRED >= 1090
+ if (m_bytesReceived >= fileBackedResourceMinimumSize())
+ DiskCacheMonitor::monitorFileBackingStoreCreation([nsResponse _CFCachedURLResponse], this);
+#endif
+
+ m_handle->continueWillCacheResponse(nsResponse);
+}
+
+} // namespace WebKit
diff --git a/Source/WebKit2/NetworkProcess/mac/RemoteNetworkingContext.h b/Source/WebKit2/NetworkProcess/mac/RemoteNetworkingContext.h
index 8f51186b4..d0402246b 100644
--- a/Source/WebKit2/NetworkProcess/mac/RemoteNetworkingContext.h
+++ b/Source/WebKit2/NetworkProcess/mac/RemoteNetworkingContext.h
@@ -32,25 +32,35 @@ namespace WebKit {
class RemoteNetworkingContext : public WebCore::NetworkingContext {
public:
- static PassRefPtr<RemoteNetworkingContext> create(bool needsSiteSpecificQuirks, bool localFileContentSniffingEnabled)
+ static PassRefPtr<RemoteNetworkingContext> create(bool needsSiteSpecificQuirks, bool localFileContentSniffingEnabled, bool privateBrowsingEnabled, bool shouldClearReferrerOnHTTPSToHTTPRedirect)
{
- return adoptRef(new RemoteNetworkingContext(needsSiteSpecificQuirks, localFileContentSniffingEnabled));
+ return adoptRef(new RemoteNetworkingContext(needsSiteSpecificQuirks, localFileContentSniffingEnabled, privateBrowsingEnabled, shouldClearReferrerOnHTTPSToHTTPRedirect));
}
virtual ~RemoteNetworkingContext();
+ static void setPrivateBrowsingStorageSessionIdentifierBase(const String&);
+ static void ensurePrivateBrowsingSession();
+ static void destroyPrivateBrowsingSession();
+
+ static WebCore::NetworkStorageSession* privateBrowsingSession();
+
+ virtual bool shouldClearReferrerOnHTTPSToHTTPRedirect() const OVERRIDE;
+
private:
- RemoteNetworkingContext(bool needsSiteSpecificQuirks, bool localFileContentSniffingEnabled);
+ RemoteNetworkingContext(bool needsSiteSpecificQuirks, bool localFileContentSniffingEnabled, bool privateBrowsingEnabled, bool m_shouldClearReferrerOnHTTPSToHTTPRedirect);
virtual bool isValid() const OVERRIDE;
virtual bool needsSiteSpecificQuirks() const OVERRIDE;
virtual bool localFileContentSniffingEnabled() const OVERRIDE;
- virtual CFURLStorageSessionRef storageSession() const OVERRIDE;
- virtual NSOperationQueue *scheduledOperationQueue() const OVERRIDE;
+ virtual WebCore::NetworkStorageSession& storageSession() const OVERRIDE;
+ virtual RetainPtr<CFDataRef> sourceApplicationAuditData() const OVERRIDE;
virtual WebCore::ResourceError blockedError(const WebCore::ResourceRequest&) const OVERRIDE;
bool m_needsSiteSpecificQuirks;
bool m_localFileContentSniffingEnabled;
+ bool m_privateBrowsingEnabled;
+ bool m_shouldClearReferrerOnHTTPSToHTTPRedirect;
};
}
diff --git a/Source/WebKit2/NetworkProcess/mac/RemoteNetworkingContext.mm b/Source/WebKit2/NetworkProcess/mac/RemoteNetworkingContext.mm
index 0eb7024f6..53ec91c5d 100644
--- a/Source/WebKit2/NetworkProcess/mac/RemoteNetworkingContext.mm
+++ b/Source/WebKit2/NetworkProcess/mac/RemoteNetworkingContext.mm
@@ -26,16 +26,33 @@
#import "config.h"
#import "RemoteNetworkingContext.h"
-#import "WebCore/ResourceError.h"
#import "WebErrors.h"
+#import <WebCore/ResourceError.h>
+#import <WebKitSystemInterface.h>
+#import <wtf/MainThread.h>
+#import <wtf/PassOwnPtr.h>
using namespace WebCore;
namespace WebKit {
-RemoteNetworkingContext::RemoteNetworkingContext(bool needsSiteSpecificQuirks, bool localFileContentSniffingEnabled)
+static OwnPtr<NetworkStorageSession>& privateBrowsingStorageSession()
+{
+ ASSERT(isMainThread());
+ DEFINE_STATIC_LOCAL(OwnPtr<NetworkStorageSession>, session, ());
+ return session;
+}
+
+bool RemoteNetworkingContext::shouldClearReferrerOnHTTPSToHTTPRedirect() const
+{
+ return m_shouldClearReferrerOnHTTPSToHTTPRedirect;
+}
+
+RemoteNetworkingContext::RemoteNetworkingContext(bool needsSiteSpecificQuirks, bool localFileContentSniffingEnabled, bool privateBrowsingEnabled, bool shouldClearReferrerOnHTTPSToHTTPRedirect)
: m_needsSiteSpecificQuirks(needsSiteSpecificQuirks)
, m_localFileContentSniffingEnabled(localFileContentSniffingEnabled)
+ , m_privateBrowsingEnabled(privateBrowsingEnabled)
+ , m_shouldClearReferrerOnHTTPSToHTTPRedirect(shouldClearReferrerOnHTTPSToHTTPRedirect)
{
}
@@ -58,21 +75,28 @@ bool RemoteNetworkingContext::localFileContentSniffingEnabled() const
return m_localFileContentSniffingEnabled;
}
-CFURLStorageSessionRef RemoteNetworkingContext::storageSession() const
+NetworkStorageSession& RemoteNetworkingContext::storageSession() const
{
- // FIXME (NetworkProcess): Implement.
- return 0;
+ if (m_privateBrowsingEnabled) {
+ NetworkStorageSession* privateSession = privateBrowsingStorageSession().get();
+ if (privateSession)
+ return *privateSession;
+ // Some requests with private browsing mode requested may still be coming shortly after NetworkProcess was told to destroy its session.
+ // FIXME: Find a way to track private browsing sessions more rigorously.
+ LOG_ERROR("Private browsing was requested, but there was no session for it. Please file a bug unless you just disabled private browsing, in which case it's an expected race.");
+ }
+
+ return NetworkStorageSession::defaultStorageSession();
}
-NSOperationQueue *RemoteNetworkingContext::scheduledOperationQueue() const
+NetworkStorageSession* RemoteNetworkingContext::privateBrowsingSession()
{
- static NSOperationQueue *queue;
- if (!queue) {
- queue = [[NSOperationQueue alloc] init];
- // Default concurrent operation count depends on current system workload, but delegate methods are mostly idling in IPC, so we can run as many as needed.
- [queue setMaxConcurrentOperationCount:NSIntegerMax];
- }
- return queue;
+ return privateBrowsingStorageSession().get();
+}
+
+RetainPtr<CFDataRef> RemoteNetworkingContext::sourceApplicationAuditData() const
+{
+ return nil;
}
ResourceError RemoteNetworkingContext::blockedError(const ResourceRequest& request) const
@@ -80,4 +104,32 @@ ResourceError RemoteNetworkingContext::blockedError(const ResourceRequest& reque
return WebKit::blockedError(request);
}
+static String& privateBrowsingStorageSessionIdentifierBase()
+{
+ ASSERT(isMainThread());
+ DEFINE_STATIC_LOCAL(String, base, ());
+ return base;
+}
+
+void RemoteNetworkingContext::setPrivateBrowsingStorageSessionIdentifierBase(const String& identifier)
+{
+ privateBrowsingStorageSessionIdentifierBase() = identifier;
+}
+
+void RemoteNetworkingContext::ensurePrivateBrowsingSession()
+{
+ if (privateBrowsingStorageSession())
+ return;
+
+ ASSERT(!privateBrowsingStorageSessionIdentifierBase().isNull());
+ RetainPtr<CFStringRef> cfIdentifier = String(privateBrowsingStorageSessionIdentifierBase() + ".PrivateBrowsing").createCFString();
+
+ privateBrowsingStorageSession() = NetworkStorageSession::createPrivateBrowsingSession(privateBrowsingStorageSessionIdentifierBase());
+}
+
+void RemoteNetworkingContext::destroyPrivateBrowsingSession()
+{
+ privateBrowsingStorageSession() = nullptr;
+}
+
}
diff --git a/Source/WebKit2/NetworkProcess/mac/com.apple.WebKit.NetworkProcess.sb.in b/Source/WebKit2/NetworkProcess/mac/com.apple.WebKit.NetworkProcess.sb.in
new file mode 100644
index 000000000..7ba86c038
--- /dev/null
+++ b/Source/WebKit2/NetworkProcess/mac/com.apple.WebKit.NetworkProcess.sb.in
@@ -0,0 +1,148 @@
+(version 1)
+(deny default (with partial-symbolication))
+(allow system-audit file-read-metadata)
+
+(import "system.sb")
+
+;; Utility functions for home directory relative path filters
+(define (home-regex home-relative-regex)
+ (regex (string-append "^" (regex-quote (param "HOME_DIR")) home-relative-regex)))
+
+(define (home-subpath home-relative-subpath)
+ (subpath (string-append (param "HOME_DIR") home-relative-subpath)))
+
+(define (home-literal home-relative-literal)
+ (literal (string-append (param "HOME_DIR") home-relative-literal)))
+
+#if __MAC_OS_X_VERSION_MIN_REQUIRED == 1070
+;; Low level networking. Defined in system.sb on newer OS versions.
+(define (system-network)
+ (allow file-read*
+ (literal "/Library/Preferences/com.apple.networkd.plist"))
+ (allow mach-lookup
+ (global-name "com.apple.SystemConfiguration.PPPController")
+ (global-name "com.apple.SystemConfiguration.SCNetworkReachability")
+ (global-name "com.apple.networkd"))
+ (allow network-outbound
+ (control-name "com.apple.netsrc")
+ (control-name "com.apple.network.statistics"))
+ (allow system-socket
+ (require-all (socket-domain AF_SYSTEM)
+ (socket-protocol 2)) ; SYSPROTO_CONTROL
+ (socket-domain AF_ROUTE)))
+#endif
+
+;; Read-only preferences and data
+(allow file-read*
+ ;; Basic system paths
+ (subpath "/Library/Frameworks")
+ (subpath "/Library/Managed Preferences")
+
+ ;; System and user preferences
+ (literal "/Library/Preferences/.GlobalPreferences.plist")
+ (regex #"^/Library/Managed Preferences/[^/]+/com\.apple\.networkConnect\.plist$")
+ (home-literal "/Library/Preferences/.GlobalPreferences.plist")
+ (home-regex #"/Library/Preferences/ByHost/\.GlobalPreferences\.")
+ (home-regex #"/Library/Preferences/ByHost/com\.apple\.networkConnect\.")
+ (home-literal "/Library/Preferences/com.apple.DownloadAssessment.plist")
+ (home-literal "/Library/Preferences/com.apple.WebFoundation.plist")
+
+ ;; On-disk WebKit2 framework location, to account for debug installations
+ ;; outside of /System/Library/Frameworks
+ (subpath (param "WEBKIT2_FRAMEWORK_DIR")))
+
+;; Sandbox extensions
+(define (apply-read-and-issue-extension op path-filter)
+ (op file-read* path-filter)
+ (op file-issue-extension (require-all (extension-class "com.apple.app-sandbox.read") path-filter)))
+(define (apply-write-and-issue-extension op path-filter)
+ (op file-write* path-filter)
+ (op file-issue-extension (require-all (extension-class "com.apple.app-sandbox.read-write") path-filter)))
+(define (read-only-and-issue-extensions path-filter)
+ (apply-read-and-issue-extension allow path-filter))
+(define (read-write-and-issue-extensions path-filter)
+ (apply-read-and-issue-extension allow path-filter)
+ (apply-write-and-issue-extension allow path-filter))
+(read-only-and-issue-extensions (extension "com.apple.app-sandbox.read"))
+(read-write-and-issue-extensions (extension "com.apple.app-sandbox.read-write"))
+
+#if __MAC_OS_X_VERSION_MIN_REQUIRED >= 1080
+(allow file-read* file-write* (subpath (param "DARWIN_USER_CACHE_DIR")))
+#else
+(allow file-read* file-write* (subpath (string-append (param "DARWIN_USER_CACHE_DIR") "/mds")))
+#endif
+
+(allow file-read* file-write* (subpath (param "DARWIN_USER_TEMP_DIR")))
+
+;; IOKit user clients
+(allow iokit-open
+ (iokit-user-client-class "RootDomainUserClient"))
+
+;; cookied.
+;; FIXME: Update for <rdar://problem/13642852>.
+(allow ipc-posix-shm-read-data
+ (ipc-posix-name "FNetwork.defaultStorageSession")
+ (ipc-posix-name-regex #"\.PrivateBrowsing-")
+ (ipc-posix-name-regex #"^Private WebKit Session-"))
+
+;; Various services required by CFNetwork and other frameworks
+(allow mach-lookup
+ (global-name "com.apple.PowerManagement.control")
+ (global-name "com.apple.SystemConfiguration.configd")
+ (global-name "com.apple.cookied")
+ (global-name "com.apple.cfnetwork.AuthBrokerAgent"))
+
+;; Security framework
+(allow mach-lookup
+ (global-name "com.apple.ocspd")
+ (global-name "com.apple.SecurityServer"))
+(allow file-read* file-write* (home-subpath "/Library/Keychains")) ;; FIXME: This should be removed when <rdar://problem/10479685> is fixed.
+(allow file-read* file-write* (subpath "/private/var/db/mds/system")) ;; FIXME: This should be removed when <rdar://problem/9538414> is fixed.
+(allow file-read*
+ (subpath "/Library/Keychains")
+ (subpath "/private/var/db/mds")
+ (literal "/private/var/db/DetachedSignatures")
+ (literal "/Library/Preferences/com.apple.crypto.plist")
+ (literal "/Library/Preferences/com.apple.security.plist")
+ (literal "/Library/Preferences/com.apple.security.common.plist")
+ (literal "/Library/Preferences/com.apple.security.revocation.plist")
+ (home-literal "/Library/Application Support/SyncServices/Local/ClientsWithChanges/com.apple.Keychain")
+ (home-literal "/Library/Preferences/com.apple.security.plist")
+ (home-literal "/Library/Preferences/com.apple.security.revocation.plist"))
+(allow ipc-posix-shm-read* ipc-posix-shm-write-data
+ (ipc-posix-name "com.apple.AppleDatabaseChanged"))
+
+(system-network)
+(allow network-outbound
+ ;; Local mDNSResponder for DNS, arbitrary outbound TCP
+ (literal "/private/var/run/mDNSResponder")
+ (remote tcp))
+
+;; FIXME should be removed when <rdar://problem/9347205> + related radar in Safari is fixed
+(allow mach-lookup
+ (global-name "org.h5l.kcm")
+ (global-name "com.apple.system.logger")
+ (global-name "com.apple.system.notification_center"))
+(allow network-outbound
+ (remote udp))
+(allow file-read*
+ (home-subpath "/Library/Preferences/com.apple.Kerberos.plist")
+ (home-subpath "/Library/Preferences/com.apple.GSS.plist")
+ (home-subpath "/Library/Preferences/edu.mit.Kerberos")
+ (literal "/Library/Preferences/com.apple.Kerberos.plist")
+ (literal "/Library/Preferences/com.apple.GSS.plist")
+ (literal "/Library/Preferences/edu.mit.Kerberos")
+ (literal "/private/etc/krb5.conf")
+ (literal "/private/etc/services")
+ (literal "/private/etc/host"))
+
+(if (defined? 'vnode-type)
+ (deny file-write-create (vnode-type SYMLINK)))
+
+(deny file-read* file-write* (with no-log)
+#if __MAC_OS_X_VERSION_MIN_REQUIRED <= 1080
+ (home-literal "/Library/Caches/Cache.db") ;; <rdar://problem/9422957>
+#endif
+ ;; FIXME: Should be removed after <rdar://problem/10463881> is fixed.
+ (home-literal "/Library/Preferences/com.apple.LaunchServices.QuarantineEventsV2")
+ (home-literal "/Library/Preferences/com.apple.LaunchServices.QuarantineEventsV2-journal"))
diff --git a/Source/WebKit2/NetworkProcess/unix/NetworkProcessMainUnix.cpp b/Source/WebKit2/NetworkProcess/unix/NetworkProcessMainUnix.cpp
new file mode 100644
index 000000000..c82af840e
--- /dev/null
+++ b/Source/WebKit2/NetworkProcess/unix/NetworkProcessMainUnix.cpp
@@ -0,0 +1,80 @@
+/*
+ * Copyright (C) 2013 Apple Inc. All rights reserved.
+ * Copyright (C) 2013 Company 100 Inc.
+ *
+ * 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 THE COPYRIGHT HOLDERS ``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 "NetworkProcessMainUnix.h"
+
+#if ENABLE(NETWORK_PROCESS)
+
+#include "WKBase.h"
+#include "WebKit2Initialize.h"
+#include <WebCore/RunLoop.h>
+#include <WebKit2/NetworkProcess.h>
+#include <error.h>
+#include <runtime/InitializeThreading.h>
+#include <stdlib.h>
+#include <wtf/MainThread.h>
+
+#if PLATFORM(EFL)
+#include <Ecore.h>
+#endif
+
+using namespace WebCore;
+
+namespace WebKit {
+
+WK_EXPORT int NetworkProcessMain(int argc, char* argv[])
+{
+ if (argc != 2)
+ return 1;
+
+#if PLATFORM(EFL)
+ if (!ecore_init())
+ return 1;
+
+ if (!ecore_main_loop_glib_integrate())
+ return 1;
+#endif
+
+ InitializeWebKit2();
+
+ // FIXME: handle proxy settings.
+
+ int socket = atoi(argv[1]);
+
+ WebKit::ChildProcessInitializationParameters parameters;
+ parameters.connectionIdentifier = int(socket);
+
+ NetworkProcess::shared().initialize(parameters);
+
+ RunLoop::run();
+
+ return 0;
+}
+
+} // namespace WebKit
+
+#endif // ENABLE(NETWORK_PROCESS)
diff --git a/Source/WebKit2/NetworkProcess/unix/NetworkProcessMainUnix.h b/Source/WebKit2/NetworkProcess/unix/NetworkProcessMainUnix.h
new file mode 100644
index 000000000..cb62eda2d
--- /dev/null
+++ b/Source/WebKit2/NetworkProcess/unix/NetworkProcessMainUnix.h
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2013 University of Szeged. All rights reserved.
+ * Copyright (C) 2013 Company 100 Inc.
+ *
+ * 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 NetworkProcessMainUnix_h
+#define NetworkProcessMainUnix_h
+
+#include <WebKit2/WKBase.h>
+
+namespace WebKit {
+
+#ifdef __cplusplus
+extern "C" {
+WK_EXPORT int NetworkProcessMain(int argc, char* argv[]);
+} // extern "C"
+#endif // __cplusplus
+
+} // namespace WebKit
+
+#endif // NetworkProcessMainUnix_h