📄 cookiejar.java
字号:
package com.meterware.httpunit.cookies;/******************************************************************************************************************** * $Id: CookieJar.java,v 1.11 2004/09/29 17:15:26 russgold Exp $ * * Copyright (c) 2002-2004, Russell Gold * * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated * documentation files (the "Software"), to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and * to permit persons to whom the Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all copies or substantial portions * of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO * THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. * *******************************************************************************************************************/import java.io.IOException;import java.io.StreamTokenizer;import java.io.StringReader;import java.net.URL;import java.util.*;/** * A collection of HTTP cookies, which can interact with cookie and set-cookie header values. * * @author <a href="mailto:russgold@httpunit.org">Russell Gold</a> * @author <a href="mailto:drew.varner@oracle.com">Drew Varner</a> **/public class CookieJar { private static final int DEFAULT_HEADER_SIZE = 80; private ArrayList _cookies = new ArrayList(); private ArrayList _globalCookies = new ArrayList(); private CookiePress _press; /** * Creates an empty cookie jar. */ public CookieJar() { _press = new CookiePress( null ); } /** * Creates a cookie jar which is initially populated with cookies parsed from the <code>Set-Cookie</code> and * <code>Set-Cookie2</code> header fields. * <p> * Note that the parsing does not strictly follow the specifications, but * attempts to imitate the behavior of popular browsers. Specifically, * it allows cookie values to contain commas, which the * Netscape standard does not allow for, but which is required by some servers. * </p> */ public CookieJar( CookieSource source ) { _press = new CookiePress( source.getURL() ); findCookies( source.getHeaderFields( "Set-Cookie" ), new RFC2109CookieRecipe() ); findCookies( source.getHeaderFields( "Set-Cookie2" ), new RFC2965CookieRecipe() ); } private void findCookies( String cookieHeader[], CookieRecipe recipe ) { for (int i = 0; i < cookieHeader.length; i++) { recipe.findCookies( cookieHeader[i] ); } } /** * Empties this cookie jar of all contents. */ public void clear() { _cookies.clear(); _globalCookies.clear(); } /** * Defines a cookie to be sent to the server on every request. This bypasses the normal mechanism by which only * certain cookies are sent based on their host and path. * @deprecated as of 1.6, use #putCookie **/ public void addCookie( String name, String value ) { _globalCookies.add( new Cookie( name, value ) ); } /** * Defines a cookie to be sent to the server on every request. This bypasses the normal mechanism by which only * certain cookies are sent based on their host and path. * @since 1.6 **/ public void putCookie( String name, String value ) { for (Iterator iterator = _globalCookies.iterator(); iterator.hasNext();) { Cookie cookie = (Cookie) iterator.next(); if (name.equals( cookie.getName() )) iterator.remove(); } _globalCookies.add( new Cookie( name, value ) ); } /** * Returns the name of all the active cookies in this cookie jar. **/ public String[] getCookieNames() { final int numGlobalCookies = _globalCookies.size(); String[] names = new String[ _cookies.size() + numGlobalCookies ]; for (int i = 0; i < numGlobalCookies; i++) { names[i] = ((Cookie) _globalCookies.get(i)).getName(); } for (int i = numGlobalCookies; i < names.length; i++) { names[i] = ((Cookie) _cookies.get( i-numGlobalCookies )).getName(); } return names; } /** * Returns a collection containing all of the cookies in this jar. */ public Collection getCookies() { final Collection collection = (Collection) _cookies.clone(); collection.addAll( _globalCookies ); return collection; } /** * Returns the value of the specified cookie. **/ public String getCookieValue( String name ) { Cookie cookie = getCookie( name ); return cookie == null ? null : cookie.getValue(); } /** * Returns the value of the specified cookie. **/ public Cookie getCookie( String name ) { if (name == null) throw new IllegalArgumentException( "getCookieValue: no name specified" ); for (Iterator iterator = _cookies.iterator(); iterator.hasNext();) { Cookie cookie = (Cookie) iterator.next(); if (name.equals( cookie.getName() )) return cookie; } for (Iterator iterator = _globalCookies.iterator(); iterator.hasNext();) { Cookie cookie = (Cookie) iterator.next(); if (name.equals( cookie.getName() )) return cookie; } return null; } /** * Returns the value of the cookie header to be sent to the specified URL. * Will return null if no compatible cookie is defined. **/ public String getCookieHeaderField( URL targetURL ) { if (_cookies.isEmpty() && _globalCookies.isEmpty()) return null; StringBuffer sb = new StringBuffer( DEFAULT_HEADER_SIZE ); HashSet restrictedCookies = new HashSet(); for (Iterator i = _cookies.iterator(); i.hasNext();) { Cookie cookie = (Cookie) i.next(); if (!cookie.mayBeSentTo( targetURL )) continue; restrictedCookies.add( cookie.getName() ); if (sb.length() != 0) sb.append( "; " ); sb.append( cookie.getName() ).append( '=' ).append( cookie.getValue() ); } for (Iterator i = _globalCookies.iterator(); i.hasNext();) { Cookie cookie = (Cookie) i.next(); if (restrictedCookies.contains( cookie.getName() )) continue; if (sb.length() != 0) sb.append( "; " ); sb.append( cookie.getName() ).append( '=' ).append( cookie.getValue() ); } return sb.length() == 0 ? null : sb.toString(); } /** * Updates the cookies maintained in this cookie jar with those in another cookie jar. Any duplicate cookies in * the new jar will replace those in this jar. **/ public void updateCookies( CookieJar newJar ) { for (Iterator i = newJar._cookies.iterator(); i.hasNext();) { addUniqueCookie( (Cookie) i.next() ); } } /** * Add the cookie to this jar, replacing any previous matching cookie. */ void addUniqueCookie( Cookie cookie ) { _cookies.remove( cookie ); _cookies.add( cookie ); } abstract class CookieRecipe { /** * Extracts cookies from a cookie header. Works in conjunction with a cookie press class, which actually creates * the cookies and adds them to the jar as appropriate. * * 1. Parse the header into tokens, separated by ',' and ';' (respecting single and double quotes) * 2. Process tokens from the end: * a. if the token contains an '=' we have a name/value pair. Add them to the cookie press, which * will decide if it is a cookie name or an attribute name. * b. if the token is a reserved word, flush the cookie press and continue. * c. otherwise, add the token to the cookie press, passing along the last character of the previous token. */ void findCookies( String cookieHeader ) { Vector tokens = getCookieTokens( cookieHeader ); for (int i = tokens.size() - 1; i >= 0; i--) { String token = (String) tokens.elementAt( i ); int equalsIndex = getEqualsIndex( token ); if (equalsIndex != -1) { _press.addTokenWithEqualsSign( this, token, equalsIndex ); } else if (isCookieReservedWord( token )) { _press.clear(); } else { _press.addToken( token, lastCharOf( (i == 0) ? "" : (String) tokens.elementAt( i - 1 ) ) );
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -