tomcat-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From cos...@locus.apache.org
Subject cvs commit: jakarta-tomcat/src/share/org/apache/tomcat/util/http Cookies.java ServerCookie.java
Date Fri, 01 Dec 2000 08:19:19 GMT
costin      00/12/01 00:19:18

  Modified:    src/share/org/apache/tomcat/modules/session SessionId.java
               src/share/org/apache/tomcat/request AccessInterceptor.java
               src/share/org/apache/tomcat/util/http Cookies.java
                        ServerCookie.java
  Log:
  - Finish the new parser for Cookies - supports Version=1, faster, better
  ( I hope ). It needs few more tests and cleanup, but it should be ok.
  I'll start removing the old code, and need to make sure all cookies-related
  fixes from 3.2 are merged.
  
  - SessionId - send only one cookie ( that is supported by all browsers ),
  don't send the cookie ( Set-Cookie:) if we are in the same session already
  ( save bandwith, browser warnings if the user have verbose cookies )
  
  - fixed small bug in AccessInterceptor ( the substring mini-optimization)
  
  Revision  Changes    Path
  1.5       +19 -11    jakarta-tomcat/src/share/org/apache/tomcat/modules/session/SessionId.java
  
  Index: SessionId.java
  ===================================================================
  RCS file: /home/cvs/jakarta-tomcat/src/share/org/apache/tomcat/modules/session/SessionId.java,v
  retrieving revision 1.4
  retrieving revision 1.5
  diff -u -r1.4 -r1.5
  --- SessionId.java	2000/12/01 06:00:38	1.4
  +++ SessionId.java	2000/12/01 08:19:14	1.5
  @@ -223,7 +223,13 @@
   	    return 0;
           if (noCookies)
               return 0;
  -
  +	if( reqSessionId.equals( rrequest.getRequestedSessionId() )) {
  +	    // we are already in a session - no need to
  +	    // send the Set-Cookie again ( plus it's annoying if
  +	    // the user doesn't want sessions but rewriting )
  +	    //	    log( "We are in a session already ");
  +	    return 0;
  +	}
   	
           // GS, set the path attribute to the cookie. This way
           // multiple session cookies can be used, one for each
  @@ -242,19 +248,21 @@
   //  //     }
   
   	// we know reqSessionId doesn't need quoting ( we generate it )
  -	StringBuffer buf = new StringBuffer();
  -	buf.append( "JSESSIONID=" ).append( reqSessionId );
  -	buf.append( ";Version=1" );
  -	buf.append( ";Path=" );
  -	ServerCookie.maybeQuote( 1 , buf, sessionPath ); // XXX ugly 
  -	buf.append( ";Discard" );
  -	// discard results from:    	cookie.setMaxAge(-1);
  +// 	StringBuffer buf = new StringBuffer();
  +// 	buf.append( "JSESSIONID=" ).append( reqSessionId );
  +// 	buf.append( ";Version=1" );
  +// 	buf.append( ";Path=" );
  +// 	ServerCookie.maybeQuote( 1 , buf, sessionPath ); // XXX ugly 
  +// 	buf.append( ";Discard" );
  +// 	// discard results from:    	cookie.setMaxAge(-1);
   	
   	
  -	response.addHeader( "Set-Cookie2",
  -			    buf.toString() ); // XXX XXX garbage generator
  +// 	response.addHeader( "Set-Cookie2",
  +// 			    buf.toString() ); // XXX XXX garbage generator
   
  -	buf = new StringBuffer();
  +	// We'll use a Netscape cookie for sessions - it's
  +	// the only one supported by all browsers
  +	StringBuffer buf = new StringBuffer();
   	buf.append( "JSESSIONID=" ).append( reqSessionId );
   	buf.append( ";Path=" ).append(  sessionPath  );
   	response.addHeader( "Set-Cookie",
  
  
  
  1.24      +2 -0      jakarta-tomcat/src/share/org/apache/tomcat/request/AccessInterceptor.java
  
  Index: AccessInterceptor.java
  ===================================================================
  RCS file: /home/cvs/jakarta-tomcat/src/share/org/apache/tomcat/request/AccessInterceptor.java,v
  retrieving revision 1.23
  retrieving revision 1.24
  diff -u -r1.23 -r1.24
  --- AccessInterceptor.java	2000/11/30 04:58:48	1.23
  +++ AccessInterceptor.java	2000/12/01 08:19:16	1.24
  @@ -304,6 +304,8 @@
   	    // changed to eliminate the allocation ( will be changed again
   	    // when MessageBytes will be used in intercepotrs, now they are
   	    // in core
  +	    if( path.length() < ctPathL - 2  )
  +		return false;
   	    for( int i=0; i< ctPathL - 2 ; i++ ) {
   		if( path.charAt( i ) != ctPath.charAt( i ))
   		    return false;
  
  
  
  1.4       +147 -51   jakarta-tomcat/src/share/org/apache/tomcat/util/http/Cookies.java
  
  Index: Cookies.java
  ===================================================================
  RCS file: /home/cvs/jakarta-tomcat/src/share/org/apache/tomcat/util/http/Cookies.java,v
  retrieving revision 1.3
  retrieving revision 1.4
  diff -u -r1.3 -r1.4
  --- Cookies.java	2000/12/01 06:00:38	1.3
  +++ Cookies.java	2000/12/01 08:19:17	1.4
  @@ -79,7 +79,8 @@
       // expected average number of cookies per request
       public static final int INITIAL_SIZE=4; 
       ServerCookie scookies[]=new ServerCookie[INITIAL_SIZE];
  -    int cookieCount=-1; // -1 = cookies not processed yet
  +    int cookieCount=0;
  +    boolean unprocessed=true;
   
       MimeHeaders headers;
       
  @@ -97,20 +98,20 @@
   	    if( scookies[i]!=null )
   		scookies[i].recycle();
   	}
  -	cookieCount=-1;
  +	cookieCount=0;
  +	unprocessed=true;
       }
   
       public ServerCookie getCookie( int idx ) {
  -	if( cookieCount == -1 ) {
  +	if( unprocessed ) {
   	    getCookieCount(); // will also update the cookies
   	}
   	return scookies[idx];
       }
   
       public int getCookieCount() {
  -	if( cookieCount == -1 ) {
  -	    cookieCount=0;
  -	    // compute cookies
  +	if( unprocessed ) {
  +	    unprocessed=false;
   	    processCookies(headers);
   	}
   	return cookieCount;
  @@ -139,6 +140,8 @@
        *  in a cookie vector
        */
       public  void processCookies( MimeHeaders headers ) {
  +	if( headers==null )
  +	    return;// nothing to process
   	// process each "cookie" header
   	int pos=0;
   	while( pos>=0 ) {
  @@ -151,82 +154,126 @@
   	    if( cookieValue==null || cookieValue.isNull() ) continue;
   
   	    // Uncomment to test the new parsing code
  -	    // 	    if( cookieValue.getType() == MessageBytes.T_BYTES ) {
  -	    // 		processCookieHeader( cookieValue.getBytes(),
  -	    // 				     cookieValue.getOffset(),
  -	    // 				     cookieValue.getLength());
  -	    // 	    } else {
  -	    processCookieHeader( cookieValue.toString() );
  -	    // 	    }
  +	    if( cookieValue.getType() == MessageBytes.T_BYTES ) {
  +		if( dbg>-1 ) log( "Parsing b[]: " + cookieValue.toString());
  +		processCookieHeader( cookieValue.getBytes(),
  +				     cookieValue.getOffset(),
  +				     cookieValue.getLength());
  +	    } else {
  +		if( dbg>-1 ) log( "Parsing S: " + cookieValue.toString());
  +		processCookieHeader( cookieValue.toString() );
  +	    }
   	    pos++;// search from the next position
   	}
       }
   
  -    private  void processCookieHeader(  byte bytes[], int off, int len )
  +    void processCookieHeader(  byte bytes[], int off, int len )
       {
   	if( len<=0 || bytes==null ) return;
   	int end=off+len;
   	int pos=off;
  -
  -	while( true ) {
  +	
  +	int version=0; //sticky
  +	ServerCookie sc=null;
  +	
  +	while( pos<end ) {
  +	    byte cc;
   	    // [ skip_spaces name skip_spaces "=" skip_spaces value EXTRA ; ] *
  +	    if( dbg>0 ) log( "Start: " + pos + " " + end );
   	    
  -	    int startName=skipSpaces(bytes, pos, end);
  +	    pos=skipSpaces(bytes, pos, end);
   	    if( pos>=end )
   		return; // only spaces
  -
  +	    int startName=pos;
  +	    if( dbg>0 ) log( "SN: " + pos );
  +	    
   	    // Version should be the first token
   	    boolean isSpecial=false;
   	    if(bytes[pos]=='$') { pos++; isSpecial=true; }
   
  -	    int endName= findDelim1( bytes, startName, end); // " =;,"
  -	    if(endName >= end ) {
  +	    pos= findDelim1( bytes, startName, end); // " =;,"
  +	    int endName=pos;
  +	    // current = "=" or " " or DELIM
  +	    pos= skipSpaces( bytes, endName, end ); 
  +	    if( dbg>0 ) log( "DELIM: " + endName + " " + (char)bytes[pos]);
  +
  +	    if(pos >= end ) {
   		// it's a name-only cookie ( valid in RFC2109 )
  -		// XXX todo
  -		return; 
  +		if( ! isSpecial ) {
  +		    sc=addCookie();
  +		    sc.getName().setBytes( bytes, startName,
  +					   endName-startName );
  +		    sc.getValue().setString("");
  +		    sc.setVersion( version );
  +		    if( dbg>0 ) log( "Name only, end: " + startName + " " +
  +				     endName);
  +		}
  +		return;
   	    }
  -	    // XXX it's a , or a ; ?
  -	    
  -	    // current = "=" or " " 
  -	    pos= skipSpaces( bytes, endName, end );
  -	    if(endName >= end )
  -		return; // invalid
  -
  -	    // cookie without value
  -	    if( bytes[pos] == ';' || bytes[pos]==',' ) {
  -		// add cookie
   
  -		// we may have more cookies
  +	    cc=bytes[pos];
  +	    pos++;
  +	    if( cc==';' || cc==',' ) {
  +		if( ! isSpecial && startName!= endName ) {
  +		    sc=addCookie();
  +		    sc.getName().setBytes( bytes, startName,
  +					   endName-startName );
  +		    sc.getValue().setString("");
  +		    sc.setVersion( version );
  +		    if( dbg>0 ) log( "Name only: " + startName + " " + endName);
  +		}
   		continue;
  -	    }
  -
  -	    if( bytes[pos] != '=' ) {
  -		// syntax error - ignore the rest
  -		// ( we could also skip to the next ';' )
  -		return;
   	    }
  -	
  -	    // we must have "="
  -	    pos++;
  +	    
  +	    // we should have "=" ( tested all other alternatives )
   	    int startValue=skipSpaces( bytes, pos, end);
   	    int endValue=startValue;
  -	    // XXX quote is valid only in version=1 cookies
  -	    if( bytes[pos]== '\'' || bytes[pos]=='"' ) {
  +	    
  +	    // quote is valid only in version=1 cookies
  +	    cc=bytes[pos];
  +	    if( version==1 && ( cc== '\'' || cc=='"' ) ) {
   		startValue++;
  -		endValue=indexOf( bytes, startValue, end, bytes[startValue] );
  +		endValue=indexOf( bytes, startValue, end, cc );
  +		pos=endValue+1; // to skip to next cookie
    	    } else {
   		endValue=findDelim2( bytes, startValue, end );
  +		pos=endValue+1;
   	    }
  -
  -	    // process $Version, etc
  +	    
  +	    // if not $Version, etc
   	    if( ! isSpecial ) {
  -		ServerCookie sc=addCookie();
  -		sc.getName().setBytes( bytes, startName, endName );
  -		sc.getValue().setBytes( bytes, startValue, endValue );
  +		sc=addCookie();
  +		sc.getName().setBytes( bytes, startName, endName-startName );
  +		sc.getValue().setBytes( bytes, startValue, endValue-startValue);
  +		sc.setVersion( version );
  +		if( dbg>0 ) log( "New: " + sc.getName() + "X=X" + sc.getValue());
   		continue;
   	    }
  +	    
   	    // special - Path, Version, Domain, Port
  +	    if( dbg>0 ) log( "Special: " + startName + " " + endName);
   	    // XXX TODO
  +	    if( equals( "$Version", bytes, startName, endName ) ) {
  +		if(dbg>0 ) log( "Found version " );
  +		if( bytes[startValue]=='1' && endValue==startValue+1 ) {
  +		    version=1;
  +		    if(dbg>0 ) log( "Found version=1" );
  +		}
  +		continue;
  +	    }
  +	    if( sc==null ) {
  +		// Path, etc without a previous cookie
  +		continue;
  +	    }
  +	    if( equals( "$Path", bytes, startName, endName ) ) {
  +		sc.getPath().setBytes( bytes, startName, endName-startName );
  +	    }
  +	    if( equals( "$Domain", bytes, startName, endName ) ) {
  +		sc.getDomain().setBytes( bytes, startName, endName-startName );
  +	    }
  +	    if( equals( "$Port", bytes, startName, endName ) ) {
  +		// sc.getPort().setBytes( bytes, startName, endName-startName );
  +	    }
   	}
       }
   
  @@ -284,6 +331,21 @@
   	return off;
       }
       
  +    // XXX will be refactored soon!
  +    public static boolean equals( String s, byte b[], int start, int end) {
  +	int blen = end-start;
  +	if (b == null || blen != s.length()) {
  +	    return false;
  +	}
  +	int boff = start;
  +	for (int i = 0; i < blen; i++) {
  +	    if (b[boff++] != s.charAt(i)) {
  +		return false;
  +	    }
  +	}
  +	return true;
  +    }
  +    
   
       // ---------------------------------------------------------
       // -------------------- DEPRECATED, OLD --------------------
  @@ -347,9 +409,43 @@
   
   
       // log
  -    static final int dbg=1;
  +    static final int dbg=0;
       public void log(String s ) {
   	System.out.println("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;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 ) {
  +	System.out.println("Processing " + s );
  +	Cookies cs=new Cookies(null);
  +	cs.processCookieHeader( s.getBytes(), 0, s.length());
  +	for( int i=0; i< cs.getCookieCount() ; i++ ) {
  +	    System.out.println("Cookie: " + cs.getCookie( i ));
  +	}
  +	    
  +    }
   }
  
  
  
  1.4       +5 -0      jakarta-tomcat/src/share/org/apache/tomcat/util/http/ServerCookie.java
  
  Index: ServerCookie.java
  ===================================================================
  RCS file: /home/cvs/jakarta-tomcat/src/share/org/apache/tomcat/util/http/ServerCookie.java,v
  retrieving revision 1.3
  retrieving revision 1.4
  diff -u -r1.3 -r1.4
  --- ServerCookie.java	2000/12/01 06:00:39	1.3
  +++ ServerCookie.java	2000/12/01 08:19:17	1.4
  @@ -150,6 +150,11 @@
   
   
       // -------------------- utils --------------------
  +
  +    public String toString() {
  +	return "Cookie " + getName() + "=" + getValue() + " ; "
  +	    + getVersion() + " " + getPath() + " " + getDomain();
  +    }
       
       // Note -- disabled for now to allow full Netscape compatibility
       // from RFC 2068, token special case characters
  
  
  

Mime
View raw message