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