Author: jfclere
Date: Wed Sep 26 01:52:21 2007
New Revision: 579521
URL: http://svn.apache.org/viewvc?rev=579521&view=rev
Log:
Add the test part move remy's patch to people.apache.org and cast my vote.
Modified:
tomcat/tc6.0.x/trunk/STATUS
Modified: tomcat/tc6.0.x/trunk/STATUS
URL:
http://svn.apache.org/viewvc/tomcat/tc6.0.x/trunk/STATUS?rev=579521&r1=579520&r2=579521&view=diff
==============================================================================
--- tomcat/tc6.0.x/trunk/STATUS (original)
+++ tomcat/tc6.0.x/trunk/STATUS Wed Sep 26 01:52:21 2007
@@ -26,551 +26,7 @@
[ New proposals should be added at the end of the list ]
* New cookie parser (third party contribution)
- +1:
- -1: jfclere: The tests must done another way.
-
-Index: java/org/apache/tomcat/util/http/Cookies.java
-===================================================================
---- java/org/apache/tomcat/util/http/Cookies.java (revision 579106)
-+++ java/org/apache/tomcat/util/http/Cookies.java (working copy)
-@@ -45,7 +45,28 @@
- boolean unprocessed=true;
-
- MimeHeaders headers;
--
-+
-+ /*
-+ List of Separator Characters (see isSeparator())
-+ Excluding the '/' char violates the RFC, but
-+ it looks like a lot of people put '/'
-+ in unquoted values: '/': ; //47
-+ '\t':9 ' ':32 '\"':34 '\'':39 '(':40 ')':41 ',':44 ':':58 ';':59 '<':60
-+ '=':61 '>':62 '?':63 '@':64 '[':91 '\\':92 ']':93 '{':123 '}':125
-+ */
-+ public static final char SEPARATORS[] = { '\t', ' ', '\"', '\'', '(',
')', ',',
-+ ':', ';', '<', '=', '>', '?', '@', '[', '\\', ']', '{', '}' };
-+
-+ protected static final boolean separators[] = new boolean[128];
-+ static {
-+ for (int i = 0; i < 128; i++) {
-+ separators[i] = false;
-+ }
-+ for (int i = 0; i < SEPARATORS.length; i++) {
-+ separators[SEPARATORS[i]] = true;
-+ }
-+ }
-+
- /**
- * Construct a new cookie collection, that will extract
- * the information from headers.
-@@ -182,181 +203,6 @@
- }
- }
-
-- /** Process a byte[] header - allowing fast processing of the
-- * raw data
-- */
-- void processCookieHeader( byte bytes[], int off, int len )
-- {
-- if( len<=0 || bytes==null ) return;
-- int end=off+len;
-- int pos=off;
--
-- 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 );
--
-- 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; }
--
-- 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 )
-- 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;
-- }
--
-- cc=bytes[pos];
-- pos++;
-- if( cc==';' || cc==',' || pos>=end ) {
-- 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;
-- }
--
-- // we should have "=" ( tested all other alternatives )
-- int startValue=skipSpaces( bytes, pos, end);
-- int endValue=startValue;
--
-- cc=bytes[pos];
-- if( cc=='"' ) {
-- endValue=findDelim3( bytes, startValue+1, end, cc );
-- if (endValue == -1) {
-- endValue=findDelim2( bytes, startValue+1, end );
-- } else startValue++;
-- pos=endValue+1; // to skip to next cookie
-- } else {
-- endValue=findDelim2( bytes, startValue, end );
-- pos=endValue+1;
-- }
--
-- // if not $Version, etc
-- if( ! isSpecial ) {
-- 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,
-- startValue,
-- endValue-startValue );
-- }
-- if( equals( "$Domain", bytes, startName, endName ) ) {
-- sc.getDomain().setBytes( bytes,
-- startValue,
-- endValue-startValue );
-- }
-- if( equals( "$Port", bytes, startName, endName ) ) {
-- // sc.getPort().setBytes( bytes,
-- // startValue,
-- // endValue-startValue );
-- }
-- }
-- }
--
-- // -------------------- Utils --------------------
-- public static int skipSpaces( byte bytes[], int off, int end ) {
-- while( off < end ) {
-- byte b=bytes[off];
-- if( b!= ' ' ) return off;
-- off ++;
-- }
-- return off;
-- }
--
-- public static int findDelim1( byte bytes[], int off, int end )
-- {
-- while( off < end ) {
-- byte b=bytes[off];
-- if( b==' ' || b=='=' || b==';' || b==',' )
-- return off;
-- off++;
-- }
-- return off;
-- }
--
-- public static int findDelim2( byte bytes[], int off, int end )
-- {
-- while( off < end ) {
-- byte b=bytes[off];
-- if( b==';' || b==',' )
-- return off;
-- off++;
-- }
-- return off;
-- }
--
-- /*
-- * search for cc but skip \cc as required by rfc2616
-- * (according to rfc2616 cc should be ")
-- */
-- public static int findDelim3( byte bytes[], int off, int end, byte cc )
-- {
-- while( off < end ) {
-- byte b=bytes[off];
-- if ( b== '\\' ) {
-- off++;
-- off++;
-- continue;
-- }
-- if( b==cc )
-- return off;
-- off++;
-- }
-- return -1;
-- }
--
- // XXX will be refactored soon!
- public static boolean equals( String s, byte b[], int start, int end) {
- int blen = end-start;
-@@ -440,42 +286,294 @@
- log.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");
-+
-+ /**
-+ * Returns true if the byte is a separator character as
-+ * defined in RFC2619. Since this is called often, this
-+ * function should be organized with the most probable
-+ * outcomes first.
-+ * JVK
-+ */
-+ public static final boolean isSeparator(final byte c) {
-+ if (c > 0 && c < 126)
-+ return separators[c];
-+ else
-+ return false;
-+ }
-+
-+ /**
-+ * Returns true if the byte is a whitespace character as
-+ * defined in RFC2619
-+ * JVK
-+ */
-+ public static final boolean isWhiteSpace(final byte c) {
-+ // This switch statement is slightly slower
-+ // for my vm than the if statement.
-+ // Java(TM) 2 Runtime Environment, Standard Edition (build
1.5.0_07-164)
-+ /*
-+ switch (c) {
-+ case ' ':;
-+ case '\t':;
-+ case '\n':;
-+ case '\r':;
-+ case '\f':;
-+ return true;
-+ default:;
-+ return false;
-+ }
-+ */
-+ if (c == ' ' || c == '\t' || c == '\n' || c == '\r' || c == '\f')
-+ return true;
-+ else
-+ return false;
-+ }
-+
-+ /**
-+ * Parses a cookie header after the initial "Cookie:"
-+ * [WS][$]token[WS]=[WS](token|QV)[;|,]
-+ * RFC 2965
-+ * JVK
-+ */
-+ public final void processCookieHeader(byte bytes[], int off, int len){
-+ if( len<=0 || bytes==null ) return;
-+ int end=off+len;
-+ int pos=off;
-+ int nameStart=0;
-+ int nameEnd=0;
-+ int valueStart=0;
-+ int valueEnd=0;
-+ int version = 0;
-+ ServerCookie sc=null;
-+ boolean isSpecial;
-+
-+ while (pos < end) {
-+ isSpecial = false;
-+
-+ // Skip whitespace and non-token characters (separators)
-+ while (pos < end &&
-+ (isSeparator(bytes[pos]) || isWhiteSpace(bytes[pos])))
-+ {pos++; }
-+
-+ if (pos >= end)
-+ return;
-+
-+ // Detect Special cookies
-+ if (bytes[pos] == '$') {
-+ isSpecial = true;
-+ pos++;
-+ }
-+
-+ // Get the cookie name. This must be a token
-+ valueEnd = valueStart = nameStart = pos;
-+ pos = nameEnd = getTokenEndPosition(bytes,pos,end);
-+
-+ // Skip whitespace
-+ while (pos < end && isWhiteSpace(bytes[pos])) {pos++; };
-+
-+
-+ // Check for an '=' -- This could also be a name-only
-+ // cookie at the end of the cookie header, so if we
-+ // are past the end of the header, but we have a name
-+ // skip to the name-only part.
-+ if (pos < end && bytes[pos] == '=') {
-+
-+ // Skip whitespace
-+ do {
-+ pos++;
-+ } while (pos < end && isWhiteSpace(bytes[pos]));
-+
-+ if (pos >= end)
-+ return;
-+
-+ // Determine what type of value this is, quoted value,
-+ // token, name-only with an '=', or other (bad)
-+ switch (bytes[pos]) {
-+ case '"':; // Quoted Value
-+ valueStart=pos + 1; // strip "
-+ // getQuotedValue returns the position before
-+ // at the last qoute. This must be dealt with
-+ // when the bytes are copied into the cookie
-+ valueEnd=getQuotedValueEndPosition(bytes,
-+ valueStart, end);
-+ // We need pos to advance
-+ pos = valueEnd;
-+ // Handles cases where the quoted value is
-+ // unterminated and at the end of the header,
-+ // e.g. [myname="value]
-+ if (pos >= end)
-+ return;
-+ break;
-+ case ';':
-+ case ',':
-+ // Name-only cookie with an '=' after the name token
-+ // This may not be RFC compliant
-+ valueStart = valueEnd = -1;
-+ // The position is OK (On a delimiter)
-+ break;
-+ default:;
-+ if (!isSeparator(bytes[pos])) {
-+ // Token
-+ valueStart=pos;
-+ // getToken returns the position at the delimeter
-+ // or other non-token character
-+ valueEnd=getTokenEndPosition(bytes, valueStart, end);
-+ // We need pos to advance
-+ pos = valueEnd;
-+ } else {
-+ // INVALID COOKIE, advance to next delimiter
-+ // The starting character of the cookie value was
-+ // not valid.
-+ log("Invalid cookie. Value not a token or quoted
value");
-+ while (pos < end && bytes[pos] != ';' &&
-+ bytes[pos] != ',')
-+ {pos++; };
-+ pos++;
-+ // Make sure no special avpairs can be attributed to
-+ // the previous cookie by setting the current cookie
-+ // to null
-+ sc = null;
-+ continue;
-+ }
-+ }
-+ } else {
-+ // Name only cookie
-+ valueStart = valueEnd = -1;
-+ pos = nameEnd;
-+
-+ }
-+
-+ // We should have an avpair or name-only cookie at this
-+ // point. Perform some basic checks to make sure we are
-+ // in a good state.
-+
-+ // Skip whitespace
-+ while (pos < end && isWhiteSpace(bytes[pos])) {pos++; };
-+
-+
-+ // Make sure that after the cookie we have a separator. This
-+ // is only important if this is not the last cookie pair
-+ while (pos < end && bytes[pos] != ';' && bytes[pos] != ',') {
-+ pos++;
-+ }
-+
-+ pos++;
-+
-+ /*
-+ if (nameEnd <= nameStart || valueEnd < valueStart ) {
-+ // Something is wrong, but this may be a case
-+ // of having two ';' characters in a row.
-+ // log("Cookie name/value does not conform to RFC 2965");
-+ // Advance to next delimiter (ignoring everything else)
-+ while (pos < end && bytes[pos] != ';' && bytes[pos] != ',')
-+ { pos++; };
-+ pos++;
-+ // Make sure no special cookies can be attributed to
-+ // the previous cookie by setting the current cookie
-+ // to null
-+ sc = null;
-+ continue;
-+ }
-+ */
-+
-+ // All checks passed. Add the cookie, start with the
-+ // special avpairs first
-+ if (isSpecial) {
-+ isSpecial = false;
-+ // $Version must be the first avpair in the cookie header
-+ // (sc must be null)
-+ if (equals( "Version", bytes, nameStart, nameEnd) &&
-+ sc == null) {
-+ // Set version
-+ if( bytes[valueStart] =='1' && valueEnd == valueStart) {
-+ version=1;
-+ } else {
-+ // unknown version (Versioning is not very strict)
-+ }
-+ continue;
-+ }
-+
-+ // We need an active cookie for Path/Port/etc.
-+ if (sc == null) {
-+ continue;
-+ }
-+
-+ // Domain is more common, so it goes first
-+ if (equals( "Domain", bytes, nameStart, nameEnd)) {
-+ sc.getDomain().setBytes( bytes,
-+ valueStart,
-+ valueEnd-valueStart);
-+ continue;
-+ }
-+
-+ if (equals( "Path", bytes, nameStart, nameEnd)) {
-+ sc.getPath().setBytes( bytes,
-+ valueStart,
-+ valueEnd-valueStart);
-+ continue;
-+ }
-+
-+
-+ if (equals( "Port", bytes, nameStart, nameEnd)) {
-+ // sc.getPort is not currently implemented.
-+ // sc.getPort().setBytes( bytes,
-+ // valueStart,
-+ // valueEnd-valueStart );
-+ continue;
-+ }
-+
-+ // Unknown cookie, complain
-+ log("Unknown Special Cookie");
-
-- // wrong
-- test("$Version=1;foo=\"bar\";$Domain=apache.org;$Port=8080;a=b");
-+ } else { // Normal Cookie
-+ sc = addCookie();
-+ sc.setVersion( version );
-+ sc.getName().setBytes( bytes, nameStart,
-+ nameEnd-nameStart);
-+
-+ if (valueStart != -1) { // Normal AVPair
-+ sc.getValue().setBytes( bytes, valueStart,
-+ valueEnd-valueStart);
-+ } else {
-+ // Name Only
-+ sc.getValue().setString("");
-+ }
-+ continue;
-+ }
-+ }
- }
-
-- 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 ));
-+ /**
-+ * Given the starting position of a token, this gets the end of the
-+ * token, with no separator characters in between.
-+ * JVK
-+ */
-+ public static final int getTokenEndPosition(byte bytes[], int off, int
end){
-+ int pos = off;
-+ while (pos < end && !isSeparator(bytes[pos])) {pos++; };
-+
-+ if (pos > end)
-+ return end;
-+ return pos;
-+ }
-+
-+ /**
-+ * Given a starting position after an initial quote chracter, this gets
-+ * the position of the end quote. This escapes anything after a '\' char
-+ * JVK RFC 2616
-+ */
-+ public static final int getQuotedValueEndPosition(byte bytes[], int off,
int end){
-+ int pos = off;
-+ while (pos < end) {
-+ if (bytes[pos] == '"') {
-+ return pos;
-+ } else if (bytes[pos] == '\\' && pos < (end - 1)) {
-+ pos+=2;
-+ } else {
-+ pos++;
-+ }
- }
--
-+ // Error, we have reached the end of the header w/o a end quote
-+ return end;
- }
-- */
-
- }
-
-
+ http://people.apache.org/~jfclere/patches/Cookies.java.remy.patch
+ http://people.apache.org/~jfclere/patches/CookiesTest.patch
+ +1: jfclere
+ -1:
---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]