a36390467d210929882fcf60e150031c1f909acb
[WebKit-https.git] / Source / WebCore / platform / Cookie.h
1 /*
2  * Copyright (C) 2009 Joseph Pecoraro. All rights reserved.
3  * Copyright (C) 2017 Apple Inc. All rights reserved.
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. ``AS IS'' AND ANY
15  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
17  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
18  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
19  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
20  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
21  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
22  * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
24  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
25  */
26
27 #pragma once
28
29 #include "URL.h"
30 #include <wtf/text/StringHash.h>
31 #include <wtf/text/WTFString.h>
32
33 #ifdef __OBJC__
34 #include <objc/objc.h>
35 #endif
36
37 namespace WebCore {
38
39 struct Cookie {
40     Cookie() { }
41     
42     Cookie(WTF::HashTableDeletedValueType)
43         : name(WTF::HashTableDeletedValue)
44     { }
45
46     Cookie(const String& name, const String& value, const String& domain, const String& path, double expires, bool httpOnly, bool secure, bool session, const String& comment, const URL& commentURL, const Vector<uint16_t> ports)
47         : name(name)
48         , value(value)
49         , domain(domain)
50         , path(path)
51         , expires(expires)
52         , httpOnly(httpOnly)
53         , secure(secure)
54         , session(session)
55         , comment(comment)
56         , commentURL(commentURL)
57         , ports(ports)
58     {
59     }
60
61     template<class Encoder> void encode(Encoder&) const;
62     template<class Decoder> static std::optional<Cookie> decode(Decoder&);
63
64     WEBCORE_EXPORT bool operator==(const Cookie&) const;
65     WEBCORE_EXPORT unsigned hash() const;
66
67 #ifdef __OBJC__
68     WEBCORE_EXPORT Cookie(NSHTTPCookie *);
69     WEBCORE_EXPORT operator NSHTTPCookie *() const;
70 #elif USE(SOUP)
71     explicit Cookie(SoupCookie*);
72     SoupCookie* toSoupCookie() const;
73 #endif
74
75     bool isNull() const
76     {
77         return name.isNull()
78         && value.isNull()
79         && domain.isNull()
80         && path.isNull()
81         && expires == 0
82         && !httpOnly
83         && !secure
84         && !session
85         && comment.isNull()
86         && commentURL.isNull();
87     }
88     
89     String name;
90     String value;
91     String domain;
92     String path;
93     // Expiration date, expressed as milliseconds since the UNIX epoch.
94     double expires { 0 };
95     bool httpOnly { false };
96     bool secure { false };
97     bool session { false };
98     String comment;
99     URL commentURL;
100     Vector<uint16_t> ports;
101 };
102
103 struct CookieHash {
104     static unsigned hash(const Cookie& key)
105     {
106         return key.hash();
107     }
108
109     static bool equal(const Cookie& a, const Cookie& b)
110     {
111         return a == b;
112     }
113     static const bool safeToCompareToEmptyOrDeleted = false;
114 };
115
116 template<class Encoder>
117 void Cookie::encode(Encoder& encoder) const
118 {
119     encoder << name << value << domain << path << expires << httpOnly << secure << session << comment << commentURL << ports;
120 }
121
122 template<class Decoder>
123 std::optional<Cookie> Cookie::decode(Decoder& decoder)
124 {
125     std::optional<String> name;
126     decoder >> name;
127     if (!name)
128         return std::nullopt;
129     
130     std::optional<String> value;
131     decoder >> value;
132     if (!value)
133         return std::nullopt;
134
135     std::optional<String> domain;
136     decoder >> domain;
137     if (!domain)
138         return std::nullopt;
139
140     std::optional<String> path;
141     decoder >> path;
142     if (!path)
143         return std::nullopt;
144
145     std::optional<double> expires;
146     decoder >> expires;
147     if (!expires)
148         return std::nullopt;
149
150     std::optional<bool> httpOnly;
151     decoder >> httpOnly;
152     if (!httpOnly)
153         return std::nullopt;
154
155     std::optional<bool> secure;
156     decoder >> secure;
157     if (!secure)
158         return std::nullopt;
159
160     std::optional<bool> session;
161     decoder >> session;
162     if (!session)
163         return std::nullopt;
164
165     std::optional<String> comment;
166     decoder >> comment;
167     if (!comment)
168         return std::nullopt;
169
170     URL commentURL;
171     if (!decoder.decode(commentURL))
172         return std::nullopt;
173
174     std::optional<Vector<uint16_t>> ports;
175     decoder >> ports;
176     if (!ports)
177         return std::nullopt;
178
179     return {{ WTFMove(*name), WTFMove(*value), WTFMove(*domain), WTFMove(*path), WTFMove(*expires), WTFMove(*httpOnly), WTFMove(*secure), WTFMove(*session), WTFMove(*comment), WTFMove(commentURL), WTFMove(*ports) }};
180 }
181
182 }
183
184 namespace WTF {
185     template<typename T> struct DefaultHash;
186     template<> struct DefaultHash<WebCore::Cookie> {
187         typedef WebCore::CookieHash Hash;
188     };
189     template<> struct HashTraits<WebCore::Cookie> : GenericHashTraits<WebCore::Cookie> {
190         static WebCore::Cookie emptyValue() { return { }; }
191         static void constructDeletedValue(WebCore::Cookie& slot) { slot = WebCore::Cookie(WTF::HashTableDeletedValue); }
192         static bool isDeletedValue(const WebCore::Cookie& slot) { return slot.name.isHashTableDeletedValue(); }
193     };
194 }