151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski/* 22c87ad3a45cecf9e344487cad1abfdebe79f2c7cNarayan Kamath * Copyright (C) 2014 The Android Open Source Project 351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Copyright (c) 2005, 2008, Oracle and/or its affiliates. All rights reserved. 451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * This code is free software; you can redistribute it and/or modify it 751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * under the terms of the GNU General Public License version 2 only, as 851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * published by the Free Software Foundation. Oracle designates this 951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * particular file as subject to the "Classpath" exception as provided 1051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * by Oracle in the LICENSE file that accompanied this code. 1151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 1251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * This code is distributed in the hope that it will be useful, but WITHOUT 1351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 1451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 1551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * version 2 for more details (a copy is included in the LICENSE file that 1651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * accompanied this code). 1751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 1851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * You should have received a copy of the GNU General Public License version 1951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 2 along with this work; if not, write to the Free Software Foundation, 2051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 2151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 2251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 2351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * or visit www.oracle.com if you need additional information or have any 2451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * questions. 2551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 2651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 2751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebskipackage java.net; 2851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 297363410d6ab95420d62cc5e2ee52801a693781ebNarayan Kamathimport dalvik.system.VMRuntime; 307363410d6ab95420d62cc5e2ee52801a693781ebNarayan Kamath 3151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebskiimport java.util.ArrayList; 32225d1301a97641464a1b437219eb60853260b28cNarayan Kamathimport java.util.Collections; 337363410d6ab95420d62cc5e2ee52801a693781ebNarayan Kamathimport java.util.HashMap; 3451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebskiimport java.util.Iterator; 357363410d6ab95420d62cc5e2ee52801a693781ebNarayan Kamathimport java.util.List; 367363410d6ab95420d62cc5e2ee52801a693781ebNarayan Kamathimport java.util.Map; 3751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebskiimport java.util.concurrent.locks.ReentrantLock; 3851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 3951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski/** 4051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * A simple in-memory java.net.CookieStore implementation 4151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 4251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @author Edward Wang 4351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @since 1.6 447363410d6ab95420d62cc5e2ee52801a693781ebNarayan Kamath * @hide Visible for testing only. 4551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 467363410d6ab95420d62cc5e2ee52801a693781ebNarayan Kamathpublic class InMemoryCookieStore implements CookieStore { 4751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // the in-memory representation of cookies 4851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private Map<URI, List<HttpCookie>> uriIndex = null; 4951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 5051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // use ReentrantLock instead of syncronized for scalability 5151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private ReentrantLock lock = null; 5251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 537363410d6ab95420d62cc5e2ee52801a693781ebNarayan Kamath private final boolean applyMCompatibility; 547363410d6ab95420d62cc5e2ee52801a693781ebNarayan Kamath 5551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 5651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * The default ctor 5751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 5851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public InMemoryCookieStore() { 597363410d6ab95420d62cc5e2ee52801a693781ebNarayan Kamath this(VMRuntime.getRuntime().getTargetSdkVersion()); 607363410d6ab95420d62cc5e2ee52801a693781ebNarayan Kamath } 617363410d6ab95420d62cc5e2ee52801a693781ebNarayan Kamath 627363410d6ab95420d62cc5e2ee52801a693781ebNarayan Kamath public InMemoryCookieStore(int targetSdkVersion) { 637363410d6ab95420d62cc5e2ee52801a693781ebNarayan Kamath uriIndex = new HashMap<>(); 6451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski lock = new ReentrantLock(false); 657363410d6ab95420d62cc5e2ee52801a693781ebNarayan Kamath applyMCompatibility = (targetSdkVersion <= 23); 6651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 6751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 6851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 6951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Add one cookie into cookie store. 7051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 7151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public void add(URI uri, HttpCookie cookie) { 7251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // pre-condition : argument can't be null 7351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (cookie == null) { 7451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throw new NullPointerException("cookie is null"); 7551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 7651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 7751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski lock.lock(); 7851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski try { 79a5f1c8ef223a10b956f259d60f715d99ac4f04efPrzemyslaw Szczepaniak if (cookie.getMaxAge() != 0) { 80a5f1c8ef223a10b956f259d60f715d99ac4f04efPrzemyslaw Szczepaniak addIndex(uriIndex, getEffectiveURI(uri), cookie); 8151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 8251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } finally { 8351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski lock.unlock(); 8451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 8551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 8651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 8751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 8851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 8951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Get all cookies, which: 9051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 1) given uri domain-matches with, or, associated with 9151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * given uri when added to the cookie store. 9251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 3) not expired. 9351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * See RFC 2965 sec. 3.3.4 for more detail. 9451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 9551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public List<HttpCookie> get(URI uri) { 9651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // argument can't be null 9751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (uri == null) { 9851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throw new NullPointerException("uri is null"); 9951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 10051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 10151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski List<HttpCookie> cookies = new ArrayList<HttpCookie>(); 10251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski lock.lock(); 10351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski try { 10451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // check domainIndex first 1057938429403c009accb92834db70288110b017115Przemyslaw Szczepaniak getInternal1(cookies, uriIndex, uri.getHost()); 10651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // check uriIndex then 1077938429403c009accb92834db70288110b017115Przemyslaw Szczepaniak getInternal2(cookies, uriIndex, getEffectiveURI(uri)); 10851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } finally { 10951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski lock.unlock(); 11051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 11151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 11251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return cookies; 11351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 11451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 11551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 11651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Get all cookies in cookie store, except those have expired 11751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 11851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public List<HttpCookie> getCookies() { 119a5f1c8ef223a10b956f259d60f715d99ac4f04efPrzemyslaw Szczepaniak List<HttpCookie> rt = new ArrayList<HttpCookie>(); 12051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 12151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski lock.lock(); 12251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski try { 123a5f1c8ef223a10b956f259d60f715d99ac4f04efPrzemyslaw Szczepaniak for (List<HttpCookie> list : uriIndex.values()) { 124a5f1c8ef223a10b956f259d60f715d99ac4f04efPrzemyslaw Szczepaniak Iterator<HttpCookie> it = list.iterator(); 125a5f1c8ef223a10b956f259d60f715d99ac4f04efPrzemyslaw Szczepaniak while (it.hasNext()) { 126a5f1c8ef223a10b956f259d60f715d99ac4f04efPrzemyslaw Szczepaniak HttpCookie cookie = it.next(); 127a5f1c8ef223a10b956f259d60f715d99ac4f04efPrzemyslaw Szczepaniak if (cookie.hasExpired()) { 128a5f1c8ef223a10b956f259d60f715d99ac4f04efPrzemyslaw Szczepaniak it.remove(); 129a5f1c8ef223a10b956f259d60f715d99ac4f04efPrzemyslaw Szczepaniak } else if (!rt.contains(cookie)) { 130a5f1c8ef223a10b956f259d60f715d99ac4f04efPrzemyslaw Szczepaniak rt.add(cookie); 131a5f1c8ef223a10b956f259d60f715d99ac4f04efPrzemyslaw Szczepaniak } 13251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 13351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 13451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } finally { 135a5f1c8ef223a10b956f259d60f715d99ac4f04efPrzemyslaw Szczepaniak rt = Collections.unmodifiableList(rt); 13651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski lock.unlock(); 13751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 13851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 13951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return rt; 14051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 14151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 14251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 14351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Get all URIs, which are associated with at least one cookie 14451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * of this cookie store. 14551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 14651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public List<URI> getURIs() { 14751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski List<URI> uris = new ArrayList<URI>(); 14851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 14951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski lock.lock(); 15051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski try { 151a5f1c8ef223a10b956f259d60f715d99ac4f04efPrzemyslaw Szczepaniak List<URI> result = new ArrayList<URI>(uriIndex.keySet()); 152a5f1c8ef223a10b956f259d60f715d99ac4f04efPrzemyslaw Szczepaniak result.remove(null); 153a5f1c8ef223a10b956f259d60f715d99ac4f04efPrzemyslaw Szczepaniak return Collections.unmodifiableList(result); 15451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } finally { 15551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski uris.addAll(uriIndex.keySet()); 15651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski lock.unlock(); 15751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 15851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 15951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 16051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 16151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 16251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Remove a cookie from store 16351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 16451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public boolean remove(URI uri, HttpCookie ck) { 16551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // argument can't be null 16651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (ck == null) { 16751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throw new NullPointerException("cookie is null"); 16851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 16951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 17051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski lock.lock(); 17151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski try { 172a5f1c8ef223a10b956f259d60f715d99ac4f04efPrzemyslaw Szczepaniak uri = getEffectiveURI(uri); 1739f7cb9dbab95a1c94864063908d213487d17535eNarayan Kamath if (uriIndex.get(uri) == null) { 174a5f1c8ef223a10b956f259d60f715d99ac4f04efPrzemyslaw Szczepaniak return false; 1755a7bc45f8f662d0673779aad34fc595309d93526Przemyslaw Szczepaniak } else { 176a5f1c8ef223a10b956f259d60f715d99ac4f04efPrzemyslaw Szczepaniak List<HttpCookie> cookies = uriIndex.get(uri); 177a5f1c8ef223a10b956f259d60f715d99ac4f04efPrzemyslaw Szczepaniak if (cookies != null) { 178a5f1c8ef223a10b956f259d60f715d99ac4f04efPrzemyslaw Szczepaniak return cookies.remove(ck); 179a5f1c8ef223a10b956f259d60f715d99ac4f04efPrzemyslaw Szczepaniak } else { 180a5f1c8ef223a10b956f259d60f715d99ac4f04efPrzemyslaw Szczepaniak return false; 181a5f1c8ef223a10b956f259d60f715d99ac4f04efPrzemyslaw Szczepaniak } 1825a7bc45f8f662d0673779aad34fc595309d93526Przemyslaw Szczepaniak } 18351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } finally { 18451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski lock.unlock(); 18551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 18651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 18751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 18851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 18951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 19051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Remove all cookies in this cookie store. 19151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 19251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public boolean removeAll() { 19351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski lock.lock(); 1945a7bc45f8f662d0673779aad34fc595309d93526Przemyslaw Szczepaniak boolean result = false; 1955a7bc45f8f662d0673779aad34fc595309d93526Przemyslaw Szczepaniak 19651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski try { 197a5f1c8ef223a10b956f259d60f715d99ac4f04efPrzemyslaw Szczepaniak result = !uriIndex.isEmpty(); 19851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski uriIndex.clear(); 19951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } finally { 20051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski lock.unlock(); 20151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 20251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 2035a7bc45f8f662d0673779aad34fc595309d93526Przemyslaw Szczepaniak return result; 20451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 20551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 20651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 20751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /* ---------------- Private operations -------------- */ 20851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 20951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 21051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /* 21151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * This is almost the same as HttpCookie.domainMatches except for 21251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * one difference: It won't reject cookies when the 'H' part of the 21351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * domain contains a dot ('.'). 21451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * I.E.: RFC 2965 section 3.3.2 says that if host is x.y.domain.com 21551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * and the cookie domain is .domain.com, then it should be rejected. 21651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * However that's not how the real world works. Browsers don't reject and 21751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * some sites, like yahoo.com do actually expect these cookies to be 21851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * passed along. 21951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * And should be used for 'old' style cookies (aka Netscape type of cookies) 22051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 22151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private boolean netscapeDomainMatches(String domain, String host) 22251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski { 22351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (domain == null || host == null) { 22451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return false; 22551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 22651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 22751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // if there's no embedded dot in domain and domain is not .local 22851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski boolean isLocalDomain = ".local".equalsIgnoreCase(domain); 22951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski int embeddedDotInDomain = domain.indexOf('.'); 23051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (embeddedDotInDomain == 0) { 23151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski embeddedDotInDomain = domain.indexOf('.', 1); 23251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 23351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (!isLocalDomain && (embeddedDotInDomain == -1 || embeddedDotInDomain == domain.length() - 1)) { 23451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return false; 23551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 23651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 23751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // if the host name contains no dot and the domain name is .local 23851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski int firstDotInHost = host.indexOf('.'); 23951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (firstDotInHost == -1 && isLocalDomain) { 24051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return true; 24151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 24251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 24351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski int domainLength = domain.length(); 24451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski int lengthDiff = host.length() - domainLength; 24551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (lengthDiff == 0) { 24651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // if the host name and the domain name are just string-compare euqal 24751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return host.equalsIgnoreCase(domain); 24851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } else if (lengthDiff > 0) { 24951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // need to check H & D component 25051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski String D = host.substring(lengthDiff); 25151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 2527363410d6ab95420d62cc5e2ee52801a693781ebNarayan Kamath // Android M and earlier: Cookies with domain "foo.com" would not match "bar.foo.com". 2537363410d6ab95420d62cc5e2ee52801a693781ebNarayan Kamath // The RFC dictates that the user agent must treat those domains as if they had a 2547363410d6ab95420d62cc5e2ee52801a693781ebNarayan Kamath // leading period and must therefore match "bar.foo.com". 2557363410d6ab95420d62cc5e2ee52801a693781ebNarayan Kamath if (applyMCompatibility && !domain.startsWith(".")) { 2567363410d6ab95420d62cc5e2ee52801a693781ebNarayan Kamath return false; 2577363410d6ab95420d62cc5e2ee52801a693781ebNarayan Kamath } 2587363410d6ab95420d62cc5e2ee52801a693781ebNarayan Kamath 259225d1301a97641464a1b437219eb60853260b28cNarayan Kamath return (D.equalsIgnoreCase(domain)); 26051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } else if (lengthDiff == -1) { 26151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // if domain is actually .host 26251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return (domain.charAt(0) == '.' && 26351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski host.equalsIgnoreCase(domain.substring(1))); 26451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 26551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 26651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return false; 26751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 26851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 269a5f1c8ef223a10b956f259d60f715d99ac4f04efPrzemyslaw Szczepaniak private void getInternal1(List<HttpCookie> cookies, Map<URI, List<HttpCookie>> cookieIndex, 2707938429403c009accb92834db70288110b017115Przemyslaw Szczepaniak String host) { 27151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // Use a separate list to handle cookies that need to be removed so 27251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // that there is no conflict with iterators. 27351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski ArrayList<HttpCookie> toRemove = new ArrayList<HttpCookie>(); 274a5f1c8ef223a10b956f259d60f715d99ac4f04efPrzemyslaw Szczepaniak for (Map.Entry<URI, List<HttpCookie>> entry : cookieIndex.entrySet()) { 27551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski List<HttpCookie> lst = entry.getValue(); 27651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski for (HttpCookie c : lst) { 277a5f1c8ef223a10b956f259d60f715d99ac4f04efPrzemyslaw Szczepaniak String domain = c.getDomain(); 27851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if ((c.getVersion() == 0 && netscapeDomainMatches(domain, host)) || 27951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski (c.getVersion() == 1 && HttpCookie.domainMatches(domain, host))) { 280a5f1c8ef223a10b956f259d60f715d99ac4f04efPrzemyslaw Szczepaniak 281a5f1c8ef223a10b956f259d60f715d99ac4f04efPrzemyslaw Szczepaniak // the cookie still in main cookie store 282a5f1c8ef223a10b956f259d60f715d99ac4f04efPrzemyslaw Szczepaniak if (!c.hasExpired()) { 2837938429403c009accb92834db70288110b017115Przemyslaw Szczepaniak // don't add twice 2847938429403c009accb92834db70288110b017115Przemyslaw Szczepaniak if (!cookies.contains(c)) { 285a5f1c8ef223a10b956f259d60f715d99ac4f04efPrzemyslaw Szczepaniak cookies.add(c); 28651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 28751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } else { 28851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski toRemove.add(c); 28951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 29051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 29151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 29251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // Clear up the cookies that need to be removed 29351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski for (HttpCookie c : toRemove) { 29451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski lst.remove(c); 29551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 29651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 29751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski toRemove.clear(); 29851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 29951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 30051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 30151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // @param cookies [OUT] contains the found cookies 30251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // @param cookieIndex the index 30351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // @param comparator the prediction to decide whether or not 30451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // a cookie in index should be returned 3059f7cb9dbab95a1c94864063908d213487d17535eNarayan Kamath private <T extends Comparable<T>> 3069f7cb9dbab95a1c94864063908d213487d17535eNarayan Kamath void getInternal2(List<HttpCookie> cookies, Map<T, List<HttpCookie>> cookieIndex, 3077938429403c009accb92834db70288110b017115Przemyslaw Szczepaniak T comparator) 30851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski { 309a5f1c8ef223a10b956f259d60f715d99ac4f04efPrzemyslaw Szczepaniak // Removed cookieJar 31051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski for (T index : cookieIndex.keySet()) { 3119f7cb9dbab95a1c94864063908d213487d17535eNarayan Kamath if ((index == comparator) || (index != null && comparator.compareTo(index) == 0)) { 31251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski List<HttpCookie> indexedCookies = cookieIndex.get(index); 31351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // check the list of cookies associated with this domain 31451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (indexedCookies != null) { 31551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski Iterator<HttpCookie> it = indexedCookies.iterator(); 31651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski while (it.hasNext()) { 31751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski HttpCookie ck = it.next(); 318a5f1c8ef223a10b956f259d60f715d99ac4f04efPrzemyslaw Szczepaniak // the cookie still in main cookie store 319a5f1c8ef223a10b956f259d60f715d99ac4f04efPrzemyslaw Szczepaniak if (!ck.hasExpired()) { 320a5f1c8ef223a10b956f259d60f715d99ac4f04efPrzemyslaw Szczepaniak // don't add twice 3217938429403c009accb92834db70288110b017115Przemyslaw Szczepaniak if (!cookies.contains(ck)) 322a5f1c8ef223a10b956f259d60f715d99ac4f04efPrzemyslaw Szczepaniak cookies.add(ck); 32351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } else { 32451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski it.remove(); 32551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 32651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 32751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } // end of indexedCookies != null 32851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } // end of comparator.compareTo(index) == 0 32951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } // end of cookieIndex iteration 33051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 33151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 33251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // add 'cookie' indexed by 'index' into 'indexStore' 33351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private <T> void addIndex(Map<T, List<HttpCookie>> indexStore, 33451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski T index, 33551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski HttpCookie cookie) 33651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski { 3379f7cb9dbab95a1c94864063908d213487d17535eNarayan Kamath // Android-changed : "index" can be null. We only use the URI based 3389f7cb9dbab95a1c94864063908d213487d17535eNarayan Kamath // index on Android and we want to support null URIs. The underlying 3399f7cb9dbab95a1c94864063908d213487d17535eNarayan Kamath // store is a HashMap which will support null keys anyway. 3409f7cb9dbab95a1c94864063908d213487d17535eNarayan Kamath List<HttpCookie> cookies = indexStore.get(index); 3419f7cb9dbab95a1c94864063908d213487d17535eNarayan Kamath if (cookies != null) { 3429f7cb9dbab95a1c94864063908d213487d17535eNarayan Kamath // there may already have the same cookie, so remove it first 3439f7cb9dbab95a1c94864063908d213487d17535eNarayan Kamath cookies.remove(cookie); 3449f7cb9dbab95a1c94864063908d213487d17535eNarayan Kamath 3459f7cb9dbab95a1c94864063908d213487d17535eNarayan Kamath cookies.add(cookie); 3469f7cb9dbab95a1c94864063908d213487d17535eNarayan Kamath } else { 3479f7cb9dbab95a1c94864063908d213487d17535eNarayan Kamath cookies = new ArrayList<HttpCookie>(); 3489f7cb9dbab95a1c94864063908d213487d17535eNarayan Kamath cookies.add(cookie); 3499f7cb9dbab95a1c94864063908d213487d17535eNarayan Kamath indexStore.put(index, cookies); 35051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 35151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 35251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 35351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 35451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // 35551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // for cookie purpose, the effective uri should only be http://host 35651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // the path will be taken into account when path-match algorithm applied 35751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // 35851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private URI getEffectiveURI(URI uri) { 35951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski URI effectiveURI = null; 360a5f1c8ef223a10b956f259d60f715d99ac4f04efPrzemyslaw Szczepaniak if (uri == null) { 361a5f1c8ef223a10b956f259d60f715d99ac4f04efPrzemyslaw Szczepaniak return null; 362a5f1c8ef223a10b956f259d60f715d99ac4f04efPrzemyslaw Szczepaniak } 36351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski try { 36451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski effectiveURI = new URI("http", 36551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski uri.getHost(), 36651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski null, // path component 36751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski null, // query component 36851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski null // fragment component 36951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski ); 37051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } catch (URISyntaxException ignored) { 37151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski effectiveURI = uri; 37251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 37351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 37451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return effectiveURI; 37551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 37651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski} 377