Move NetworkCache ownership from NetworkProcess to NetworkSession
[WebKit-https.git] / Source / WebKit / NetworkProcess / soup / NetworkProcessSoup.cpp
1 /*
2  * Copyright (C) 2013 Apple Inc. All rights reserved.
3  * Copyright (C) 2013 Comapny 100 Inc.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  * 1. Redistributions of source code must retain the above copyright
9  *    notice, this list of conditions and the following disclaimer.
10  * 2. Redistributions in binary form must reproduce the above copyright
11  *    notice, this list of conditions and the following disclaimer in the
12  *    documentation and/or other materials provided with the distribution.
13  *
14  * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
15  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
16  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
17  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
18  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
19  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
20  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
21  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
22  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
23  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
24  * THE POSSIBILITY OF SUCH DAMAGE.
25  */
26
27 #include "config.h"
28 #include "NetworkProcess.h"
29
30 #include "NetworkCache.h"
31 #include "NetworkProcessCreationParameters.h"
32 #include "NetworkSession.h"
33 #include "ResourceCachesToClear.h"
34 #include "WebCookieManager.h"
35 #include "WebKitCachedResolver.h"
36 #include <WebCore/CertificateInfo.h>
37 #include <WebCore/NetworkStorageSession.h>
38 #include <WebCore/NotImplemented.h>
39 #include <WebCore/ResourceHandle.h>
40 #include <WebCore/SoupNetworkSession.h>
41 #include <libsoup/soup.h>
42 #include <wtf/CallbackAggregator.h>
43 #include <wtf/FileSystem.h>
44 #include <wtf/RAMSize.h>
45 #include <wtf/glib/GRefPtr.h>
46 #include <wtf/glib/GUniquePtr.h>
47 #include <wtf/text/CString.h>
48 #include <wtf/text/StringBuilder.h>
49
50 namespace WebKit {
51 using namespace WebCore;
52
53 static CString buildAcceptLanguages(const Vector<String>& languages)
54 {
55     size_t languagesCount = languages.size();
56
57     // Ignore "C" locale.
58     size_t cLocalePosition = languages.find("c");
59     if (cLocalePosition != notFound)
60         languagesCount--;
61
62     // Fallback to "en" if the list is empty.
63     if (!languagesCount)
64         return "en";
65
66     // Calculate deltas for the quality values.
67     int delta;
68     if (languagesCount < 10)
69         delta = 10;
70     else if (languagesCount < 20)
71         delta = 5;
72     else
73         delta = 1;
74
75     // Set quality values for each language.
76     StringBuilder builder;
77     for (size_t i = 0; i < languages.size(); ++i) {
78         if (i == cLocalePosition)
79             continue;
80
81         if (i)
82             builder.appendLiteral(",");
83
84         builder.append(languages[i]);
85
86         int quality = 100 - i * delta;
87         if (quality > 0 && quality < 100) {
88             builder.appendLiteral(";q=");
89             char buffer[8];
90             g_ascii_formatd(buffer, 8, "%.2f", quality / 100.0);
91             builder.append(buffer);
92         }
93     }
94
95     return builder.toString().utf8();
96 }
97
98 void NetworkProcess::userPreferredLanguagesChanged(const Vector<String>& languages)
99 {
100     auto acceptLanguages = buildAcceptLanguages(languages);
101     SoupNetworkSession::setInitialAcceptLanguages(acceptLanguages);
102     forEachNetworkStorageSession([&acceptLanguages](const auto& session) {
103         session.soupNetworkSession().setAcceptLanguages(acceptLanguages);
104     });
105 }
106
107 void NetworkProcess::platformInitializeNetworkProcess(const NetworkProcessCreationParameters& parameters)
108 {
109     if (parameters.proxySettings.mode != SoupNetworkProxySettings::Mode::Default)
110         setNetworkProxySettings(parameters.proxySettings);
111
112     ASSERT(!parameters.diskCacheDirectory.isEmpty());
113     m_diskCacheDirectory = parameters.diskCacheDirectory;
114
115     GRefPtr<GResolver> cachedResolver = adoptGRef(webkitCachedResolverNew(adoptGRef(g_resolver_get_default())));
116     g_resolver_set_default(cachedResolver.get());
117
118     SoupNetworkSession::clearOldSoupCache(FileSystem::directoryName(m_diskCacheDirectory));
119
120     OptionSet<NetworkCache::CacheOption> cacheOptions { NetworkCache::CacheOption::RegisterNotify };
121 #if ENABLE(NETWORK_CACHE_SPECULATIVE_REVALIDATION)
122     if (parameters.shouldEnableNetworkCacheSpeculativeRevalidation)
123         cacheOptions.add(NetworkCache::CacheOption::SpeculativeRevalidation);
124 #endif
125
126     supplement<WebCookieManager>()->setHTTPCookieAcceptPolicy(parameters.cookieAcceptPolicy, OptionalCallbackID());
127
128     if (!parameters.languages.isEmpty())
129         userPreferredLanguagesChanged(parameters.languages);
130
131     setIgnoreTLSErrors(parameters.ignoreTLSErrors);
132 }
133
134 std::unique_ptr<WebCore::NetworkStorageSession> NetworkProcess::platformCreateDefaultStorageSession() const
135 {
136     return std::make_unique<WebCore::NetworkStorageSession>(PAL::SessionID::defaultSessionID(), std::make_unique<SoupNetworkSession>(PAL::SessionID::defaultSessionID()));
137 }
138
139 void NetworkProcess::setIgnoreTLSErrors(bool ignoreTLSErrors)
140 {
141     SoupNetworkSession::setShouldIgnoreTLSErrors(ignoreTLSErrors);
142 }
143
144 void NetworkProcess::allowSpecificHTTPSCertificateForHost(const CertificateInfo& certificateInfo, const String& host)
145 {
146     SoupNetworkSession::allowSpecificHTTPSCertificateForHost(certificateInfo, host);
147 }
148
149 void NetworkProcess::clearCacheForAllOrigins(uint32_t cachesToClear)
150 {
151     if (cachesToClear == InMemoryResourceCachesOnly)
152         return;
153
154     clearDiskCache(-WallTime::infinity(), [] { });
155 }
156
157 void NetworkProcess::clearDiskCache(WallTime modifiedSince, CompletionHandler<void()>&& completionHandler)
158 {
159     auto aggregator = CallbackAggregator::create(WTFMove(completionHandler));
160     for (auto& session : networkSessions().values()) {
161         if (auto* cache = session->cache())
162             cache->clear(modifiedSince, [aggregator = aggregator.copyRef()] () { });
163     }
164 }
165
166 void NetworkProcess::platformTerminate()
167 {
168     notImplemented();
169 }
170
171 void NetworkProcess::setNetworkProxySettings(const SoupNetworkProxySettings& settings)
172 {
173     SoupNetworkSession::setProxySettings(settings);
174     forEachNetworkStorageSession([](const auto& session) {
175         session.soupNetworkSession().setupProxy();
176     });
177 }
178
179 void NetworkProcess::platformPrepareToSuspend(CompletionHandler<void()>&& completionHandler)
180 {
181     notImplemented();
182     completionHandler();
183 }
184
185 void NetworkProcess::platformProcessDidResume()
186 {
187     notImplemented();
188 }
189
190 void NetworkProcess::platformProcessDidTransitionToForeground()
191 {
192     notImplemented();
193 }
194
195 void NetworkProcess::platformProcessDidTransitionToBackground()
196 {
197     notImplemented();
198 }
199
200 } // namespace WebKit