< prev index next >

src/java.base/share/classes/java/net/InMemoryCookieStore.java

Print this page




  45  */
  46 class InMemoryCookieStore implements CookieStore {
  47     // the in-memory representation of cookies
  48     private List<HttpCookie> cookieJar = null;
  49 
  50     // the cookies are indexed by its domain and associated uri (if present)
  51     // CAUTION: when a cookie removed from main data structure (i.e. cookieJar),
  52     //          it won't be cleared in domainIndex & uriIndex. Double-check the
  53     //          presence of cookie when retrieve one form index store.
  54     private Map<String, List<HttpCookie>> domainIndex = null;
  55     private Map<URI, List<HttpCookie>> uriIndex = null;
  56 
  57     // use ReentrantLock instead of syncronized for scalability
  58     private ReentrantLock lock = null;
  59 
  60 
  61     /**
  62      * The default ctor
  63      */
  64     public InMemoryCookieStore() {
  65         cookieJar = new ArrayList<HttpCookie>();
  66         domainIndex = new HashMap<String, List<HttpCookie>>();
  67         uriIndex = new HashMap<URI, List<HttpCookie>>();
  68 
  69         lock = new ReentrantLock(false);
  70     }
  71 
  72     /**
  73      * Add one cookie into cookie store.
  74      */
  75     public void add(URI uri, HttpCookie cookie) {
  76         // pre-condition : argument can't be null
  77         if (cookie == null) {
  78             throw new NullPointerException("cookie is null");
  79         }
  80 
  81 
  82         lock.lock();
  83         try {
  84             // remove the ole cookie if there has had one
  85             cookieJar.remove(cookie);
  86 
  87             // add new cookie if it has a non-zero max-age


  98             }
  99         } finally {
 100             lock.unlock();
 101         }
 102     }
 103 
 104 
 105     /**
 106      * Get all cookies, which:
 107      *  1) given uri domain-matches with, or, associated with
 108      *     given uri when added to the cookie store.
 109      *  3) not expired.
 110      * See RFC 2965 sec. 3.3.4 for more detail.
 111      */
 112     public List<HttpCookie> get(URI uri) {
 113         // argument can't be null
 114         if (uri == null) {
 115             throw new NullPointerException("uri is null");
 116         }
 117 
 118         List<HttpCookie> cookies = new ArrayList<HttpCookie>();
 119         boolean secureLink = "https".equalsIgnoreCase(uri.getScheme());
 120         lock.lock();
 121         try {
 122             // check domainIndex first
 123             getInternal1(cookies, domainIndex, uri.getHost(), secureLink);
 124             // check uriIndex then
 125             getInternal2(cookies, uriIndex, getEffectiveURI(uri), secureLink);
 126         } finally {
 127             lock.unlock();
 128         }
 129 
 130         return cookies;
 131     }
 132 
 133     /**
 134      * Get all cookies in cookie store, except those have expired
 135      */
 136     public List<HttpCookie> getCookies() {
 137         List<HttpCookie> rt;
 138 


 140         try {
 141             Iterator<HttpCookie> it = cookieJar.iterator();
 142             while (it.hasNext()) {
 143                 if (it.next().hasExpired()) {
 144                     it.remove();
 145                 }
 146             }
 147         } finally {
 148             rt = Collections.unmodifiableList(cookieJar);
 149             lock.unlock();
 150         }
 151 
 152         return rt;
 153     }
 154 
 155     /**
 156      * Get all URIs, which are associated with at least one cookie
 157      * of this cookie store.
 158      */
 159     public List<URI> getURIs() {
 160         List<URI> uris = new ArrayList<URI>();
 161 
 162         lock.lock();
 163         try {
 164             Iterator<URI> it = uriIndex.keySet().iterator();
 165             while (it.hasNext()) {
 166                 URI uri = it.next();
 167                 List<HttpCookie> cookies = uriIndex.get(uri);
 168                 if (cookies == null || cookies.size() == 0) {
 169                     // no cookies list or an empty list associated with
 170                     // this uri entry, delete it
 171                     it.remove();
 172                 }
 173             }
 174         } finally {
 175             uris.addAll(uriIndex.keySet());
 176             lock.unlock();
 177         }
 178 
 179         return uris;
 180     }


 264             return host.equalsIgnoreCase(domain);
 265         } else if (lengthDiff > 0) {
 266             // need to check H & D component
 267             String H = host.substring(0, lengthDiff);
 268             String D = host.substring(lengthDiff);
 269 
 270             return (D.equalsIgnoreCase(domain));
 271         } else if (lengthDiff == -1) {
 272             // if domain is actually .host
 273             return (domain.charAt(0) == '.' &&
 274                     host.equalsIgnoreCase(domain.substring(1)));
 275         }
 276 
 277         return false;
 278     }
 279 
 280     private void getInternal1(List<HttpCookie> cookies, Map<String, List<HttpCookie>> cookieIndex,
 281             String host, boolean secureLink) {
 282         // Use a separate list to handle cookies that need to be removed so
 283         // that there is no conflict with iterators.
 284         ArrayList<HttpCookie> toRemove = new ArrayList<HttpCookie>();
 285         for (Map.Entry<String, List<HttpCookie>> entry : cookieIndex.entrySet()) {
 286             String domain = entry.getKey();
 287             List<HttpCookie> lst = entry.getValue();
 288             for (HttpCookie c : lst) {
 289                 if ((c.getVersion() == 0 && netscapeDomainMatches(domain, host)) ||
 290                         (c.getVersion() == 1 && HttpCookie.domainMatches(domain, host))) {
 291                     if ((cookieJar.indexOf(c) != -1)) {
 292                         // the cookie still in main cookie store
 293                         if (!c.hasExpired()) {
 294                             // don't add twice and make sure it's the proper
 295                             // security level
 296                             if ((secureLink || !c.getSecure()) &&
 297                                     !cookies.contains(c)) {
 298                                 cookies.add(c);
 299                             }
 300                         } else {
 301                             toRemove.add(c);
 302                         }
 303                     } else {
 304                         // the cookie has beed removed from main store,


 351                         }
 352                     }
 353                 } // end of indexedCookies != null
 354             } // end of comparator.compareTo(index) == 0
 355         } // end of cookieIndex iteration
 356     }
 357 
 358     // add 'cookie' indexed by 'index' into 'indexStore'
 359     private <T> void addIndex(Map<T, List<HttpCookie>> indexStore,
 360                               T index,
 361                               HttpCookie cookie)
 362     {
 363         if (index != null) {
 364             List<HttpCookie> cookies = indexStore.get(index);
 365             if (cookies != null) {
 366                 // there may already have the same cookie, so remove it first
 367                 cookies.remove(cookie);
 368 
 369                 cookies.add(cookie);
 370             } else {
 371                 cookies = new ArrayList<HttpCookie>();
 372                 cookies.add(cookie);
 373                 indexStore.put(index, cookies);
 374             }
 375         }
 376     }
 377 
 378 
 379     //
 380     // for cookie purpose, the effective uri should only be http://host
 381     // the path will be taken into account when path-match algorithm applied
 382     //
 383     private URI getEffectiveURI(URI uri) {
 384         URI effectiveURI = null;
 385         try {
 386             effectiveURI = new URI("http",
 387                                    uri.getHost(),
 388                                    null,  // path component
 389                                    null,  // query component
 390                                    null   // fragment component
 391                                   );


  45  */
  46 class InMemoryCookieStore implements CookieStore {
  47     // the in-memory representation of cookies
  48     private List<HttpCookie> cookieJar = null;
  49 
  50     // the cookies are indexed by its domain and associated uri (if present)
  51     // CAUTION: when a cookie removed from main data structure (i.e. cookieJar),
  52     //          it won't be cleared in domainIndex & uriIndex. Double-check the
  53     //          presence of cookie when retrieve one form index store.
  54     private Map<String, List<HttpCookie>> domainIndex = null;
  55     private Map<URI, List<HttpCookie>> uriIndex = null;
  56 
  57     // use ReentrantLock instead of syncronized for scalability
  58     private ReentrantLock lock = null;
  59 
  60 
  61     /**
  62      * The default ctor
  63      */
  64     public InMemoryCookieStore() {
  65         cookieJar = new ArrayList<>();
  66         domainIndex = new HashMap<>();
  67         uriIndex = new HashMap<>();
  68 
  69         lock = new ReentrantLock(false);
  70     }
  71 
  72     /**
  73      * Add one cookie into cookie store.
  74      */
  75     public void add(URI uri, HttpCookie cookie) {
  76         // pre-condition : argument can't be null
  77         if (cookie == null) {
  78             throw new NullPointerException("cookie is null");
  79         }
  80 
  81 
  82         lock.lock();
  83         try {
  84             // remove the ole cookie if there has had one
  85             cookieJar.remove(cookie);
  86 
  87             // add new cookie if it has a non-zero max-age


  98             }
  99         } finally {
 100             lock.unlock();
 101         }
 102     }
 103 
 104 
 105     /**
 106      * Get all cookies, which:
 107      *  1) given uri domain-matches with, or, associated with
 108      *     given uri when added to the cookie store.
 109      *  3) not expired.
 110      * See RFC 2965 sec. 3.3.4 for more detail.
 111      */
 112     public List<HttpCookie> get(URI uri) {
 113         // argument can't be null
 114         if (uri == null) {
 115             throw new NullPointerException("uri is null");
 116         }
 117 
 118         List<HttpCookie> cookies = new ArrayList<>();
 119         boolean secureLink = "https".equalsIgnoreCase(uri.getScheme());
 120         lock.lock();
 121         try {
 122             // check domainIndex first
 123             getInternal1(cookies, domainIndex, uri.getHost(), secureLink);
 124             // check uriIndex then
 125             getInternal2(cookies, uriIndex, getEffectiveURI(uri), secureLink);
 126         } finally {
 127             lock.unlock();
 128         }
 129 
 130         return cookies;
 131     }
 132 
 133     /**
 134      * Get all cookies in cookie store, except those have expired
 135      */
 136     public List<HttpCookie> getCookies() {
 137         List<HttpCookie> rt;
 138 


 140         try {
 141             Iterator<HttpCookie> it = cookieJar.iterator();
 142             while (it.hasNext()) {
 143                 if (it.next().hasExpired()) {
 144                     it.remove();
 145                 }
 146             }
 147         } finally {
 148             rt = Collections.unmodifiableList(cookieJar);
 149             lock.unlock();
 150         }
 151 
 152         return rt;
 153     }
 154 
 155     /**
 156      * Get all URIs, which are associated with at least one cookie
 157      * of this cookie store.
 158      */
 159     public List<URI> getURIs() {
 160         List<URI> uris = new ArrayList<>();
 161 
 162         lock.lock();
 163         try {
 164             Iterator<URI> it = uriIndex.keySet().iterator();
 165             while (it.hasNext()) {
 166                 URI uri = it.next();
 167                 List<HttpCookie> cookies = uriIndex.get(uri);
 168                 if (cookies == null || cookies.size() == 0) {
 169                     // no cookies list or an empty list associated with
 170                     // this uri entry, delete it
 171                     it.remove();
 172                 }
 173             }
 174         } finally {
 175             uris.addAll(uriIndex.keySet());
 176             lock.unlock();
 177         }
 178 
 179         return uris;
 180     }


 264             return host.equalsIgnoreCase(domain);
 265         } else if (lengthDiff > 0) {
 266             // need to check H & D component
 267             String H = host.substring(0, lengthDiff);
 268             String D = host.substring(lengthDiff);
 269 
 270             return (D.equalsIgnoreCase(domain));
 271         } else if (lengthDiff == -1) {
 272             // if domain is actually .host
 273             return (domain.charAt(0) == '.' &&
 274                     host.equalsIgnoreCase(domain.substring(1)));
 275         }
 276 
 277         return false;
 278     }
 279 
 280     private void getInternal1(List<HttpCookie> cookies, Map<String, List<HttpCookie>> cookieIndex,
 281             String host, boolean secureLink) {
 282         // Use a separate list to handle cookies that need to be removed so
 283         // that there is no conflict with iterators.
 284         ArrayList<HttpCookie> toRemove = new ArrayList<>();
 285         for (Map.Entry<String, List<HttpCookie>> entry : cookieIndex.entrySet()) {
 286             String domain = entry.getKey();
 287             List<HttpCookie> lst = entry.getValue();
 288             for (HttpCookie c : lst) {
 289                 if ((c.getVersion() == 0 && netscapeDomainMatches(domain, host)) ||
 290                         (c.getVersion() == 1 && HttpCookie.domainMatches(domain, host))) {
 291                     if ((cookieJar.indexOf(c) != -1)) {
 292                         // the cookie still in main cookie store
 293                         if (!c.hasExpired()) {
 294                             // don't add twice and make sure it's the proper
 295                             // security level
 296                             if ((secureLink || !c.getSecure()) &&
 297                                     !cookies.contains(c)) {
 298                                 cookies.add(c);
 299                             }
 300                         } else {
 301                             toRemove.add(c);
 302                         }
 303                     } else {
 304                         // the cookie has beed removed from main store,


 351                         }
 352                     }
 353                 } // end of indexedCookies != null
 354             } // end of comparator.compareTo(index) == 0
 355         } // end of cookieIndex iteration
 356     }
 357 
 358     // add 'cookie' indexed by 'index' into 'indexStore'
 359     private <T> void addIndex(Map<T, List<HttpCookie>> indexStore,
 360                               T index,
 361                               HttpCookie cookie)
 362     {
 363         if (index != null) {
 364             List<HttpCookie> cookies = indexStore.get(index);
 365             if (cookies != null) {
 366                 // there may already have the same cookie, so remove it first
 367                 cookies.remove(cookie);
 368 
 369                 cookies.add(cookie);
 370             } else {
 371                 cookies = new ArrayList<>();
 372                 cookies.add(cookie);
 373                 indexStore.put(index, cookies);
 374             }
 375         }
 376     }
 377 
 378 
 379     //
 380     // for cookie purpose, the effective uri should only be http://host
 381     // the path will be taken into account when path-match algorithm applied
 382     //
 383     private URI getEffectiveURI(URI uri) {
 384         URI effectiveURI = null;
 385         try {
 386             effectiveURI = new URI("http",
 387                                    uri.getHost(),
 388                                    null,  // path component
 389                                    null,  // query component
 390                                    null   // fragment component
 391                                   );
< prev index next >