/* * Copyright (C) 2009 Joseph Pecoraro. All rights reserved. * Copyright (C) 2017-2018 Apple Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #pragma once #include #include #include #ifdef __OBJC__ #include #endif #if USE(SOUP) typedef struct _SoupCookie SoupCookie; #endif namespace WebCore { struct Cookie { Cookie() = default; template void encode(Encoder&) const; template static std::optional decode(Decoder&); WEBCORE_EXPORT bool operator==(const Cookie&) const; WEBCORE_EXPORT unsigned hash() const; #ifdef __OBJC__ WEBCORE_EXPORT Cookie(NSHTTPCookie *); WEBCORE_EXPORT operator NSHTTPCookie *() const; #elif USE(SOUP) explicit Cookie(SoupCookie*); SoupCookie* toSoupCookie() const; #endif bool isNull() const { return name.isNull() && value.isNull() && domain.isNull() && path.isNull() && !created && !expires && !httpOnly && !secure && !session && comment.isNull() && commentURL.isNull(); } bool isKeyEqual(const Cookie& otherCookie) const { return name == otherCookie.name && domain == otherCookie.domain && path == otherCookie.path; } String name; String value; String domain; String path; // Creation and expiration dates are expressed as milliseconds since the UNIX epoch. double created { 0 }; std::optional expires; bool httpOnly { false }; bool secure { false }; bool session { false }; String comment; URL commentURL; Vector ports; enum class SameSitePolicy { None, Lax, Strict }; SameSitePolicy sameSite { SameSitePolicy::None }; }; struct CookieHash { static unsigned hash(const Cookie& key) { return key.hash(); } static bool equal(const Cookie& a, const Cookie& b) { return a == b; } static const bool safeToCompareToEmptyOrDeleted = false; }; template void Cookie::encode(Encoder& encoder) const { encoder << name; encoder << value; encoder << domain; encoder << path; encoder << created; encoder << expires; encoder << httpOnly; encoder << secure; encoder << session; encoder << comment; encoder << commentURL; encoder << ports; encoder << sameSite; } template std::optional Cookie::decode(Decoder& decoder) { Cookie cookie; if (!decoder.decode(cookie.name)) return std::nullopt; if (!decoder.decode(cookie.value)) return std::nullopt; if (!decoder.decode(cookie.domain)) return std::nullopt; if (!decoder.decode(cookie.path)) return std::nullopt; if (!decoder.decode(cookie.created)) return std::nullopt; if (!decoder.decode(cookie.expires)) return std::nullopt; if (!decoder.decode(cookie.httpOnly)) return std::nullopt; if (!decoder.decode(cookie.secure)) return std::nullopt; if (!decoder.decode(cookie.session)) return std::nullopt; if (!decoder.decode(cookie.comment)) return std::nullopt; if (!decoder.decode(cookie.commentURL)) return std::nullopt; if (!decoder.decode(cookie.ports)) return std::nullopt; if (!decoder.decode(cookie.sameSite)) return std::nullopt; return cookie; } } namespace WTF { template struct DefaultHash; template<> struct DefaultHash : WebCore::CookieHash { }; template<> struct HashTraits : GenericHashTraits { static WebCore::Cookie emptyValue() { return { }; } static void constructDeletedValue(WebCore::Cookie& slot) { new (NotNull, &slot.name) String(WTF::HashTableDeletedValue); } static bool isDeletedValue(const WebCore::Cookie& slot) { return slot.name.isHashTableDeletedValue(); } static const bool hasIsEmptyValueFunction = true; static bool isEmptyValue(const WebCore::Cookie& slot) { return slot.isNull(); } }; template<> struct EnumTraits { using values = EnumValues< WebCore::Cookie::SameSitePolicy, WebCore::Cookie::SameSitePolicy::None, WebCore::Cookie::SameSitePolicy::Lax, WebCore::Cookie::SameSitePolicy::Strict >; }; }