Implement Same-Site cookies
[WebKit-https.git] / Source / WebCore / platform / network / cf / CookieJarCFNet.cpp
index 469fe6f..b6bd805 100644 (file)
@@ -29,6 +29,7 @@
 #if USE(CFURLCONNECTION)
 
 #include "Cookie.h"
+#include "CookieRequestHeaderFieldProxy.h"
 #include "CookiesStrategy.h"
 #include "NetworkStorageSession.h"
 #include "NotImplemented.h"
@@ -70,15 +71,44 @@ namespace WebCore {
 
 static const CFStringRef s_setCookieKeyCF = CFSTR("Set-Cookie");
 static const CFStringRef s_cookieCF = CFSTR("Cookie");
+static const CFStringRef s_createdCF = CFSTR("Created");
 
 static inline RetainPtr<CFStringRef> cookieDomain(CFHTTPCookieRef cookie)
 {
     return adoptCF(CFHTTPCookieCopyDomain(cookie));
 }
 
+static double canonicalCookieTime(double time)
+{
+    if (!time)
+        return time;
+
+    return (time + kCFAbsoluteTimeIntervalSince1970) * 1000;
+}
+
+static double cookieCreatedTime(CFHTTPCookieRef cookie)
+{
+    RetainPtr<CFDictionaryRef> props = adoptCF(CFHTTPCookieCopyProperties(cookie));
+    auto value = CFDictionaryGetValue(props.get(), s_createdCF);
+
+    auto asNumber = dynamic_cf_cast<CFNumberRef>(value);
+    if (asNumber) {
+        double asDouble;
+        if (CFNumberGetValue(asNumber, kCFNumberFloat64Type, &asDouble))
+            return canonicalCookieTime(asDouble);
+        return 0.0;
+    }
+
+    auto asString = dynamic_cf_cast<CFStringRef>(value);
+    if (asString)
+        return canonicalCookieTime(CFStringGetDoubleValue(asString));
+
+    return 0.0;
+}
+
 static inline CFAbsoluteTime cookieExpirationTime(CFHTTPCookieRef cookie)
 {
-    return CFHTTPCookieGetExpirationTime(cookie);
+    return canonicalCookieTime(CFHTTPCookieGetExpirationTime(cookie));
 }
 
 static inline RetainPtr<CFStringRef> cookieName(CFHTTPCookieRef cookie)
@@ -138,7 +168,7 @@ static CFArrayRef createCookies(CFDictionaryRef headerFields, CFURLRef url)
     return parsedCookies;
 }
 
-void setCookiesFromDOM(const NetworkStorageSession& session, const URL& firstParty, const URL& url, std::optional<uint64_t> frameID, std::optional<uint64_t> pageID, const String& value)
+void setCookiesFromDOM(const NetworkStorageSession& session, const URL& firstParty, const SameSiteInfo&, const URL& url, std::optional<uint64_t> frameID, std::optional<uint64_t> pageID, const String& value)
 {
     UNUSED_PARAM(frameID);
     UNUSED_PARAM(pageID);
@@ -174,7 +204,7 @@ static bool containsSecureCookies(CFArrayRef cookies)
     return false;
 }
 
