Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
SeleniumHQ
GitHub Repository: SeleniumHQ/Selenium
Path: blob/trunk/java/src/org/openqa/selenium/Cookie.java
4010 views
1
// Licensed to the Software Freedom Conservancy (SFC) under one
2
// or more contributor license agreements. See the NOTICE file
3
// distributed with this work for additional information
4
// regarding copyright ownership. The SFC licenses this file
5
// to you under the Apache License, Version 2.0 (the
6
// "License"); you may not use this file except in compliance
7
// with the License. You may obtain a copy of the License at
8
//
9
// http://www.apache.org/licenses/LICENSE-2.0
10
//
11
// Unless required by applicable law or agreed to in writing,
12
// software distributed under the License is distributed on an
13
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14
// KIND, either express or implied. See the License for the
15
// specific language governing permissions and limitations
16
// under the License.
17
18
package org.openqa.selenium;
19
20
import java.io.Serializable;
21
import java.text.SimpleDateFormat;
22
import java.util.Date;
23
import java.util.Map;
24
import java.util.Objects;
25
import java.util.TimeZone;
26
import java.util.TreeMap;
27
import org.jspecify.annotations.Nullable;
28
29
public class Cookie implements Serializable {
30
private static final long serialVersionUID = 4115876353625612383L;
31
32
private final String name;
33
private final String value;
34
private final String path;
35
private final @Nullable String domain;
36
private final @Nullable Date expiry;
37
private final boolean isSecure;
38
private final boolean isHttpOnly;
39
private final @Nullable String sameSite;
40
41
/**
42
* Creates an insecure non-httpOnly cookie with no domain specified.
43
*
44
* @param name The name of the cookie; may not be null or an empty string.
45
* @param value The cookie value; may not be null.
46
* @param path The path the cookie is visible to. If left blank or set to null, will be set to
47
* "/".
48
* @param expiry The cookie's expiration date; may be null.
49
* @see #Cookie(String, String, String, String, Date)
50
*/
51
public Cookie(String name, String value, @Nullable String path, @Nullable Date expiry) {
52
this(name, value, null, path, expiry);
53
}
54
55
/**
56
* Creates an insecure non-httpOnly cookie.
57
*
58
* @param name The name of the cookie; may not be null or an empty string.
59
* @param value The cookie value; may not be null.
60
* @param domain The domain the cookie is visible to.
61
* @param path The path the cookie is visible to. If left blank or set to null, will be set to
62
* "/".
63
* @param expiry The cookie's expiration date; may be null.
64
* @see #Cookie(String, String, String, String, Date, boolean)
65
*/
66
public Cookie(
67
String name,
68
String value,
69
@Nullable String domain,
70
@Nullable String path,
71
@Nullable Date expiry) {
72
this(name, value, domain, path, expiry, false);
73
}
74
75
/**
76
* Creates a non-httpOnly cookie.
77
*
78
* @param name The name of the cookie; may not be null or an empty string.
79
* @param value The cookie value; may not be null.
80
* @param domain The domain the cookie is visible to.
81
* @param path The path the cookie is visible to. If left blank or set to null, will be set to
82
* "/".
83
* @param expiry The cookie's expiration date; may be null.
84
* @param isSecure Whether this cookie requires a secure connection.
85
*/
86
public Cookie(
87
String name,
88
String value,
89
@Nullable String domain,
90
@Nullable String path,
91
@Nullable Date expiry,
92
boolean isSecure) {
93
this(name, value, domain, path, expiry, isSecure, false);
94
}
95
96
/**
97
* Creates a cookie.
98
*
99
* @param name The name of the cookie; may not be null or an empty string.
100
* @param value The cookie value; may not be null.
101
* @param domain The domain the cookie is visible to.
102
* @param path The path the cookie is visible to. If left blank or set to null, will be set to
103
* "/".
104
* @param expiry The cookie's expiration date; may be null.
105
* @param isSecure Whether this cookie requires a secure connection.
106
* @param isHttpOnly Whether this cookie is a httpOnly cooke.
107
*/
108
public Cookie(
109
String name,
110
String value,
111
@Nullable String domain,
112
@Nullable String path,
113
@Nullable Date expiry,
114
boolean isSecure,
115
boolean isHttpOnly) {
116
this(name, value, domain, path, expiry, isSecure, isHttpOnly, null);
117
}
118
119
/**
120
* Creates a cookie.
121
*
122
* @param name The name of the cookie; may not be null or an empty string.
123
* @param value The cookie value; may not be null.
124
* @param domain The domain the cookie is visible to.
125
* @param path The path the cookie is visible to. If left blank or set to null, will be set to
126
* "/".
127
* @param expiry The cookie's expiration date; may be null.
128
* @param isSecure Whether this cookie requires a secure connection.
129
* @param isHttpOnly Whether this cookie is a httpOnly cookie.
130
* @param sameSite The samesite attribute of this cookie; e.g. None, Lax, Strict.
131
*/
132
public Cookie(
133
String name,
134
String value,
135
@Nullable String domain,
136
@Nullable String path,
137
@Nullable Date expiry,
138
boolean isSecure,
139
boolean isHttpOnly,
140
@Nullable String sameSite) {
141
this.name = name;
142
this.value = value;
143
this.path = path == null || path.isEmpty() ? "/" : path;
144
145
this.domain = stripPort(domain);
146
this.isSecure = isSecure;
147
this.isHttpOnly = isHttpOnly;
148
149
if (expiry != null) {
150
// Expiration date is specified in seconds since (UTC) epoch time, so truncate the date.
151
this.expiry = new Date(expiry.getTime() / 1000 * 1000);
152
} else {
153
this.expiry = null;
154
}
155
156
this.sameSite = sameSite;
157
}
158
159
/**
160
* Create a cookie for the default path with the given name and value with no expiry set.
161
*
162
* @param name The cookie's name
163
* @param value The cookie's value
164
*/
165
public Cookie(String name, String value) {
166
this(name, value, "/", null);
167
}
168
169
/**
170
* Create a cookie.
171
*
172
* @param name The cookie's name
173
* @param value The cookie's value
174
* @param path The path the cookie is for
175
*/
176
public Cookie(String name, String value, String path) {
177
this(name, value, path, null);
178
}
179
180
public String getName() {
181
return name;
182
}
183
184
public String getValue() {
185
return value;
186
}
187
188
public @Nullable String getDomain() {
189
return domain;
190
}
191
192
public String getPath() {
193
return path;
194
}
195
196
public boolean isSecure() {
197
return isSecure;
198
}
199
200
public boolean isHttpOnly() {
201
return isHttpOnly;
202
}
203
204
public @Nullable Date getExpiry() {
205
return expiry == null ? null : new Date(expiry.getTime());
206
}
207
208
public @Nullable String getSameSite() {
209
return sameSite;
210
}
211
212
private static @Nullable String stripPort(@Nullable String domain) {
213
return (domain == null) ? null : domain.split(":")[0];
214
}
215
216
public void validate() {
217
if (name == null || name.isEmpty() || value == null || path == null) {
218
throw new IllegalArgumentException(
219
"Required attributes are not set or " + "any non-null attribute set to null");
220
}
221
222
if (name.indexOf(';') != -1) {
223
throw new IllegalArgumentException("Cookie names cannot contain a ';': " + name);
224
}
225
226
if (domain != null && domain.contains(":")) {
227
throw new IllegalArgumentException("Domain should not contain a port: " + domain);
228
}
229
}
230
231
/**
232
* JSON object keys are defined in
233
* https://w3c.github.io/webdriver/#dfn-table-for-cookie-conversion.
234
*/
235
public Map<String, Object> toJson() {
236
Map<String, Object> toReturn = new TreeMap<>();
237
238
if (getDomain() != null) {
239
toReturn.put("domain", getDomain());
240
}
241
242
if (getExpiry() != null) {
243
toReturn.put("expiry", getExpiry());
244
}
245
246
if (getName() != null) {
247
toReturn.put("name", getName());
248
}
249
250
if (getPath() != null) {
251
toReturn.put("path", getPath());
252
}
253
254
if (getValue() != null) {
255
toReturn.put("value", getValue());
256
}
257
258
toReturn.put("secure", isSecure());
259
toReturn.put("httpOnly", isHttpOnly());
260
261
if (getSameSite() != null) {
262
toReturn.put("sameSite", getSameSite());
263
}
264
265
return toReturn;
266
}
267
268
@Override
269
public String toString() {
270
SimpleDateFormat sdf = new SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss z");
271
sdf.setTimeZone(TimeZone.getTimeZone("GMT"));
272
return name
273
+ "="
274
+ value
275
+ (expiry == null ? "" : "; expires=" + sdf.format(expiry))
276
+ ("".equals(path) ? "" : "; path=" + path)
277
+ (domain == null ? "" : "; domain=" + domain)
278
+ (isSecure ? ";secure;" : "")
279
+ (sameSite == null ? "" : "; sameSite=" + sameSite);
280
}
281
282
/** Two cookies are equal if the name and value match */
283
@Override
284
public boolean equals(@Nullable Object o) {
285
if (this == o) {
286
return true;
287
}
288
if (!(o instanceof Cookie)) {
289
return false;
290
}
291
292
Cookie cookie = (Cookie) o;
293
294
if (!name.equals(cookie.name)) {
295
return false;
296
}
297
return Objects.equals(value, cookie.value);
298
}
299
300
@Override
301
public int hashCode() {
302
return name.hashCode();
303
}
304
305
public static class Builder {
306
307
private final String name;
308
private final String value;
309
private @Nullable String path;
310
private @Nullable String domain;
311
private @Nullable Date expiry;
312
private boolean secure;
313
private boolean httpOnly;
314
private @Nullable String sameSite;
315
316
public Builder(String name, String value) {
317
this.name = name;
318
this.value = value;
319
}
320
321
public Builder domain(@Nullable String host) {
322
this.domain = stripPort(host);
323
return this;
324
}
325
326
public Builder path(@Nullable String path) {
327
this.path = path;
328
return this;
329
}
330
331
public Builder expiresOn(@Nullable Date expiry) {
332
this.expiry = expiry == null ? null : new Date(expiry.getTime());
333
return this;
334
}
335
336
public Builder isSecure(boolean secure) {
337
this.secure = secure;
338
return this;
339
}
340
341
public Builder isHttpOnly(boolean httpOnly) {
342
this.httpOnly = httpOnly;
343
return this;
344
}
345
346
public Builder sameSite(@Nullable String sameSite) {
347
this.sameSite = sameSite;
348
return this;
349
}
350
351
public Cookie build() {
352
return new Cookie(name, value, domain, path, expiry, secure, httpOnly, sameSite);
353
}
354
}
355
}
356
357