1/*
2 * Copyright (C) 2012-2018 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#pragma once
27
28#include "CredentialStorage.h"
29#include "PageIdentifier.h"
30#include "RegistrableDomain.h"
31#include <pal/SessionID.h>
32#include <wtf/Function.h>
33#include <wtf/HashMap.h>
34#include <wtf/HashSet.h>
35#include <wtf/WallTime.h>
36#include <wtf/text/WTFString.h>
37
38#if PLATFORM(COCOA) || USE(CFURLCONNECTION)
39#include <pal/spi/cf/CFNetworkSPI.h>
40#include <wtf/RetainPtr.h>
41#endif
42
43#if USE(SOUP)
44#include <wtf/Function.h>
45#include <wtf/glib/GRefPtr.h>
46typedef struct _SoupCookieJar SoupCookieJar;
47#endif
48
49#if USE(CURL)
50#include "CookieJarCurl.h"
51#include "CookieJarDB.h"
52#include <wtf/UniqueRef.h>
53#endif
54
55#ifdef __OBJC__
56#include <objc/objc.h>
57#endif
58
59#if PLATFORM(COCOA)
60#include "CookieStorageObserver.h"
61#endif
62
63namespace WebCore {
64
65class CurlProxySettings;
66class NetworkingContext;
67class ResourceRequest;
68class SoupNetworkSession;
69
70struct Cookie;
71struct CookieRequestHeaderFieldProxy;
72struct SameSiteInfo;
73
74enum class IncludeSecureCookies : bool;
75enum class IncludeHttpOnlyCookies : bool;
76
77class NetworkStorageSession {
78 WTF_MAKE_NONCOPYABLE(NetworkStorageSession); WTF_MAKE_FAST_ALLOCATED;
79public:
80 WEBCORE_EXPORT static void permitProcessToUseCookieAPI(bool);
81 WEBCORE_EXPORT static bool processMayUseCookieAPI();
82
83 PAL::SessionID sessionID() const { return m_sessionID; }
84 CredentialStorage& credentialStorage() { return m_credentialStorage; }
85
86#ifdef __OBJC__
87 WEBCORE_EXPORT NSHTTPCookieStorage *nsCookieStorage() const;
88#endif
89
90#if PLATFORM(COCOA) || USE(CFURLCONNECTION)
91 WEBCORE_EXPORT static RetainPtr<CFURLStorageSessionRef> createCFStorageSessionForIdentifier(CFStringRef identifier);
92 WEBCORE_EXPORT NetworkStorageSession(PAL::SessionID, RetainPtr<CFURLStorageSessionRef>&&, RetainPtr<CFHTTPCookieStorageRef>&&);
93 WEBCORE_EXPORT explicit NetworkStorageSession(PAL::SessionID);
94
95 // May be null, in which case a Foundation default should be used.
96 CFURLStorageSessionRef platformSession() { return m_platformSession.get(); }
97 WEBCORE_EXPORT RetainPtr<CFHTTPCookieStorageRef> cookieStorage() const;
98 WEBCORE_EXPORT static void setStorageAccessAPIEnabled(bool);
99#elif USE(SOUP)
100 WEBCORE_EXPORT NetworkStorageSession(PAL::SessionID, std::unique_ptr<SoupNetworkSession>&&);
101 ~NetworkStorageSession();
102
103 SoupNetworkSession& soupNetworkSession() const;
104 void clearSoupNetworkSession();
105 SoupCookieJar* cookieStorage() const;
106 void setCookieStorage(SoupCookieJar*);
107 void setCookieObserverHandler(Function<void ()>&&);
108 void getCredentialFromPersistentStorage(const ProtectionSpace&, GCancellable*, Function<void (Credential&&)>&& completionHandler);
109 void saveCredentialToPersistentStorage(const ProtectionSpace&, const Credential&);
110#elif USE(CURL)
111 WEBCORE_EXPORT NetworkStorageSession(PAL::SessionID);
112 ~NetworkStorageSession();
113
114 const CookieJarCurl& cookieStorage() const { return m_cookieStorage; };
115 CookieJarDB& cookieDatabase() const;
116 WEBCORE_EXPORT void setCookieDatabase(UniqueRef<CookieJarDB>&&);
117
118 WEBCORE_EXPORT void setProxySettings(CurlProxySettings&&);
119#else
120 WEBCORE_EXPORT NetworkStorageSession(PAL::SessionID, NetworkingContext*);
121 ~NetworkStorageSession();
122
123 NetworkingContext* context() const;
124#endif
125
126 WEBCORE_EXPORT bool cookiesEnabled() const;
127 WEBCORE_EXPORT void setCookie(const Cookie&);
128 WEBCORE_EXPORT void setCookies(const Vector<Cookie>&, const URL&, const URL& mainDocumentURL);
129 WEBCORE_EXPORT void setCookiesFromDOM(const URL& firstParty, const SameSiteInfo&, const URL&, Optional<uint64_t> frameID, Optional<PageIdentifier>, const String&) const;
130 WEBCORE_EXPORT void deleteCookie(const Cookie&);
131 WEBCORE_EXPORT void deleteCookie(const URL&, const String&) const;
132 WEBCORE_EXPORT void deleteAllCookies();
133 WEBCORE_EXPORT void deleteAllCookiesModifiedSince(WallTime);
134 WEBCORE_EXPORT void deleteCookiesForHostnames(const Vector<String>& cookieHostNames);
135 WEBCORE_EXPORT void deleteCookiesForHostnames(const Vector<String>& cookieHostNames, IncludeHttpOnlyCookies);
136 WEBCORE_EXPORT Vector<Cookie> getAllCookies();
137 WEBCORE_EXPORT Vector<Cookie> getCookies(const URL&);
138 WEBCORE_EXPORT bool getRawCookies(const URL& firstParty, const SameSiteInfo&, const URL&, Optional<uint64_t> frameID, Optional<PageIdentifier>, Vector<Cookie>&) const;
139 WEBCORE_EXPORT void flushCookieStore();
140 WEBCORE_EXPORT void getHostnamesWithCookies(HashSet<String>& hostnames);
141 WEBCORE_EXPORT std::pair<String, bool> cookiesForDOM(const URL& firstParty, const SameSiteInfo&, const URL&, Optional<uint64_t> frameID, Optional<PageIdentifier>, IncludeSecureCookies) const;
142 WEBCORE_EXPORT std::pair<String, bool> cookieRequestHeaderFieldValue(const URL& firstParty, const SameSiteInfo&, const URL&, Optional<uint64_t> frameID, Optional<PageIdentifier>, IncludeSecureCookies) const;
143 WEBCORE_EXPORT std::pair<String, bool> cookieRequestHeaderFieldValue(const CookieRequestHeaderFieldProxy&) const;
144
145#if ENABLE(RESOURCE_LOAD_STATISTICS)
146 WEBCORE_EXPORT bool shouldBlockCookies(const ResourceRequest&, Optional<uint64_t> frameID, Optional<PageIdentifier>) const;
147 WEBCORE_EXPORT bool shouldBlockCookies(const URL& firstPartyForCookies, const URL& resource, Optional<uint64_t> frameID, Optional<PageIdentifier>) const;
148 WEBCORE_EXPORT bool shouldBlockThirdPartyCookies(const RegistrableDomain&) const;
149 WEBCORE_EXPORT void setPrevalentDomainsToBlockCookiesFor(const Vector<RegistrableDomain>&);
150 WEBCORE_EXPORT void setAgeCapForClientSideCookies(Optional<Seconds>);
151 WEBCORE_EXPORT void removePrevalentDomains(const Vector<RegistrableDomain>& domains);
152 WEBCORE_EXPORT bool hasStorageAccess(const RegistrableDomain& resourceDomain, const RegistrableDomain& firstPartyDomain, Optional<uint64_t> frameID, PageIdentifier) const;
153 WEBCORE_EXPORT Vector<String> getAllStorageAccessEntries() const;
154 WEBCORE_EXPORT void grantStorageAccess(const RegistrableDomain& resourceDomain, const RegistrableDomain& firstPartyDomain, Optional<uint64_t> frameID, PageIdentifier);
155 WEBCORE_EXPORT void removeStorageAccessForFrame(uint64_t frameID, PageIdentifier);
156 WEBCORE_EXPORT void clearPageSpecificDataForResourceLoadStatistics(PageIdentifier);
157 WEBCORE_EXPORT void removeAllStorageAccess();
158 WEBCORE_EXPORT void setCacheMaxAgeCapForPrevalentResources(Seconds);
159 WEBCORE_EXPORT void resetCacheMaxAgeCapForPrevalentResources();
160 WEBCORE_EXPORT Optional<Seconds> maxAgeCacheCap(const ResourceRequest&);
161 WEBCORE_EXPORT void didCommitCrossSiteLoadWithDataTransferFromPrevalentResource(const RegistrableDomain& toDomain, PageIdentifier);
162 WEBCORE_EXPORT void resetCrossSiteLoadsWithLinkDecorationForTesting();
163#endif
164
165private:
166 PAL::SessionID m_sessionID;
167
168#if PLATFORM(COCOA) || USE(CFURLCONNECTION)
169 RetainPtr<CFURLStorageSessionRef> m_platformSession;
170 RetainPtr<CFHTTPCookieStorageRef> m_platformCookieStorage;
171#elif USE(SOUP)
172 static void cookiesDidChange(NetworkStorageSession*);
173
174 mutable std::unique_ptr<SoupNetworkSession> m_session;
175 Function<void ()> m_cookieObserverHandler;
176#elif USE(CURL)
177 UniqueRef<CookieJarCurl> m_cookieStorage;
178 mutable UniqueRef<CookieJarDB> m_cookieDatabase;
179#else
180 RefPtr<NetworkingContext> m_context;
181#endif
182
183 CredentialStorage m_credentialStorage;
184
185#if ENABLE(RESOURCE_LOAD_STATISTICS)
186 Optional<Seconds> clientSideCookieCap(const RegistrableDomain& firstParty, Optional<PageIdentifier>) const;
187 HashSet<RegistrableDomain> m_registrableDomainsToBlockCookieFor;
188 HashMap<PageIdentifier, HashMap<uint64_t, RegistrableDomain, DefaultHash<uint64_t>::Hash, WTF::UnsignedWithZeroKeyHashTraits<uint64_t>>> m_framesGrantedStorageAccess;
189 HashMap<PageIdentifier, HashMap<RegistrableDomain, RegistrableDomain>> m_pagesGrantedStorageAccess;
190 Optional<Seconds> m_cacheMaxAgeCapForPrevalentResources { };
191 Optional<Seconds> m_ageCapForClientSideCookies { };
192 Optional<Seconds> m_ageCapForClientSideCookiesShort { };
193 HashMap<WebCore::PageIdentifier, RegistrableDomain> m_navigatedToWithLinkDecorationByPrevalentResource;
194 bool m_navigationWithLinkDecorationTestMode = false;
195#endif
196
197#if PLATFORM(COCOA)
198public:
199 CookieStorageObserver& cookieStorageObserver() const;
200
201private:
202 mutable RefPtr<CookieStorageObserver> m_cookieStorageObserver;
203#endif
204 static bool m_processMayUseCookieAPI;
205};
206
207#if PLATFORM(COCOA) || USE(CFURLCONNECTION)
208WEBCORE_EXPORT CFURLStorageSessionRef createPrivateStorageSession(CFStringRef identifier);
209#endif
210
211}
212