c7faf043e39dced73757b2e74fb2a909856fc28b
[WebKit-https.git] / Source / WebKit / NetworkProcess / NetworkSession.cpp
1 /*
2  * Copyright (C) 2015-2019 Apple Inc. All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
7  * 1. Redistributions of source code must retain the above copyright
8  *    notice, this list of conditions and the following disclaimer.
9  * 2. Redistributions in binary form must reproduce the above copyright
10  *    notice, this list of conditions and the following disclaimer in the
11  *    documentation and/or other materials provided with the distribution.
12  *
13  * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
14  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
15  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
17  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
18  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
19  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
20  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
21  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
22  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
23  * THE POSSIBILITY OF SUCH DAMAGE.
24  */
25
26 #include "config.h"
27 #include "NetworkSession.h"
28
29 #include "AdClickAttributionManager.h"
30 #include "NetworkProcess.h"
31 #include "NetworkProcessProxyMessages.h"
32 #include "NetworkResourceLoadParameters.h"
33 #include "NetworkResourceLoader.h"
34 #include "PingLoad.h"
35 #include "StorageManager.h"
36 #include "WebPageProxy.h"
37 #include "WebPageProxyMessages.h"
38 #include "WebProcessProxy.h"
39 #include "WebSocketTask.h"
40 #include <WebCore/AdClickAttribution.h>
41 #include <WebCore/CookieJar.h>
42 #include <WebCore/NetworkStorageSession.h>
43 #include <WebCore/ResourceRequest.h>
44
45 #if PLATFORM(COCOA)
46 #include "NetworkSessionCocoa.h"
47 #endif
48 #if USE(SOUP)
49 #include "NetworkSessionSoup.h"
50 #endif
51 #if USE(CURL)
52 #include "NetworkSessionCurl.h"
53 #endif
54
55 namespace WebKit {
56 using namespace WebCore;
57
58 Ref<NetworkSession> NetworkSession::create(NetworkProcess& networkProcess, NetworkSessionCreationParameters&& parameters)
59 {
60 #if PLATFORM(COCOA)
61     return NetworkSessionCocoa::create(networkProcess, WTFMove(parameters));
62 #endif
63 #if USE(SOUP)
64     return NetworkSessionSoup::create(networkProcess, WTFMove(parameters));
65 #endif
66 #if USE(CURL)
67     return NetworkSessionCurl::create(networkProcess, WTFMove(parameters));
68 #endif
69 }
70
71 NetworkStorageSession* NetworkSession::networkStorageSession() const
72 {
73     // FIXME: https://bugs.webkit.org/show_bug.cgi?id=194926 NetworkSession should own NetworkStorageSession
74     // instead of having separate maps with the same key and different management.
75     auto* storageSession = m_networkProcess->storageSession(m_sessionID);
76     ASSERT(storageSession);
77     return storageSession;
78 }
79
80 NetworkSession::NetworkSession(NetworkProcess& networkProcess, PAL::SessionID sessionID, String&& localStorageDirectory, SandboxExtension::Handle& handle)
81     : m_sessionID(sessionID)
82     , m_networkProcess(networkProcess)
83     , m_adClickAttribution(makeUniqueRef<AdClickAttributionManager>(sessionID))
84     , m_storageManager(StorageManager::create(WTFMove(localStorageDirectory)))
85 {
86     SandboxExtension::consumePermanently(handle);
87     m_adClickAttribution->setPingLoadFunction([this, weakThis = makeWeakPtr(this)](NetworkResourceLoadParameters&& loadParameters, CompletionHandler<void(const WebCore::ResourceError&, const WebCore::ResourceResponse&)>&& completionHandler) {
88         if (!weakThis)
89             return;
90         // PingLoad manages its own lifetime, deleting itself when its purpose has been fulfilled.
91         new PingLoad(m_networkProcess, WTFMove(loadParameters), WTFMove(completionHandler));
92     });
93 }
94
95 NetworkSession::~NetworkSession()
96 {
97     m_storageManager->resume();
98     m_storageManager->waitUntilTasksFinished();
99 }
100
101 void NetworkSession::invalidateAndCancel()
102 {
103     for (auto* task : m_dataTaskSet)
104         task->invalidateAndCancel();
105 #if ENABLE(RESOURCE_LOAD_STATISTICS)
106     if (m_resourceLoadStatistics)
107         m_resourceLoadStatistics->invalidateAndCancel();
108 #endif
109 #if !ASSERT_DISABLED
110     m_isInvalidated = true;
111 #endif
112 }
113
114 #if ENABLE(RESOURCE_LOAD_STATISTICS)
115 void NetworkSession::setResourceLoadStatisticsEnabled(bool enable)
116 {
117     ASSERT(!m_isInvalidated);
118     if (!enable) {
119         m_resourceLoadStatistics = nullptr;
120         return;
121     }
122
123     if (m_resourceLoadStatistics)
124         return;
125
126     // FIXME(193728): Support ResourceLoadStatistics for ephemeral sessions, too.
127     if (m_sessionID.isEphemeral())
128         return;
129
130     m_resourceLoadStatistics = WebResourceLoadStatisticsStore::create(*this, m_resourceLoadStatisticsDirectory, m_shouldIncludeLocalhostInResourceLoadStatistics);
131
132     if (m_enableResourceLoadStatisticsDebugMode == EnableResourceLoadStatisticsDebugMode::Yes)
133         m_resourceLoadStatistics->setResourceLoadStatisticsDebugMode(true, [] { });
134     // This should always be forwarded since debug mode may be enabled at runtime.
135     if (!m_resourceLoadStatisticsManualPrevalentResource.isEmpty())
136         m_resourceLoadStatistics->setPrevalentResourceForDebugMode(m_resourceLoadStatisticsManualPrevalentResource, [] { });
137 }
138
139 void NetworkSession::notifyResourceLoadStatisticsProcessed()
140 {
141     m_networkProcess->parentProcessConnection()->send(Messages::NetworkProcessProxy::NotifyResourceLoadStatisticsProcessed(), 0);
142 }
143
144 void NetworkSession::logDiagnosticMessageWithValue(const String& message, const String& description, unsigned value, unsigned significantFigures, WebCore::ShouldSample shouldSample)
145 {
146     m_networkProcess->parentProcessConnection()->send(Messages::WebPageProxy::LogDiagnosticMessageWithValue(message, description, value, significantFigures, shouldSample), 0);
147 }
148
149 void NetworkSession::notifyPageStatisticsTelemetryFinished(unsigned totalPrevalentResources, unsigned totalPrevalentResourcesWithUserInteraction, unsigned top3SubframeUnderTopFrameOrigins)
150 {
151     m_networkProcess->parentProcessConnection()->send(Messages::NetworkProcessProxy::NotifyResourceLoadStatisticsTelemetryFinished(totalPrevalentResources, totalPrevalentResourcesWithUserInteraction, top3SubframeUnderTopFrameOrigins), 0);
152 }
153
154 void NetworkSession::deleteWebsiteDataForRegistrableDomains(OptionSet<WebsiteDataType> dataTypes, HashMap<RegistrableDomain, WebsiteDataToRemove>&& domains, bool shouldNotifyPage, CompletionHandler<void(const HashSet<RegistrableDomain>&)>&& completionHandler)
155 {
156     m_networkProcess->deleteWebsiteDataForRegistrableDomains(m_sessionID, dataTypes, WTFMove(domains), shouldNotifyPage, WTFMove(completionHandler));
157 }
158
159 void NetworkSession::registrableDomainsWithWebsiteData(OptionSet<WebsiteDataType> dataTypes, bool shouldNotifyPage, CompletionHandler<void(HashSet<RegistrableDomain>&&)>&& completionHandler)
160 {
161     m_networkProcess->registrableDomainsWithWebsiteData(m_sessionID, dataTypes, shouldNotifyPage, WTFMove(completionHandler));
162 }
163 #endif // ENABLE(RESOURCE_LOAD_STATISTICS)
164
165 void NetworkSession::storeAdClickAttribution(WebCore::AdClickAttribution&& adClickAttribution)
166 {
167     m_adClickAttribution->storeUnconverted(WTFMove(adClickAttribution));
168 }
169
170 void NetworkSession::handleAdClickAttributionConversion(AdClickAttribution::Conversion&& conversion, const URL& requestURL, const WebCore::ResourceRequest& redirectRequest)
171 {
172     m_adClickAttribution->handleConversion(WTFMove(conversion), requestURL, redirectRequest);
173 }
174
175 void NetworkSession::dumpAdClickAttribution(CompletionHandler<void(String)>&& completionHandler)
176 {
177     m_adClickAttribution->toString(WTFMove(completionHandler));
178 }
179
180 void NetworkSession::clearAdClickAttribution()
181 {
182     m_adClickAttribution->clear();
183 }
184
185 void NetworkSession::clearAdClickAttributionForRegistrableDomain(WebCore::RegistrableDomain&& domain)
186 {
187     m_adClickAttribution->clearForRegistrableDomain(WTFMove(domain));
188 }
189
190 void NetworkSession::setAdClickAttributionOverrideTimerForTesting(bool value)
191 {
192     m_adClickAttribution->setOverrideTimerForTesting(value);
193 }
194
195 void NetworkSession::setAdClickAttributionConversionURLForTesting(URL&& url)
196 {
197     m_adClickAttribution->setConversionURLForTesting(WTFMove(url));
198 }
199
200 void NetworkSession::markAdClickAttributionsAsExpiredForTesting()
201 {
202     m_adClickAttribution->markAllUnconvertedAsExpiredForTesting();
203 }
204
205 void NetworkSession::addKeptAliveLoad(Ref<NetworkResourceLoader>&& loader)
206 {
207     ASSERT(m_sessionID == loader->sessionID());
208     ASSERT(!m_keptAliveLoads.contains(loader));
209     m_keptAliveLoads.add(WTFMove(loader));
210 }
211
212 void NetworkSession::removeKeptAliveLoad(NetworkResourceLoader& loader)
213 {
214     ASSERT(m_sessionID == loader.sessionID());
215     ASSERT(m_keptAliveLoads.contains(loader));
216     m_keptAliveLoads.remove(loader);
217 }
218
219 std::unique_ptr<WebSocketTask> NetworkSession::createWebSocketTask(NetworkSocketChannel&, const WebCore::ResourceRequest&, const String& protocol)
220 {
221     return nullptr;
222 }
223
224 } // namespace WebKit