37 import java.util.Iterator;
38 import java.util.concurrent.locks.ReentrantLock;
39
40 /**
41 * A simple in-memory java.net.CookieStore implementation
42 *
43 * @author Edward Wang
44 * @since 1.6
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) {
243
244 // if there's no embedded dot in domain and domain is not .local
245 boolean isLocalDomain = ".local".equalsIgnoreCase(domain);
246 int embeddedDotInDomain = domain.indexOf('.');
247 if (embeddedDotInDomain == 0) {
248 embeddedDotInDomain = domain.indexOf('.', 1);
249 }
250 if (!isLocalDomain && (embeddedDotInDomain == -1 || embeddedDotInDomain == domain.length() - 1)) {
251 return false;
252 }
253
254 // if the host name contains no dot and the domain name is .local
255 int firstDotInHost = host.indexOf('.');
256 if (firstDotInHost == -1 && isLocalDomain) {
257 return true;
258 }
259
260 int domainLength = domain.length();
261 int lengthDiff = host.length() - domainLength;
262 if (lengthDiff == 0) {
263 // if the host name and the domain name are just string-compare euqal
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,
305 // so also remove it from domain indexed store
306 toRemove.add(c);
307 }
308 }
309 }
310 // Clear up the cookies that need to be removed
311 for (HttpCookie c : toRemove) {
312 lst.remove(c);
313 cookieJar.remove(c);
314
315 }
316 toRemove.clear();
317 }
318 }
319
320 // @param cookies [OUT] contains the found cookies
321 // @param cookieIndex the index
322 // @param comparator the prediction to decide whether or not
323 // a cookie in index should be returned
324 private <T> void getInternal2(List<HttpCookie> cookies,
328 for (T index : cookieIndex.keySet()) {
329 if (comparator.compareTo(index) == 0) {
330 List<HttpCookie> indexedCookies = cookieIndex.get(index);
331 // check the list of cookies associated with this domain
332 if (indexedCookies != null) {
333 Iterator<HttpCookie> it = indexedCookies.iterator();
334 while (it.hasNext()) {
335 HttpCookie ck = it.next();
336 if (cookieJar.indexOf(ck) != -1) {
337 // the cookie still in main cookie store
338 if (!ck.hasExpired()) {
339 // don't add twice
340 if ((secureLink || !ck.getSecure()) &&
341 !cookies.contains(ck))
342 cookies.add(ck);
343 } else {
344 it.remove();
345 cookieJar.remove(ck);
346 }
347 } else {
348 // the cookie has beed removed from main store,
349 // so also remove it from domain indexed store
350 it.remove();
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
|
37 import java.util.Iterator;
38 import java.util.concurrent.locks.ReentrantLock;
39
40 /**
41 * A simple in-memory java.net.CookieStore implementation
42 *
43 * @author Edward Wang
44 * @since 1.6
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 synchronized 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) {
243
244 // if there's no embedded dot in domain and domain is not .local
245 boolean isLocalDomain = ".local".equalsIgnoreCase(domain);
246 int embeddedDotInDomain = domain.indexOf('.');
247 if (embeddedDotInDomain == 0) {
248 embeddedDotInDomain = domain.indexOf('.', 1);
249 }
250 if (!isLocalDomain && (embeddedDotInDomain == -1 || embeddedDotInDomain == domain.length() - 1)) {
251 return false;
252 }
253
254 // if the host name contains no dot and the domain name is .local
255 int firstDotInHost = host.indexOf('.');
256 if (firstDotInHost == -1 && isLocalDomain) {
257 return true;
258 }
259
260 int domainLength = domain.length();
261 int lengthDiff = host.length() - domainLength;
262 if (lengthDiff == 0) {
263 // if the host name and the domain name are just string-compare equal
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 been removed from main store,
305 // so also remove it from domain indexed store
306 toRemove.add(c);
307 }
308 }
309 }
310 // Clear up the cookies that need to be removed
311 for (HttpCookie c : toRemove) {
312 lst.remove(c);
313 cookieJar.remove(c);
314
315 }
316 toRemove.clear();
317 }
318 }
319
320 // @param cookies [OUT] contains the found cookies
321 // @param cookieIndex the index
322 // @param comparator the prediction to decide whether or not
323 // a cookie in index should be returned
324 private <T> void getInternal2(List<HttpCookie> cookies,
328 for (T index : cookieIndex.keySet()) {
329 if (comparator.compareTo(index) == 0) {
330 List<HttpCookie> indexedCookies = cookieIndex.get(index);
331 // check the list of cookies associated with this domain
332 if (indexedCookies != null) {
333 Iterator<HttpCookie> it = indexedCookies.iterator();
334 while (it.hasNext()) {
335 HttpCookie ck = it.next();
336 if (cookieJar.indexOf(ck) != -1) {
337 // the cookie still in main cookie store
338 if (!ck.hasExpired()) {
339 // don't add twice
340 if ((secureLink || !ck.getSecure()) &&
341 !cookies.contains(ck))
342 cookies.add(ck);
343 } else {
344 it.remove();
345 cookieJar.remove(ck);
346 }
347 } else {
348 // the cookie has been removed from main store,
349 // so also remove it from domain indexed store
350 it.remove();
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
|