View Javadoc

1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one
3    * or more contributor license agreements.  See the NOTICE file
4    * distributed with this work for additional information
5    * regarding copyright ownership.  The ASF licenses this file
6    * to you under the Apache License, Version 2.0 (the
7    * "License"); you may not use this file except in compliance
8    * with the License.  You may obtain a copy of the License at
9    *
10   * http://www.apache.org/licenses/LICENSE-2.0
11   *
12   * Unless required by applicable law or agreed to in writing,
13   * software distributed under the License is distributed on an
14   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15   * KIND, either express or implied.  See the License for the
16   * specific language governing permissions and limitations
17   * under the License.
18   */
19  /*
20   * This class has been taken from Apache Harmony (http://harmony.apache.org/) 
21   * and has been modified to work with OpenCMIS.
22   */
23  package org.apache.chemistry.opencmis.client.bindings.spi.cookies;
24  
25  import java.io.Serializable;
26  import java.net.URI;
27  import java.util.ArrayDeque;
28  import java.util.ArrayList;
29  import java.util.Iterator;
30  import java.util.List;
31  import java.util.Locale;
32  import java.util.regex.Pattern;
33  
34  /**
35   * Provides an in-memory cookie store.
36   */
37  public class CmisCookieStoreImpl implements Serializable {
38      private static final long serialVersionUID = 1L;
39  
40      private static final String IP_ADDRESS_PATTERN_STR = "^([01]?\\d\\d?|2[0-4]\\d|25[0-5])\\.([01]?\\d\\d?|2[0-4]\\d|25[0-5])\\.([01]?\\d\\d?|2[0-4]\\d|25[0-5])\\.([01]?\\d\\d?|2[0-4]\\d|25[0-5])$";
41      private static final Pattern IP_ADDRESS_PATTERN = Pattern.compile(IP_ADDRESS_PATTERN_STR);
42  
43      private final int maxUrls;
44      private final ArrayDeque<CmisHttpCookie> storeList;
45  
46      public CmisCookieStoreImpl() {
47          this(300);
48      }
49  
50      public CmisCookieStoreImpl(final int maxUrls) {
51          this.maxUrls = maxUrls;
52          storeList = new ArrayDeque<CmisHttpCookie>(64);
53      }
54  
55      public void add(final URI uri, final CmisHttpCookie cookie) {
56          if (uri == null || cookie == null) {
57              throw new IllegalArgumentException("URI and cookie must be set!");
58          }
59  
60          if (cookie.hasExpired()) {
61              storeList.remove(cookie);
62              return;
63          }
64  
65          Iterator<CmisHttpCookie> iter = storeList.iterator();
66          while (iter.hasNext()) {
67              CmisHttpCookie storeCookie = iter.next();
68  
69              if (storeCookie.equals(cookie) || storeCookie.hasExpired()) {
70                  iter.remove();
71              }
72          }
73  
74          storeList.addFirst(cookie);
75  
76          if (storeList.size() > maxUrls) {
77              storeList.removeLast();
78          }
79      }
80  
81      public List<CmisHttpCookie> get(URI uri) {
82          if (uri == null) {
83              throw new IllegalArgumentException("URI is null!");
84          }
85  
86          final String uriHost = uri.getHost().toLowerCase(Locale.ENGLISH);
87  
88          boolean isSecure = false;
89          String scheme = uri.getScheme();
90          if (scheme != null) {
91              isSecure = scheme.toLowerCase(Locale.ENGLISH).startsWith("https");
92          }
93  
94          List<CmisHttpCookie> cookies = new ArrayList<CmisHttpCookie>();
95  
96          Iterator<CmisHttpCookie> iter = storeList.iterator();
97          while (iter.hasNext()) {
98              CmisHttpCookie cookie = iter.next();
99  
100             if (cookie.hasExpired()) {
101                 iter.remove();
102             } else if ((!cookie.getSecure() || isSecure) && cookie.getDomain() != null) {
103                 String cookieDomain = cookie.getDomain().toLowerCase(Locale.ENGLISH);
104 
105                 if (isIPAddress(uriHost) && uriHost.equals(cookieDomain)) {
106                     cookies.add(cookie);
107                 } else {
108                     if (cookie.getVersion() == 0) {
109                         // Netscape, RFC 2109, RFC 6265
110                         if (uriHost.endsWith(cookieDomain)
111                                 && (uriHost.length() == cookieDomain.length() || cookieDomain.charAt(0) == '.')) {
112                             cookies.add(cookie);
113                         }
114                     } else if (cookie.getVersion() == 1) {
115                         // RFC 2965
116                         if (CmisHttpCookie.domainMatches(cookieDomain, uriHost)) {
117                             cookies.add(cookie);
118                         }
119                     }
120                 }
121             }
122         }
123 
124         return cookies;
125     }
126 
127     public void clear() {
128         storeList.clear();
129     }
130 
131     private boolean isIPAddress(String s) {
132         if (s.charAt(0) == '[') {
133             // IPv6
134             return true;
135         }
136 
137         if (IP_ADDRESS_PATTERN.matcher(s).matches()) {
138             // IPv4
139             return true;
140         }
141 
142         return false;
143     }
144 }