--- ./connectors/util/java/org/apache/tomcat/util/http/ServerCookie.java	2007-03-05 16:27:39.000000000 +0100
+++ ./connectors/util/java/org/apache/tomcat/util/http/ServerCookie.java	2007-08-24 14:40:51.000000000 +0200
@@ -130,6 +130,7 @@
     //
     // private static final String tspecials = "()<>@,;:\\\"/[]?={} \t";
     private static final String tspecials = ",; ";
+    private static final String tspecials2 = ",; \"";
 
     /*
      * Tests a string and returns true if the string counts as a
@@ -154,6 +155,20 @@
 	return true;
     }
 
+    public static boolean isToken2(String value) {
+        if( value==null) return true;
+        int len = value.length();
+
+        for (int i = 0; i < len; i++) {
+            char c = value.charAt(i);
+
+            if (c < 0x20 || c >= 0x7f || tspecials2.indexOf(c) != -1)
+                return false;
+        }
+        return true;
+    }
+
+
     public static boolean checkName( String name ) {
 	if (!isToken(name)
 		|| name.equalsIgnoreCase("Comment")	// rfc2019
@@ -213,7 +228,7 @@
         // this part is the same for all cookies
 	buf.append( name );
         buf.append("=");
-        maybeQuote(version, buf, value);
+        maybeQuote2(version, buf, value);
 
 	// XXX Netscape cookie: "; "
  	// add version 1 specific information
@@ -284,6 +299,20 @@
         }
     }
 
+
+    public static void maybeQuote2 (int version, StringBuffer buf,
+            String value) {
+        // special case - a \n or \r  shouldn't happen in any case
+        if (isToken2(value)) {
+            buf.append(value);
+        } else {
+            buf.append('"');
+            buf.append(escapeDoubleQuotes(value));
+            buf.append('"');
+        }
+    }
+
+
     // log
     static final int dbg=1;
     public static void log(String s ) {
@@ -306,12 +335,14 @@
         }
 
         StringBuffer b = new StringBuffer();
+        char p = s.charAt(0);
         for (int i = 0; i < s.length(); i++) {
             char c = s.charAt(i);
-            if (c == '"')
+            if (c == '"' && p != '\\')
                 b.append('\\').append('"');
             else
                 b.append(c);
+            p = c;
         }
 
         return b.toString();
--- ./connectors/util/java/org/apache/tomcat/util/http/Cookies.java	2007-08-24 14:15:10.000000000 +0200
+++ ./connectors/util/java/org/apache/tomcat/util/http/Cookies.java	2007-08-24 14:50:26.000000000 +0200
@@ -249,9 +249,11 @@
             int endValue=startValue;
             
             cc=bytes[pos];
-            if(  cc== '\'' || cc=='"' ) {
-                startValue++;
-                endValue=indexOf( bytes, startValue, end, cc );
+            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 );
@@ -335,28 +337,26 @@
         return off;
     }
 
-    public static int indexOf( byte bytes[], int off, int end, byte qq )
+    /*
+     *  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==qq )
+            if (b=='\\') {
+                off++;
+                off++;
+                continue;
+            }
+            if( b==cc )
                 return off;
             off++;
         }
-        return off;
+        return -1;
     }
 
-    public static int indexOf( byte bytes[], int off, int end, char qq )
-    {
-        while( off < end ) {
-            byte b=bytes[off];
-            if( b==qq )
-                return off;
-            off++;
-        }
-        return off;
-    }
-    
     // XXX will be refactored soon!
     public static boolean equals( String s, byte b[], int start, int end) {
         int blen = end-start;
