View Javadoc
1   /*
2    * Copyright (c) 2002-2025 Gargoyle Software Inc.
3    *
4    * Licensed under the Apache License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    * https://www.apache.org/licenses/LICENSE-2.0
8    *
9    * Unless required by applicable law or agreed to in writing, software
10   * distributed under the License is distributed on an "AS IS" BASIS,
11   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12   * See the License for the specific language governing permissions and
13   * limitations under the License.
14   */
15  package org.htmlunit;
16  
17  import java.io.Serializable;
18  import java.util.Collections;
19  import java.util.Date;
20  import java.util.Iterator;
21  import java.util.LinkedHashSet;
22  import java.util.Objects;
23  import java.util.Set;
24  
25  import org.htmlunit.util.Cookie;
26  
27  /**
28   * Manages cookies for a {@link WebClient}. This class is thread-safe.
29   * You can disable Cookies by calling setCookiesEnabled(false). The
30   * CookieManager itself takes care of this and ignores all cookie request if
31   * disabled. If you override this your methods have to do the same.
32   *
33   * @author Daniel Gredler
34   * @author Ahmed Ashour
35   * @author Nicolas Belisle
36   * @author Ronald Brill
37   */
38  public class CookieManager implements Serializable {
39  
40      /** Whether or not cookies are enabled. */
41      private boolean cookiesEnabled_;
42  
43      /** The cookies added to this cookie manager. */
44      private final Set<Cookie> cookies_ = new LinkedHashSet<>();
45  
46      /**
47       * Creates a new instance.
48       */
49      public CookieManager() {
50          cookiesEnabled_ = true;
51      }
52  
53      /**
54       * Enables/disables cookie support. Cookies are enabled by default.
55       * @param enabled {@code true} to enable cookie support, {@code false} otherwise
56       */
57      public synchronized void setCookiesEnabled(final boolean enabled) {
58          cookiesEnabled_ = enabled;
59      }
60  
61      /**
62       * Returns {@code true} if cookies are enabled. Cookies are enabled by default.
63       * @return {@code true} if cookies are enabled, {@code false} otherwise
64       */
65      public synchronized boolean isCookiesEnabled() {
66          return cookiesEnabled_;
67      }
68  
69      /**
70       * Returns the currently configured cookies, in an unmodifiable set.
71       * If disabled, this returns an empty set.
72       * @return the currently configured cookies, in an unmodifiable set
73       */
74      public synchronized Set<Cookie> getCookies() {
75          if (!isCookiesEnabled()) {
76              return Collections.emptySet();
77          }
78  
79          final Set<Cookie> copy = new LinkedHashSet<>(cookies_);
80          return Collections.unmodifiableSet(copy);
81      }
82  
83      /**
84       * Clears all cookies that have expired before supplied date.
85       * If disabled, this returns false.
86       * @param date the date to use for comparison when clearing expired cookies
87       * @return whether any cookies were found expired, and were cleared
88       */
89      public synchronized boolean clearExpired(final Date date) {
90          if (!isCookiesEnabled()) {
91              return false;
92          }
93  
94          if (date == null) {
95              return false;
96          }
97  
98          boolean foundExpired = false;
99          for (final Iterator<Cookie> iter = cookies_.iterator(); iter.hasNext();) {
100             final Cookie cookie = iter.next();
101             if (cookie.getExpires() != null && date.after(cookie.getExpires())) {
102                 iter.remove();
103                 foundExpired = true;
104             }
105         }
106         return foundExpired;
107     }
108 
109     /**
110      * Returns the currently configured cookie with the specified name, or {@code null} if one does not exist.
111      * If disabled, this returns null.
112      * @param name the name of the cookie to return
113      * @return the currently configured cookie with the specified name, or {@code null} if one does not exist
114      */
115     public synchronized Cookie getCookie(final String name) {
116         if (!isCookiesEnabled()) {
117             return null;
118         }
119 
120         for (final Cookie cookie : cookies_) {
121             if (Objects.equals(cookie.getName(), name)) {
122                 return cookie;
123             }
124         }
125         return null;
126     }
127 
128     /**
129      * Adds the specified cookie.
130      * If disabled, this does nothing.
131      * @param cookie the cookie to add
132      */
133     public synchronized void addCookie(final Cookie cookie) {
134         if (!isCookiesEnabled()) {
135             return;
136         }
137 
138         cookies_.remove(cookie);
139 
140         // don't add expired cookie
141         if (cookie.getExpires() == null || cookie.getExpires().after(new Date())) {
142             cookies_.add(cookie);
143         }
144     }
145 
146     /**
147      * Removes the specified cookie.
148      * If disabled, this does nothing.
149      * @param cookie the cookie to remove
150      */
151     public synchronized void removeCookie(final Cookie cookie) {
152         if (!isCookiesEnabled()) {
153             return;
154         }
155 
156         cookies_.remove(cookie);
157     }
158 
159     /**
160      * Removes all cookies.
161      * If disabled, this does nothing.
162      */
163     public synchronized void clearCookies() {
164         if (!isCookiesEnabled()) {
165             return;
166         }
167 
168         cookies_.clear();
169     }
170 }