InMemoryCookieStore.java revision 51b1b6997fd3f980076b8081f7f1165ccc2a4008
151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski/* 251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Copyright (c) 2005, 2008, Oracle and/or its affiliates. All rights reserved. 351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * This code is free software; you can redistribute it and/or modify it 651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * under the terms of the GNU General Public License version 2 only, as 751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * published by the Free Software Foundation. Oracle designates this 851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * particular file as subject to the "Classpath" exception as provided 951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * by Oracle in the LICENSE file that accompanied this code. 1051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 1151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * This code is distributed in the hope that it will be useful, but WITHOUT 1251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 1351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 1451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * version 2 for more details (a copy is included in the LICENSE file that 1551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * accompanied this code). 1651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 1751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * You should have received a copy of the GNU General Public License version 1851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 2 along with this work; if not, write to the Free Software Foundation, 1951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 2051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 2151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 2251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * or visit www.oracle.com if you need additional information or have any 2351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * questions. 2451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 2551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 2651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebskipackage java.net; 2751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 2851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebskiimport java.net.URI; 2951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebskiimport java.net.CookieStore; 3051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebskiimport java.net.HttpCookie; 3151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebskiimport java.net.URISyntaxException; 3251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebskiimport java.util.List; 3351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebskiimport java.util.Map; 3451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebskiimport java.util.ArrayList; 3551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebskiimport java.util.HashMap; 3651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebskiimport java.util.Collections; 3751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebskiimport java.util.Iterator; 3851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebskiimport java.util.concurrent.locks.ReentrantLock; 3951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 4051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski/** 4151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * A simple in-memory java.net.CookieStore implementation 4251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 4351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @author Edward Wang 4451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @since 1.6 4551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 4651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebskiclass InMemoryCookieStore implements CookieStore { 4751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // the in-memory representation of cookies 4851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private List<HttpCookie> cookieJar = null; 4951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 5051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // the cookies are indexed by its domain and associated uri (if present) 5151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // CAUTION: when a cookie removed from main data structure (i.e. cookieJar), 5251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // it won't be cleared in domainIndex & uriIndex. Double-check the 5351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // presence of cookie when retrieve one form index store. 5451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private Map<String, List<HttpCookie>> domainIndex = null; 5551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private Map<URI, List<HttpCookie>> uriIndex = null; 5651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 5751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // use ReentrantLock instead of syncronized for scalability 5851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private ReentrantLock lock = null; 5951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 6051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 6151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 6251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * The default ctor 6351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 6451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public InMemoryCookieStore() { 6551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski cookieJar = new ArrayList<HttpCookie>(); 6651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski domainIndex = new HashMap<String, List<HttpCookie>>(); 6751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski uriIndex = new HashMap<URI, List<HttpCookie>>(); 6851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 6951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski lock = new ReentrantLock(false); 7051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 7151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 7251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 7351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Add one cookie into cookie store. 7451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 7551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public void add(URI uri, HttpCookie cookie) { 7651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // pre-condition : argument can't be null 7751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (cookie == null) { 7851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throw new NullPointerException("cookie is null"); 7951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 8051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 8151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 8251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski lock.lock(); 8351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski try { 8451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // remove the ole cookie if there has had one 8551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski cookieJar.remove(cookie); 8651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 8751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // add new cookie if it has a non-zero max-age 8851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (cookie.getMaxAge() != 0) { 8951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski cookieJar.add(cookie); 9051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // and add it to domain index 9151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (cookie.getDomain() != null) { 9251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski addIndex(domainIndex, cookie.getDomain(), cookie); 9351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 9451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (uri != null) { 9551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // add it to uri index, too 9651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski addIndex(uriIndex, getEffectiveURI(uri), cookie); 9751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 9851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 9951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } finally { 10051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski lock.unlock(); 10151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 10251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 10351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 10451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 10551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 10651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Get all cookies, which: 10751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 1) given uri domain-matches with, or, associated with 10851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * given uri when added to the cookie store. 10951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 3) not expired. 11051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * See RFC 2965 sec. 3.3.4 for more detail. 11151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 11251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public List<HttpCookie> get(URI uri) { 11351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // argument can't be null 11451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (uri == null) { 11551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throw new NullPointerException("uri is null"); 11651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 11751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 11851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski List<HttpCookie> cookies = new ArrayList<HttpCookie>(); 11951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski boolean secureLink = "https".equalsIgnoreCase(uri.getScheme()); 12051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski lock.lock(); 12151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski try { 12251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // check domainIndex first 12351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski getInternal1(cookies, domainIndex, uri.getHost(), secureLink); 12451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // check uriIndex then 12551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski getInternal2(cookies, uriIndex, getEffectiveURI(uri), secureLink); 12651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } finally { 12751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski lock.unlock(); 12851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 12951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 13051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return cookies; 13151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 13251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 13351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 13451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Get all cookies in cookie store, except those have expired 13551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 13651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public List<HttpCookie> getCookies() { 13751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski List<HttpCookie> rt; 13851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 13951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski lock.lock(); 14051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski try { 14151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski Iterator<HttpCookie> it = cookieJar.iterator(); 14251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski while (it.hasNext()) { 14351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (it.next().hasExpired()) { 14451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski it.remove(); 14551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 14651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 14751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } finally { 14851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski rt = Collections.unmodifiableList(cookieJar); 14951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski lock.unlock(); 15051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 15151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 15251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return rt; 15351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 15451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 15551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 15651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Get all URIs, which are associated with at least one cookie 15751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * of this cookie store. 15851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 15951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public List<URI> getURIs() { 16051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski List<URI> uris = new ArrayList<URI>(); 16151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 16251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski lock.lock(); 16351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski try { 16451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski Iterator<URI> it = uriIndex.keySet().iterator(); 16551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski while (it.hasNext()) { 16651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski URI uri = it.next(); 16751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski List<HttpCookie> cookies = uriIndex.get(uri); 16851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (cookies == null || cookies.size() == 0) { 16951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // no cookies list or an empty list associated with 17051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // this uri entry, delete it 17151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski it.remove(); 17251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 17351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 17451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } finally { 17551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski uris.addAll(uriIndex.keySet()); 17651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski lock.unlock(); 17751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 17851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 17951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return uris; 18051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 18151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 18251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 18351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 18451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Remove a cookie from store 18551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 18651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public boolean remove(URI uri, HttpCookie ck) { 18751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // argument can't be null 18851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (ck == null) { 18951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throw new NullPointerException("cookie is null"); 19051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 19151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 19251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski boolean modified = false; 19351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski lock.lock(); 19451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski try { 19551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski modified = cookieJar.remove(ck); 19651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } finally { 19751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski lock.unlock(); 19851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 19951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 20051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return modified; 20151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 20251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 20351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 20451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 20551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Remove all cookies in this cookie store. 20651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 20751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public boolean removeAll() { 20851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski lock.lock(); 20951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski try { 21051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski cookieJar.clear(); 21151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski domainIndex.clear(); 21251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski uriIndex.clear(); 21351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } finally { 21451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski lock.unlock(); 21551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 21651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 21751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return true; 21851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 21951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 22051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 22151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /* ---------------- Private operations -------------- */ 22251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 22351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 22451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /* 22551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * This is almost the same as HttpCookie.domainMatches except for 22651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * one difference: It won't reject cookies when the 'H' part of the 22751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * domain contains a dot ('.'). 22851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * I.E.: RFC 2965 section 3.3.2 says that if host is x.y.domain.com 22951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * and the cookie domain is .domain.com, then it should be rejected. 23051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * However that's not how the real world works. Browsers don't reject and 23151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * some sites, like yahoo.com do actually expect these cookies to be 23251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * passed along. 23351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * And should be used for 'old' style cookies (aka Netscape type of cookies) 23451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 23551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private boolean netscapeDomainMatches(String domain, String host) 23651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski { 23751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (domain == null || host == null) { 23851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return false; 23951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 24051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 24151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // if there's no embedded dot in domain and domain is not .local 24251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski boolean isLocalDomain = ".local".equalsIgnoreCase(domain); 24351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski int embeddedDotInDomain = domain.indexOf('.'); 24451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (embeddedDotInDomain == 0) { 24551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski embeddedDotInDomain = domain.indexOf('.', 1); 24651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 24751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (!isLocalDomain && (embeddedDotInDomain == -1 || embeddedDotInDomain == domain.length() - 1)) { 24851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return false; 24951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 25051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 25151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // if the host name contains no dot and the domain name is .local 25251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski int firstDotInHost = host.indexOf('.'); 25351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (firstDotInHost == -1 && isLocalDomain) { 25451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return true; 25551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 25651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 25751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski int domainLength = domain.length(); 25851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski int lengthDiff = host.length() - domainLength; 25951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (lengthDiff == 0) { 26051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // if the host name and the domain name are just string-compare euqal 26151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return host.equalsIgnoreCase(domain); 26251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } else if (lengthDiff > 0) { 26351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // need to check H & D component 26451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski String H = host.substring(0, lengthDiff); 26551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski String D = host.substring(lengthDiff); 26651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 26751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return (D.equalsIgnoreCase(domain)); 26851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } else if (lengthDiff == -1) { 26951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // if domain is actually .host 27051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return (domain.charAt(0) == '.' && 27151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski host.equalsIgnoreCase(domain.substring(1))); 27251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 27351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 27451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return false; 27551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 27651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 27751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private void getInternal1(List<HttpCookie> cookies, Map<String, List<HttpCookie>> cookieIndex, 27851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski String host, boolean secureLink) { 27951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // Use a separate list to handle cookies that need to be removed so 28051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // that there is no conflict with iterators. 28151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski ArrayList<HttpCookie> toRemove = new ArrayList<HttpCookie>(); 28251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski for (Map.Entry<String, List<HttpCookie>> entry : cookieIndex.entrySet()) { 28351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski String domain = entry.getKey(); 28451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski List<HttpCookie> lst = entry.getValue(); 28551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski for (HttpCookie c : lst) { 28651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if ((c.getVersion() == 0 && netscapeDomainMatches(domain, host)) || 28751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski (c.getVersion() == 1 && HttpCookie.domainMatches(domain, host))) { 28851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if ((cookieJar.indexOf(c) != -1)) { 28951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // the cookie still in main cookie store 29051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (!c.hasExpired()) { 29151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // don't add twice and make sure it's the proper 29251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // security level 29351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if ((secureLink || !c.getSecure()) && 29451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski !cookies.contains(c)) { 29551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski cookies.add(c); 29651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 29751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } else { 29851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski toRemove.add(c); 29951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 30051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } else { 30151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // the cookie has beed removed from main store, 30251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // so also remove it from domain indexed store 30351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski toRemove.add(c); 30451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 30551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 30651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 30751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // Clear up the cookies that need to be removed 30851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski for (HttpCookie c : toRemove) { 30951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski lst.remove(c); 31051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski cookieJar.remove(c); 31151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 31251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 31351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski toRemove.clear(); 31451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 31551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 31651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 31751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // @param cookies [OUT] contains the found cookies 31851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // @param cookieIndex the index 31951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // @param comparator the prediction to decide whether or not 32051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // a cookie in index should be returned 32151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private <T> void getInternal2(List<HttpCookie> cookies, 32251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski Map<T, List<HttpCookie>> cookieIndex, 32351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski Comparable<T> comparator, boolean secureLink) 32451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski { 32551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski for (T index : cookieIndex.keySet()) { 32651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (comparator.compareTo(index) == 0) { 32751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski List<HttpCookie> indexedCookies = cookieIndex.get(index); 32851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // check the list of cookies associated with this domain 32951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (indexedCookies != null) { 33051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski Iterator<HttpCookie> it = indexedCookies.iterator(); 33151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski while (it.hasNext()) { 33251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski HttpCookie ck = it.next(); 33351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (cookieJar.indexOf(ck) != -1) { 33451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // the cookie still in main cookie store 33551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (!ck.hasExpired()) { 33651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // don't add twice 33751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if ((secureLink || !ck.getSecure()) && 33851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski !cookies.contains(ck)) 33951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski cookies.add(ck); 34051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } else { 34151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski it.remove(); 34251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski cookieJar.remove(ck); 34351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 34451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } else { 34551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // the cookie has beed removed from main store, 34651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // so also remove it from domain indexed store 34751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski it.remove(); 34851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 34951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 35051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } // end of indexedCookies != null 35151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } // end of comparator.compareTo(index) == 0 35251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } // end of cookieIndex iteration 35351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 35451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 35551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // add 'cookie' indexed by 'index' into 'indexStore' 35651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private <T> void addIndex(Map<T, List<HttpCookie>> indexStore, 35751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski T index, 35851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski HttpCookie cookie) 35951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski { 36051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (index != null) { 36151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski List<HttpCookie> cookies = indexStore.get(index); 36251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (cookies != null) { 36351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // there may already have the same cookie, so remove it first 36451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski cookies.remove(cookie); 36551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 36651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski cookies.add(cookie); 36751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } else { 36851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski cookies = new ArrayList<HttpCookie>(); 36951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski cookies.add(cookie); 37051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski indexStore.put(index, cookies); 37151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 37251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 37351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 37451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 37551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 37651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // 37751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // for cookie purpose, the effective uri should only be http://host 37851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // the path will be taken into account when path-match algorithm applied 37951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // 38051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private URI getEffectiveURI(URI uri) { 38151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski URI effectiveURI = null; 38251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski try { 38351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski effectiveURI = new URI("http", 38451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski uri.getHost(), 38551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski null, // path component 38651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski null, // query component 38751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski null // fragment component 38851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski ); 38951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } catch (URISyntaxException ignored) { 39051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski effectiveURI = uri; 39151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 39251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 39351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return effectiveURI; 39451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 39551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski} 396