-std::pair<String, bool> cookiesForDOM(const NetworkStorageSession& session, const URL& firstParty, const URL& url, std::optional<uint64_t> frameID, std::optional<uint64_t> pageID, IncludeSecureCookies includeSecureCookies)
+std::pair<String, bool> cookiesForDOM(const NetworkStorageSession& session, const URL& firstParty, const SameSiteInfo&, const URL& url, std::optional<uint64_t> frameID, std::optional<uint64_t> pageID, IncludeSecureCookies includeSecureCookies)
 {
     UNUSED_PARAM(frameID);
     UNUSED_PARAM(pageID);
@@ -189,7 +219,7 @@ std::pair<String, bool> cookiesForDOM(const NetworkStorageSession& session, cons
     return { cookieString, didAccessSecureCookies };
 }
 
-std::pair<String, bool> cookieRequestHeaderFieldValue(const NetworkStorageSession& session, const URL& firstParty, const URL& url, std::optional<uint64_t> frameID, std::optional<uint64_t> pageID, IncludeSecureCookies includeSecureCookies)
+std::pair<String, bool> cookieRequestHeaderFieldValue(const NetworkStorageSession& session, const URL& firstParty, const SameSiteInfo&, const URL& url, std::optional<uint64_t> frameID, std::optional<uint64_t> pageID, IncludeSecureCookies includeSecureCookies)
 {
     UNUSED_PARAM(frameID);
     UNUSED_PARAM(pageID);
@@ -202,13 +232,18 @@ std::pair<String, bool> cookieRequestHeaderFieldValue(const NetworkStorageSessio
     return { cookieString, didAccessSecureCookies };
 }
 
+std::pair<String, bool> cookieRequestHeaderFieldValue(const NetworkStorageSession& session, const CookieRequestHeaderFieldProxy& headerFieldProxy)
+{
+    return cookieRequestHeaderFieldValue(session, headerFieldProxy.firstParty, headerFieldProxy.url, headerFieldProxy.frameID, headerFieldProxy.pageID, headerFieldProxy.includeSecureCookies);
+}
+
 bool cookiesEnabled(const NetworkStorageSession& session)
 {
     CFHTTPCookieStorageAcceptPolicy policy = CFHTTPCookieStorageGetCookieAcceptPolicy(session.cookieStorage().get());
     return policy == CFHTTPCookieStorageAcceptPolicyOnlyFromMainDocumentDomain || policy == CFHTTPCookieStorageAcceptPolicyExclusivelyFromMainDocumentDomain || policy == CFHTTPCookieStorageAcceptPolicyAlways;
 }
 
-bool getRawCookies(const NetworkStorageSession& session, const URL& firstParty, const URL& url, std::optional<uint64_t> frameID, std::optional<uint64_t> pageID, Vector<Cookie>& rawCookies)
+bool getRawCookies(const NetworkStorageSession& session, const URL& firstParty, const SameSiteInfo&, const URL& url, std::optional<uint64_t> frameID, std::optional<uint64_t> pageID, Vector<Cookie>& rawCookies)
 {
     UNUSED_PARAM(frameID);
     UNUSED_PARAM(pageID);
@@ -228,7 +263,8 @@ bool getRawCookies(const NetworkStorageSession& session, const URL& firstParty,
         String domain = cookieDomain(cookie).get();
         String path = cookiePath(cookie).get();
 
-        double expires = (cookieExpirationTime(cookie) + kCFAbsoluteTimeIntervalSince1970) * 1000;
+        double created = cookieCreatedTime(cookie);
+        double expires = cookieExpirationTime(cookie);
 
         bool httpOnly = CFHTTPCookieIsHTTPOnly(cookie);
         bool secure = CFHTTPCookieIsSecure(cookie);
@@ -238,7 +274,7 @@ bool getRawCookies(const NetworkStorageSession& session, const URL& firstParty,
         URL commentURL;
         Vector<uint16_t> ports;
 
-        rawCookies.uncheckedAppend(Cookie(name, value, domain, path, expires, httpOnly, secure, session, comment, commentURL, ports));
+        rawCookies.uncheckedAppend(Cookie(name, value, domain, path, created, expires, httpOnly, secure, session, comment, commentURL, ports));
     }
 
     return true;
@@ -286,7 +322,7 @@ void deleteCookiesForHostnames(const NetworkStorageSession& session, const Vecto
 {
 }
 
-void deleteAllCookiesModifiedSince(const NetworkStorageSession&, std::chrono::system_clock::time_point)
+void deleteAllCookiesModifiedSince(const NetworkStorageSession&, WallTime)
 {
 }