Start line:  
End line:  

Snippet Preview

Snippet HTML Code

Stack Overflow Questions
  /*
   * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
   *
   * Copyright (c) 1997-2010 Oracle and/or its affiliates. All rights reserved.
   *
   * The contents of this file are subject to the terms of either the GNU
   * General Public License Version 2 only ("GPL") or the Common Development
   * and Distribution License("CDDL") (collectively, the "License").  You
   * may not use this file except in compliance with the License.  You can
  * obtain a copy of the License at
  * https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
  * or packager/legal/LICENSE.txt.  See the License for the specific
  * language governing permissions and limitations under the License.
  *
  * When distributing the software, include this License Header Notice in each
  * file and include the License file at packager/legal/LICENSE.txt.
  *
  * GPL Classpath Exception:
  * Oracle designates this particular file as subject to the "Classpath"
  * exception as provided by Oracle in the GPL Version 2 section of the License
  * file that accompanied this code.
  *
  * Modifications:
  * If applicable, add the following below the License Header, with the fields
  * enclosed by brackets [] replaced by your own identifying information:
  * "Portions Copyright [year] [name of copyright owner]"
  *
  * Contributor(s):
  * If you wish your version of this file to be governed by only the CDDL or
  * only the GPL Version 2, indicate your decision by adding "[Contributor]
  * elects to include this software in this distribution under the [CDDL or GPL
  * Version 2] license."  If you don't indicate a single choice of license, a
  * recipient has the option to distribute your version of this file under
  * either the CDDL, the GPL Version 2 or to extend the choice of license to
  * its licensees as provided above.  However, if you add GPL Version 2 code
  * and therefore, elected the GPL Version 2 license, then the option applies
  * only if the new code is made subject to such option by the copyright
  * holder.
  *
  *
  * This file incorporates work covered by the following copyright and
  * permission notice:
  *
  * Copyright 2004 The Apache Software Foundation
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
  * You may obtain a copy of the License at
  *
  *     http://www.apache.org/licenses/LICENSE-2.0
  *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
 
 package org.apache.tomcat.util.http;
 
 
A collection of cookies - reusable and tuned for server side performance. Based on RFC2965 ( and 2109 ) This class is not synchronized.

Author(s):
Costin Manolache
kevin seguin
 
 public final class Cookies { // extends MultiMap {
   
     private static com.sun.org.apache.commons.logging.Log log=
         com.sun.org.apache.commons.logging.LogFactory.getLog(Cookies.class );
 
     // expected average number of cookies per request
     public static final int INITIAL_SIZE=4; 
     int cookieCount=0;
     boolean unprocessed=true;
 
     MimeHeaders headers;
    
    
Construct a new cookie collection, that will extract the information from headers.

Parameters:
headers Cookies are lazy-evaluated and will extract the information from the provided headers.
 
     public Cookies(MimeHeaders headers) {
         this.=headers;
     }

    
Construct a new uninitialized cookie collection. Use setHeaders(org.apache.tomcat.util.http.MimeHeaders) to initialize.
    // [seguin] added so that an empty Cookies object could be
    // created, have headers set, then recycled.
    public Cookies() {
    }

    
Set the headers from which cookies will be pulled. This has the side effect of recycling the object.

Parameters:
headers Cookies are lazy-evaluated and will extract the information from the provided headers.
    // [seguin] added so that an empty Cookies object could be
    // created, have headers set, then recycled.
    public void setHeaders(MimeHeaders headers) {
        recycle();
        this.=headers;
    }

    
Recycle.
    public void recycle() {
            forint i=0; ii++ ) {
            if[i]!=null )
                [i].recycle();
        }
        =0;
        =true;
    }

    
EXPENSIVE!!! only for debugging.
    public String toString() {
        StringWriter sw = new StringWriter();
        PrintWriter pw = new PrintWriter(sw);
        pw.println("=== Cookies ===");
        int count = getCookieCount();
        for (int i = 0; i < count; ++i) {
            pw.println(getCookie(i).toString());
        }
        return sw.toString();
    }
    // -------------------- Indexed access --------------------
    
    public ServerCookie getCookieint idx ) {
        if ) {
            getCookieCount(); // will also update the cookies
        }
        return [idx];
    }
    public int getCookieCount() {
        if ) {
            processCookies();
        }
        return ;
    }
    // -------------------- Adding cookies --------------------

    
Register a new, unitialized cookie. Cookies are recycled, and most of the time an existing ServerCookie object is returned. The caller can set the name/value and attributes for the cookie
    public ServerCookie addCookie() {
        if >= .  ) {
            ServerCookie scookiesTmp[]=new ServerCookie[2*];
            System.arraycopy, 0, scookiesTmp, 0, );
            =scookiesTmp;
        }
        
        ServerCookie c = [];
        ifc==null ) {
            cnew ServerCookie();
            []=c;
        }
        ++;
        return c;
    }
    // code from CookieTools 

    
Add all Cookie found in the headers of a request.
    public  void processCookiesMimeHeaders headers ) {
        =false;
        ifheaders==null )
            return;// nothing to process
        // process each "cookie" header
        int pos=0;
        whilepos>=0 ) {
            // Cookie2: version ? not needed
            pos=headers.findHeader"Cookie"pos );
            // no more cookie headers headers
            ifpos<0 ) break;
            MessageBytes cookieValue=headers.getValuepos );
            ifcookieValue==null || cookieValue.isNull() ) {
                pos++;
                continue;
            }
            // Uncomment to test the new parsing code
            ifcookieValue.getType() == . ) {
                if>0 ) log"Parsing b[]: " + cookieValue.toString());
                ByteChunk bc=cookieValue.getByteChunk();
                processCookieHeaderbc.getBytes(),
                                     bc.getOffset(),
                                     bc.getLength());
            } else {
                if>0 ) log"Parsing S: " + cookieValue.toString());
                processCookieHeadercookieValue.toString() );
            }
            pos++;// search from the next position
        }
    }

    
Process a byte[] header - allowing fast processing of the raw data
    public void processCookieHeader(  byte bytes[], int offint len )
    {
        =false;
        iflen<=0 || bytes==null ) return;
        int end=off+len;
        int pos=off;
        
        int version=0; //sticky
        ServerCookie sc=null;
        
        whilepos<end ) {
            byte cc;
            // [ skip_spaces name skip_spaces "=" skip_spaces value EXTRA ; ] *
            if>0 ) log"Start: " + pos + " " + end );
            
            pos=skipSpaces(bytesposend);
            ifpos>=end )
                return// only spaces
            int startName=pos;
            if>0 ) log"SN: " + pos );
            
            // Version should be the first token
            boolean isSpecial=false;
            if(bytes[pos]=='$') { pos++; isSpecial=true; }
            posfindDelim1bytesstartNameend); // " =;,"
            int endName=pos;
            // current = "=" or " " or DELIM
            posskipSpacesbytesendNameend ); 
            if>0 ) log"DELIM: " + endName + " " + (char)bytes[pos]);
            if(pos >= end ) {
                // it's a name-only cookie ( valid in RFC2109 )
                if( ! isSpecial ) {
                    sc=addCookie();
                    sc.getName().setBytesbytesstartName,
                                           endName-startName );
                    sc.getValue().setString("");
                    sc.setVersionversion );
                    if>0 ) log"Name only, end: " + startName + " " +
                                     endName);
                }
                return;
            }
            cc=bytes[pos];
            pos++;
            ifcc==';' || cc==',' || pos>=end ) {
                if( ! isSpecial && startName!= endName ) {
                    sc=addCookie();
                    sc.getName().setBytesbytesstartName,
                                           endName-startName );
                    sc.getValue().setString("");
                    sc.setVersionversion );
                    if>0 ) log"Name only: " + startName + " " + endName);
                }
                continue;
            }
            
            // we should have "=" ( tested all other alternatives )
            int startValue=skipSpacesbytesposend);
            int endValue=startValue;
            
            cc=bytes[pos];
            if(  cc== '\'' || cc=='"' ) {
                startValue++;
                endValue=indexOfbytesstartValueendcc );
                pos=endValue+1; // to skip to next cookie
             } else {
                endValue=findDelim2bytesstartValueend );
                pos=endValue+1;
            }
            
            // if not $Version, etc
            if( ! isSpecial ) {
                sc=addCookie();
                sc.getName().setBytesbytesstartNameendName-startName );
                sc.getValue().setBytesbytesstartValueendValue-startValue);
                sc.setVersionversion );
                if>0 ) {
                    log"New: " + sc.getName() + "X=X" + sc.getValue());
                }
                continue;
            }
            
            // special - Path, Version, Domain, Port
            if>0 ) log"Special: " + startName + " " + endName);
            // XXX TODO
            ifequals"$Version"bytesstartNameendName ) ) {
                if(>0 ) log"Found version " );
                ifbytes[startValue]=='1' && endValue==startValue+1 ) {
                    version=1;
                    if(>0 ) log"Found version=1" );
                }
                continue;
            }
            ifsc==null ) {
                // Path, etc without a previous cookie
                continue;
            }
            ifequals"$Path"bytesstartNameendName ) ) {
                sc.getPath().setBytesbytes,
                                       startValue,
                                       endValue-startValue );
            }
            ifequals"$Domain"bytesstartNameendName ) ) {
                sc.getDomain().setBytesbytes,
                                         startValue,
                                         endValue-startValue );
            }
            ifequals"$Port"bytesstartNameendName ) ) {
                // sc.getPort().setBytes( bytes,
                //                        startValue,
                //                        endValue-startValue );
            }
        }
    }
    // -------------------- Utils --------------------
    public static int skipSpaces(  byte bytes[], int offint end ) {
        whileoff < end ) {
            byte b=bytes[off];
            ifb!= ' ' ) return off;
            off ++;
        }
        return off;
    }
    public static int findDelim1byte bytes[], int offint end )
    {
        whileoff < end ) {
            byte b=bytes[off];
            ifb==' ' || b=='=' || b==';' || b==',' )
                return off;
            off++;
        }
        return off;
    }
    public static int findDelim2byte bytes[], int offint end )
    {
        whileoff < end ) {
            byte b=bytes[off];
            ifb==';' || b==',' )
                return off;
            off++;
        }
        return off;
    }
    public static int indexOfbyte bytes[], int offint endbyte qq )
    {
        whileoff < end ) {
            byte b=bytes[off];
            ifb==qq )
                return off;
            off++;
        }
        return off;
    }
    public static int indexOfbyte bytes[], int offint endchar qq )
    {
        whileoff < end ) {
            byte b=bytes[off];
            ifb==qq )
                return off;
            off++;
        }
        return off;
    }
    
    // XXX will be refactored soon!
    public static boolean equalsString sbyte b[], int startint end) {
        int blen = end-start;
        if (b == null || blen != s.length()) {
            return false;
        }
        int boff = start;
        for (int i = 0; i < bleni++) {
            if (b[boff++] != s.charAt(i)) {
                return false;
            }
        }
        return true;
    }
    
    // ---------------------------------------------------------
    // -------------------- DEPRECATED, OLD --------------------
    
    private void processCookieHeader(  String cookieString )
    {
        if>0 ) log"Parsing cookie header " + cookieString );
        // normal cookie, with a string value.
        // This is the original code, un-optimized - it shouldn't
        // happen in normal case
        StringTokenizer tok = new StringTokenizer(cookieString,
                                                  ";"false);
        while (tok.hasMoreTokens()) {
            String token = tok.nextToken();
            int i = token.indexOf("=");
            if (i > -1) {
                
                // XXX
                // the trims here are a *hack* -- this should
                // be more properly fixed to be spec compliant
                
                String name = token.substring(0, i).trim();
                String value = token.substring(i+1, token.length()).trim();
                // RFC 2109 and bug 
                value=stripQuotevalue );
                ServerCookie cookie = addCookie();
                
                cookie.getName().setString(name);
                cookie.getValue().setString(value);
                if > 0 ) log"Add cookie " + name + "=" + value);
            } else {
                // we have a bad cookie.... just let it go
            }
        }
    }

    
Strips quotes from the start and end of the cookie string This conforms to RFC 2109

Parameters:
value a String specifying the cookie value (possibly quoted).
See also:
setValue
    private static String stripQuoteString value )
    {
        //        log("Strip quote from " + value );
        if (((value.startsWith("\"")) && (value.endsWith("\""))) ||
            ((value.startsWith("'") && (value.endsWith("'"))))) {
            try {
                return value.substring(1,value.length()-1);
            } catch (Exception ex) { 
            }
        }
        return value;
    }  
    // log
    static final int dbg=0;
    public void log(String s ) {
        if (.isDebugEnabled())
            .debug("Cookies: " + s);
    }
    /*
    public static void main( String args[] ) {
        test("foo=bar; a=b");
        test("foo=bar;a=b");
        test("foo=bar;a=b;");
        test("foo=bar;a=b; ");
        test("foo=bar;a=b; ;");
        test("foo=;a=b; ;");
        test("foo;a=b; ;");
        // v1 
        test("$Version=1; foo=bar;a=b"); 
        test("$Version=\"1\"; foo='bar'; $Path=/path; $Domain=\"localhost\"");
        test("$Version=1;foo=bar;a=b; ; ");
        test("$Version=1;foo=;a=b; ; ");
        test("$Version=1;foo= ;a=b; ; ");
        test("$Version=1;foo;a=b; ; ");
        test("$Version=1;foo=\"bar\";a=b; ; ");
        test("$Version=1;foo=\"bar\";$Path=/examples;a=b; ; ");
        test("$Version=1;foo=\"bar\";$Domain=apache.org;a=b");
        test("$Version=1;foo=\"bar\";$Domain=apache.org;a=b;$Domain=yahoo.com");
        // rfc2965
        test("$Version=1;foo=\"bar\";$Domain=apache.org;$Port=8080;a=b");
        // wrong
        test("$Version=1;foo=\"bar\";$Domain=apache.org;$Port=8080;a=b");
    }
    public static void test( String s ) {
        log("Processing " + s );
        Cookies cs=new Cookies(null);
        cs.processCookieHeader( s.getBytes(), 0, s.length());
        for( int i=0; i< cs.getCookieCount() ; i++ ) {
            log("Cookie: " + cs.getCookie( i ));
        }
            
    }
    */
New to GrepCode? Check out our FAQ X