1 /* 2 * $HeadURL: http://svn.apache.org/repos/asf/httpcomponents/httpclient/trunk/module-client/src/main/java/org/apache/http/impl/cookie/BrowserCompatSpec.java $ 3 * $Revision: 657334 $ 4 * $Date: 2008-05-17 04:44:16 -0700 (Sat, 17 May 2008) $ 5 * 6 * ==================================================================== 7 * Licensed to the Apache Software Foundation (ASF) under one 8 * or more contributor license agreements. See the NOTICE file 9 * distributed with this work for additional information 10 * regarding copyright ownership. The ASF licenses this file 11 * to you under the Apache License, Version 2.0 (the 12 * "License"); you may not use this file except in compliance 13 * with the License. You may obtain a copy of the License at 14 * 15 * http://www.apache.org/licenses/LICENSE-2.0 16 * 17 * Unless required by applicable law or agreed to in writing, 18 * software distributed under the License is distributed on an 19 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 20 * KIND, either express or implied. See the License for the 21 * specific language governing permissions and limitations 22 * under the License. 23 * ==================================================================== 24 * 25 * This software consists of voluntary contributions made by many 26 * individuals on behalf of the Apache Software Foundation. For more 27 * information on the Apache Software Foundation, please see 28 * <http://www.apache.org/>. 29 * 30 */ 31 32 package org.apache.http.impl.cookie; 33 34 import java.util.ArrayList; 35 import java.util.List; 36 import java.util.Locale; 37 38 import org.apache.http.FormattedHeader; 39 import org.apache.http.Header; 40 import org.apache.http.HeaderElement; 41 import org.apache.http.cookie.ClientCookie; 42 import org.apache.http.cookie.Cookie; 43 import org.apache.http.cookie.CookieOrigin; 44 import org.apache.http.cookie.MalformedCookieException; 45 import org.apache.http.cookie.SM; 46 import org.apache.http.message.BufferedHeader; 47 import org.apache.http.message.ParserCursor; 48 import org.apache.http.util.CharArrayBuffer; 49 50 /** 51 * Cookie specification that strives to closely mimic (mis)behavior of 52 * common web browser applications such as Microsoft Internet Explorer 53 * and Mozilla FireFox. 54 * 55 * @author <a href="mailto:oleg at ural.ru">Oleg Kalnichevski</a> 56 * 57 * @since 4.0 58 */ 59 public class BrowserCompatSpec extends CookieSpecBase { 60 61 /** Valid date patterns used per default */ 62 protected static final String[] DATE_PATTERNS = new String[] { 63 DateUtils.PATTERN_RFC1123, 64 DateUtils.PATTERN_RFC1036, 65 DateUtils.PATTERN_ASCTIME, 66 "EEE, dd-MMM-yyyy HH:mm:ss z", 67 "EEE, dd-MMM-yyyy HH-mm-ss z", 68 "EEE, dd MMM yy HH:mm:ss z", 69 "EEE dd-MMM-yyyy HH:mm:ss z", 70 "EEE dd MMM yyyy HH:mm:ss z", 71 "EEE dd-MMM-yyyy HH-mm-ss z", 72 "EEE dd-MMM-yy HH:mm:ss z", 73 "EEE dd MMM yy HH:mm:ss z", 74 "EEE,dd-MMM-yy HH:mm:ss z", 75 "EEE,dd-MMM-yyyy HH:mm:ss z", 76 "EEE, dd-MM-yyyy HH:mm:ss z", 77 }; 78 79 private final String[] datepatterns; 80 81 /** Default constructor */ BrowserCompatSpec(final String[] datepatterns)82 public BrowserCompatSpec(final String[] datepatterns) { 83 super(); 84 if (datepatterns != null) { 85 this.datepatterns = datepatterns.clone(); 86 } else { 87 this.datepatterns = DATE_PATTERNS; 88 } 89 registerAttribHandler(ClientCookie.PATH_ATTR, new BasicPathHandler()); 90 registerAttribHandler(ClientCookie.DOMAIN_ATTR, new BasicDomainHandler()); 91 registerAttribHandler(ClientCookie.MAX_AGE_ATTR, new BasicMaxAgeHandler()); 92 registerAttribHandler(ClientCookie.SECURE_ATTR, new BasicSecureHandler()); 93 registerAttribHandler(ClientCookie.COMMENT_ATTR, new BasicCommentHandler()); 94 registerAttribHandler(ClientCookie.EXPIRES_ATTR, new BasicExpiresHandler( 95 this.datepatterns)); 96 } 97 98 /** Default constructor */ BrowserCompatSpec()99 public BrowserCompatSpec() { 100 this(null); 101 } 102 parse(final Header header, final CookieOrigin origin)103 public List<Cookie> parse(final Header header, final CookieOrigin origin) 104 throws MalformedCookieException { 105 if (header == null) { 106 throw new IllegalArgumentException("Header may not be null"); 107 } 108 if (origin == null) { 109 throw new IllegalArgumentException("Cookie origin may not be null"); 110 } 111 String headervalue = header.getValue(); 112 boolean isNetscapeCookie = false; 113 int i1 = headervalue.toLowerCase(Locale.ENGLISH).indexOf("expires="); 114 if (i1 != -1) { 115 i1 += "expires=".length(); 116 int i2 = headervalue.indexOf(';', i1); 117 if (i2 == -1) { 118 i2 = headervalue.length(); 119 } 120 try { 121 DateUtils.parseDate(headervalue.substring(i1, i2), this.datepatterns); 122 isNetscapeCookie = true; 123 } catch (DateParseException e) { 124 // Does not look like a valid expiry date 125 } 126 } 127 HeaderElement[] elems = null; 128 if (isNetscapeCookie) { 129 NetscapeDraftHeaderParser parser = NetscapeDraftHeaderParser.DEFAULT; 130 CharArrayBuffer buffer; 131 ParserCursor cursor; 132 if (header instanceof FormattedHeader) { 133 buffer = ((FormattedHeader) header).getBuffer(); 134 cursor = new ParserCursor( 135 ((FormattedHeader) header).getValuePos(), 136 buffer.length()); 137 } else { 138 String s = header.getValue(); 139 if (s == null) { 140 throw new MalformedCookieException("Header value is null"); 141 } 142 buffer = new CharArrayBuffer(s.length()); 143 buffer.append(s); 144 cursor = new ParserCursor(0, buffer.length()); 145 } 146 elems = new HeaderElement[] { parser.parseHeader(buffer, cursor) }; 147 } else { 148 elems = header.getElements(); 149 } 150 return parse(elems, origin); 151 } 152 formatCookies(final List<Cookie> cookies)153 public List<Header> formatCookies(final List<Cookie> cookies) { 154 if (cookies == null) { 155 throw new IllegalArgumentException("List of cookies may not be null"); 156 } 157 if (cookies.isEmpty()) { 158 throw new IllegalArgumentException("List of cookies may not be empty"); 159 } 160 CharArrayBuffer buffer = new CharArrayBuffer(20 * cookies.size()); 161 buffer.append(SM.COOKIE); 162 buffer.append(": "); 163 for (int i = 0; i < cookies.size(); i++) { 164 Cookie cookie = cookies.get(i); 165 if (i > 0) { 166 buffer.append("; "); 167 } 168 buffer.append(cookie.getName()); 169 buffer.append("="); 170 String s = cookie.getValue(); 171 if (s != null) { 172 buffer.append(s); 173 } 174 } 175 List<Header> headers = new ArrayList<Header>(1); 176 headers.add(new BufferedHeader(buffer)); 177 return headers; 178 } 179 getVersion()180 public int getVersion() { 181 return 0; 182 } 183 getVersionHeader()184 public Header getVersionHeader() { 185 return null; 186 } 187 188 } 189