Coverage Report - wjhk.jupload2.upload.helper.CookieJar
 
Classes in this File Line Coverage Branch Coverage Complexity
CookieJar
0 %
0/100
0 %
0/62
5,5
CookieJar$Cookie
0 %
0/36
0 %
0/18
5,5
 
 1  
 //
 2  
 // $Id: CookieJar.java 816 2009-06-26 18:49:10Z etienne_sf $
 3  
 //
 4  
 // jupload - A file upload applet.
 5  
 //
 6  
 // Copyright 2007 The JUpload Team
 7  
 //
 8  
 // Created: 08.06.2007
 9  
 // Creator: felfert
 10  
 // Last modified: $Date: 2009-06-26 20:49:10 +0200 (ven., 26 juin 2009) $
 11  
 //
 12  
 // This program is free software; you can redistribute it and/or modify
 13  
 // it under the terms of the GNU General Public License as published by
 14  
 // the Free Software Foundation; either version 2 of the License, or
 15  
 // (at your option) any later version.
 16  
 //
 17  
 // This program is distributed in the hope that it will be useful,
 18  
 // but WITHOUT ANY WARRANTY; without even the implied warranty of
 19  
 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 20  
 // GNU General Public License for more details.
 21  
 //
 22  
 // You should have received a copy of the GNU General Public License
 23  
 // along with this program; if not, write to the Free Software
 24  
 // Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 25  
 
 26  
 package wjhk.jupload2.upload.helper;
 27  
 
 28  
 import java.net.URL;
 29  
 import java.text.ParseException;
 30  
 import java.text.SimpleDateFormat;
 31  
 import java.util.HashMap;
 32  
 import java.util.StringTokenizer;
 33  
 import java.util.regex.Matcher;
 34  
 import java.util.regex.Pattern;
 35  
 
 36  
 import wjhk.jupload2.policies.UploadPolicy;
 37  
 
 38  
 /**
 39  
  * This class implements a container for multiple cookies in a single domain.
 40  
  * 
 41  
  * @author felfert
 42  
  */
 43  
 public class CookieJar {
 44  
 
 45  0
     final static Pattern pNvPair = Pattern.compile(
 46  
             "^\\s*([^=\\s]+)(\\s*=\\s*(.+))*$", Pattern.CASE_INSENSITIVE);
 47  
 
 48  
     /**
 49  
      * The current upload policy, always useful.
 50  
      */
 51  0
     private UploadPolicy uploadPolicy = null;
 52  
 
 53  0
     private HashMap<String, Cookie> jar = new HashMap<String, Cookie>();
 54  
 
 55  0
     private String domain = null;
 56  
 
 57  0
     private static class Cookie implements Cloneable {
 58  
 
 59  0
         String domain = null;
 60  
 
 61  0
         String name = null;
 62  
 
 63  0
         String value = null;
 64  
 
 65  0
         String path = null;
 66  
 
 67  0
         long max_age = 0;
 68  
 
 69  0
         int version = 0;
 70  
 
 71  0
         int secure = 0;
 72  
 
 73  0
         Cookie() {
 74  
             //
 75  0
         }
 76  
 
 77  
         /**
 78  
          * @throws CloneNotSupportedException
 79  
          * @see java.lang.Object#clone()
 80  
          */
 81  
         @Override
 82  
         public Cookie clone() throws CloneNotSupportedException {
 83  0
             Cookie ret = (Cookie) super.clone();
 84  0
             ret.domain = this.domain;
 85  0
             ret.name = this.name;
 86  0
             ret.value = this.value;
 87  0
             ret.path = this.path;
 88  0
             ret.max_age = this.max_age;
 89  0
             ret.version = this.version;
 90  0
             ret.secure = this.secure;
 91  0
             return ret;
 92  
         }
 93  
 
 94  
         /**
 95  
          * Retrieves the hash value of this cookie. Cookies are hashed by name
 96  
          * and path.
 97  
          * 
 98  
          * @return The hash value of this cookie.
 99  
          */
 100  
         public String getKey() {
 101  0
             String ret = this.name;
 102  0
             if (null != this.path)
 103  0
                 ret += this.path;
 104  0
             return ret;
 105  
         }
 106  
 
 107  
         /**
 108  
          * Returns a single client cookie header element
 109  
          * 
 110  
          * @param path The path of the corresponding request URI
 111  
          * @param secure 1, if the current connection is secure (SSL), 0
 112  
          *            otherwise
 113  
          * @return The part of the cookie header or an empty string
 114  
          */
 115  
         public String getHeader(String path, int secure) {
 116  0
             StringBuffer sb = new StringBuffer();
 117  0
             if ((null == this.path || this.path.equals("/") || this.path
 118  0
                     .startsWith(path))
 119  
                     && (this.secure <= secure)
 120  0
                     && (this.max_age > System.currentTimeMillis())) {
 121  0
                 if (this.version > 0) {
 122  0
                     sb.append("$Version=").append(this.version).append("; ");
 123  0
                     sb.append(this.name).append("=").append(this.value).append(
 124  
                             ";");
 125  0
                     if (null != this.path)
 126  0
                         sb.append(" $Path=").append(this.path).append(";");
 127  0
                     if (null != this.domain)
 128  0
                         sb.append(" $Domain=").append(this.domain).append(";");
 129  
                 } else {
 130  0
                     sb.append(this.name).append("=").append(this.value).append(
 131  
                             ";");
 132  
                 }
 133  
             }
 134  0
             return sb.toString();
 135  
         }
 136  
 
 137  
     }
 138  
 
 139  
     /*
 140  
      * **************************************************************************
 141  
      * *************************** Start of CookieJar code
 142  
      * ***********************
 143  
      * ***************************************************
 144  
      * **************************
 145  
      */
 146  
 
 147  
     /**
 148  
      * The creator for this class.
 149  
      * 
 150  
      * @param uploadPolicy The current upload policy
 151  
      */
 152  0
     public CookieJar(UploadPolicy uploadPolicy) {
 153  0
         this.uploadPolicy = uploadPolicy;
 154  0
     }
 155  
 
 156  
     private String stripQuotes(String s) {
 157  0
         if (s.startsWith("\"") && s.endsWith("\""))
 158  0
             return s.substring(1, s.length() - 1);
 159  0
         return s;
 160  
     }
 161  
 
 162  
     private boolean domainMatch(String cd) {
 163  0
         if (cd == null) {
 164  0
             return false;
 165  
         } else {
 166  0
             if (!cd.startsWith(".")) {
 167  0
                 int dot = cd.indexOf('.');
 168  0
                 if (dot >= 0)
 169  0
                     cd = cd.substring(dot);
 170  
 
 171  
             }
 172  0
             return cd.equals(this.domain);
 173  
         }
 174  
     }
 175  
 
 176  
     /**
 177  
      * Sets the domain for this cookie jar. If set, only cookies matching the
 178  
      * specified domain are handled.
 179  
      * 
 180  
      * @param domain The domain of this instance
 181  
      */
 182  
     public void setDomain(String domain) {
 183  0
         if (!domain.startsWith(".")) {
 184  0
             int dot = domain.indexOf('.');
 185  0
             if (dot >= 0)
 186  0
                 domain = domain.substring(dot);
 187  
 
 188  
         }
 189  0
         this.domain = domain;
 190  0
     }
 191  
 
 192  
     /**
 193  
      * Builds a RFC 2109 compliant client cookie header for the specified URL.
 194  
      * 
 195  
      * @param url The URL for which the cookie header is to be used.
 196  
      * @return A client cookie header (including the "Cookie: " prefix) or null
 197  
      *         if no cookies are to be set.
 198  
      */
 199  
     public String buildCookieHeader(URL url) {
 200  0
         String domain = url.getHost();
 201  0
         int dot = domain.indexOf('.');
 202  0
         if (dot >= 0)
 203  0
             domain = domain.substring(dot);
 204  0
         if (domain.equals(this.domain)) {
 205  0
             String path = url.getPath();
 206  0
             int secure = url.getProtocol().equalsIgnoreCase("https") ? 1 : 0;
 207  0
             StringBuffer sb = new StringBuffer();
 208  0
             for (String key : this.jar.keySet()) {
 209  0
                 Cookie c = this.jar.get(key);
 210  0
                 if (null != c)
 211  0
                     sb.append(c.getHeader(path, secure));
 212  0
             }
 213  0
             if (sb.length() > 0) {
 214  0
                 sb.append("\r\n");
 215  0
                 return "Cookie: " + sb.toString();
 216  
             }
 217  
         }
 218  0
         return null;
 219  
     }
 220  
 
 221  
     /**
 222  
      * Parses a "Set-Cookie" header and creates/updates/deletes cookies
 223  
      * according to the parsed values. Parsing is done according to the
 224  
      * specification in RFC 2109
 225  
      * 
 226  
      * @param s The plain value of the "Set-Cookie" HTTP header. e.g.: without
 227  
      *            the "Set-Cookie: " prefix.
 228  
      */
 229  
     public void parseCookieHeader(String s) {
 230  0
         StringTokenizer t = new StringTokenizer(s, ";");
 231  0
         Cookie cookie = new Cookie();
 232  0
         while (t.hasMoreTokens()) {
 233  0
             Matcher m = pNvPair.matcher(t.nextToken());
 234  0
             if (m.matches()) {
 235  0
                 String n = m.group(1);
 236  0
                 String v = (m.groupCount() > 2 && m.group(3) != null) ? m
 237  0
                         .group(3).trim() : "";
 238  0
                 if (n.compareToIgnoreCase("version") == 0) {
 239  0
                     cookie.version = Integer.parseInt(v);
 240  0
                     continue;
 241  
                 }
 242  0
                 if (n.compareToIgnoreCase("domain") == 0) {
 243  0
                     cookie.domain = v;
 244  0
                     continue;
 245  
                 }
 246  0
                 if (n.compareToIgnoreCase("path") == 0) {
 247  0
                     cookie.path = v;
 248  0
                     continue;
 249  
                 }
 250  0
                 if (n.compareToIgnoreCase("max-age") == 0) {
 251  0
                     cookie.max_age = Integer.parseInt(v);
 252  0
                     if (cookie.max_age < 0)
 253  0
                         cookie.max_age = 0;
 254  0
                     cookie.max_age *= 1000;
 255  0
                     cookie.max_age += System.currentTimeMillis();
 256  0
                     continue;
 257  
                 }
 258  0
                 if (n.compareToIgnoreCase("expires") == 0) {
 259  0
                     SimpleDateFormat df = new SimpleDateFormat(
 260  
                             "EEE, dd-MMM-yy HH:mm:ss zzz");
 261  
                     try {
 262  0
                         cookie.max_age = System.currentTimeMillis()
 263  0
                                 - df.parse(v).getTime();
 264  0
                         if (cookie.max_age < 0)
 265  0
                             cookie.max_age = 0;
 266  0
                     } catch (ParseException e) {
 267  0
                         cookie.max_age = 0;
 268  0
                     }
 269  0
                     continue;
 270  
                 }
 271  0
                 if (n.compareToIgnoreCase("comment") == 0) {
 272  
                     // ignored
 273  0
                     continue;
 274  
                 }
 275  0
                 if (n.compareToIgnoreCase("secure") == 0) {
 276  0
                     cookie.secure = 1;
 277  0
                     continue;
 278  
                 }
 279  0
                 if (!n.startsWith("$")) {
 280  0
                     if (null != cookie.name) {
 281  0
                         if (cookie.version > 0) {
 282  
                             // Strip possible quotes
 283  0
                             cookie.domain = stripQuotes(cookie.domain);
 284  0
                             cookie.path = stripQuotes(cookie.path);
 285  
                             // cookie.comment = stripQuotes(cookie.comment);
 286  
                             // cookie.name = stripQuotes(cookie.name);
 287  
                             // cookie.value = stripQuotes(cookie.value);
 288  
                         }
 289  0
                         if (domainMatch(cookie.domain)) {
 290  0
                             if (cookie.max_age > 0) {
 291  0
                                 this.jar.put(cookie.getKey(), cookie);
 292  0
                                 this.uploadPolicy.displayDebug(
 293  
                                         "[CookieJar] Adding cookie: "
 294  0
                                                 + cookie.getKey() + ": "
 295  
                                                 + cookie, 50);
 296  
 
 297  
                             } else {
 298  0
                                 this.jar.put(cookie.getKey(), null);
 299  0
                                 this.uploadPolicy.displayDebug(
 300  
                                         "[CookieJar] Ignoring cookie: "
 301  0
                                                 + cookie.getKey() + ": "
 302  
                                                 + cookie, 50);
 303  
                             }
 304  
                         }
 305  
                         try {
 306  0
                             cookie = cookie.clone();
 307  0
                         } catch (CloneNotSupportedException e) {
 308  0
                             cookie = new Cookie();
 309  0
                         }
 310  
                     }
 311  0
                     cookie.name = n;
 312  0
                     cookie.value = v;
 313  
                 }
 314  
             }
 315  0
         }
 316  0
     }
 317  
 }