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 "ResourceCachesToClear.h"
33#include "WebCookieManager.h"
34#include <WebCore/CertificateInfo.h>
35#include <WebCore/NetworkStorageSession.h>
36#include <WebCore/NotImplemented.h>
37#include <WebCore/ResourceHandle.h>
38#include <WebCore/SoupNetworkSession.h>
39#include <libsoup/soup.h>
40#include <wtf/FileSystem.h>
41#include <wtf/RAMSize.h>
42#include <wtf/glib/GRefPtr.h>
43#include <wtf/glib/GUniquePtr.h>
44#include <wtf/text/CString.h>
45#include <wtf/text/StringBuilder.h>
46
47namespace WebKit {
48using namespace WebCore;
49
50static CString buildAcceptLanguages(const Vector<String>& languages)
51{
52 size_t languagesCount = languages.size();
53
54 // Ignore "C" locale.
55 size_t cLocalePosition = languages.find("c");
56 if (cLocalePosition != notFound)
57 languagesCount--;
58
59 // Fallback to "en" if the list is empty.
60 if (!languagesCount)
61 return "en";
62
63 // Calculate deltas for the quality values.
64 int delta;
65 if (languagesCount < 10)
66 delta = 10;
67 else if (languagesCount < 20)
68 delta = 5;
69 else
70 delta = 1;
71
72 // Set quality values for each language.
73 StringBuilder builder;
74 for (size_t i = 0; i < languages.size(); ++i) {
75 if (i == cLocalePosition)
76 continue;
77
78 if (i)
79 builder.appendLiteral(",");
80
81 builder.append(languages[i]);
82
83 int quality = 100 - i * delta;
84 if (quality > 0 && quality < 100) {
85 builder.appendLiteral(";q=");
86 char buffer[8];
87 g_ascii_formatd(buffer, 8, "%.2f", quality / 100.0);
88 builder.append(buffer);
89 }
90 }
91
92 return builder.toString().utf8();
93}
94
95void NetworkProcess::userPreferredLanguagesChanged(const Vector<String>& languages)
96{
97 auto acceptLanguages = buildAcceptLanguages(languages);
98 SoupNetworkSession::setInitialAcceptLanguages(acceptLanguages);
99 forEachNetworkStorageSession([&acceptLanguages](const auto& session) {
100 session.soupNetworkSession().setAcceptLanguages(acceptLanguages);
101 });
102}
103
104void NetworkProcess::platformInitializeNetworkProcess(const NetworkProcessCreationParameters& parameters)
105{
106 if (parameters.proxySettings.mode != SoupNetworkProxySettings::Mode::Default)
107 setNetworkProxySettings(parameters.proxySettings);
108
109 ASSERT(!parameters.diskCacheDirectory.isEmpty());
110 m_diskCacheDirectory = parameters.diskCacheDirectory;
111
112 SoupNetworkSession::clearOldSoupCache(FileSystem::directoryName(m_diskCacheDirectory));
113
114 OptionSet<NetworkCache::Cache::Option> cacheOptions { NetworkCache::Cache::Option::RegisterNotify };
115#if ENABLE(NETWORK_CACHE_SPECULATIVE_REVALIDATION)
116 if (parameters.shouldEnableNetworkCacheSpeculativeRevalidation)
117 cacheOptions.add(NetworkCache::Cache::Option::SpeculativeRevalidation);
118#endif
119
120 m_cache = NetworkCache::Cache::open(*this, m_diskCacheDirectory, cacheOptions);
121
122 supplement<WebCookieManager>()->setHTTPCookieAcceptPolicy(parameters.cookieAcceptPolicy, OptionalCallbackID());
123
124 if (!parameters.languages.isEmpty())
125 userPreferredLanguagesChanged(parameters.languages);
126
127 setIgnoreTLSErrors(parameters.ignoreTLSErrors);
128}
129
130std::unique_ptr<WebCore::NetworkStorageSession> NetworkProcess::platformCreateDefaultStorageSession() const
131{
132 return std::make_unique<WebCore::NetworkStorageSession>(PAL::SessionID::defaultSessionID(), std::make_unique<SoupNetworkSession>(PAL::SessionID::defaultSessionID()));
133}
134
135void NetworkProcess::setIgnoreTLSErrors(bool ignoreTLSErrors)
136{
137 SoupNetworkSession::setShouldIgnoreTLSErrors(ignoreTLSErrors);
138}
139
140void NetworkProcess::allowSpecificHTTPSCertificateForHost(const CertificateInfo& certificateInfo, const String& host)
141{
142 SoupNetworkSession::allowSpecificHTTPSCertificateForHost(certificateInfo, host);
143}
144
145void NetworkProcess::clearCacheForAllOrigins(uint32_t cachesToClear)
146{
147 if (cachesToClear == InMemoryResourceCachesOnly)
148 return;
149
150 clearDiskCache(-WallTime::infinity(), [] { });
151}
152
153void NetworkProcess::clearDiskCache(WallTime modifiedSince, CompletionHandler<void()>&& completionHandler)
154{
155 if (!m_cache) {
156 completionHandler();
157 return;
158 }
159 m_cache->clear(modifiedSince, WTFMove(completionHandler));
160}
161
162void NetworkProcess::platformTerminate()
163{
164 notImplemented();
165}
166
167void NetworkProcess::setNetworkProxySettings(const SoupNetworkProxySettings& settings)
168{
169 SoupNetworkSession::setProxySettings(settings);
170 forEachNetworkStorageSession([](const auto& session) {
171 session.soupNetworkSession().setupProxy();
172 });
173}
174
175void NetworkProcess::platformPrepareToSuspend(CompletionHandler<void()>&& completionHandler)
176{
177 notImplemented();
178 completionHandler();
179}
180
181void NetworkProcess::platformProcessDidResume()
182{
183 notImplemented();
184}
185
186void NetworkProcess::platformProcessDidTransitionToForeground()
187{
188 notImplemented();
189}
190
191void NetworkProcess::platformProcessDidTransitionToBackground()
192{
193 notImplemented();
194}
195
196} // namespace WebKit
197