Author: jboynes
Date: Tue Jan  7 19:21:20 2014
New Revision: 1556328

URL: http://svn.apache.org/r1556328
Log:
Refactor ServerCookie to separate cookie state from the helper code used to 
generate the header. This change is purely a movement of code to improve 
readability.

ServerCookie is now a pure data object holding MessageBytes, typically 
resulting from the parse of the Cookie header done by Cookies. 
The appendCookieValue static helper method is moved to a new class, 
SetCookieSupport, that Response uses when addCookie is called.

Added:
    tomcat/trunk/java/org/apache/tomcat/util/http/SetCookieSupport.java   (with 
props)
Modified:
    tomcat/trunk/java/org/apache/catalina/connector/Response.java
    tomcat/trunk/java/org/apache/tomcat/util/http/ServerCookie.java

Modified: tomcat/trunk/java/org/apache/catalina/connector/Response.java
URL: 
http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/catalina/connector/Response.java?rev=1556328&r1=1556327&r2=1556328&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/catalina/connector/Response.java (original)
+++ tomcat/trunk/java/org/apache/catalina/connector/Response.java Tue Jan  7 
19:21:20 2014
@@ -49,7 +49,7 @@ import org.apache.tomcat.util.buf.CharCh
 import org.apache.tomcat.util.buf.UEncoder;
 import org.apache.tomcat.util.http.FastHttpDateFormat;
 import org.apache.tomcat.util.http.MimeHeaders;
-import org.apache.tomcat.util.http.ServerCookie;
+import org.apache.tomcat.util.http.SetCookieSupport;
 import org.apache.tomcat.util.http.parser.MediaTypeCache;
 import org.apache.tomcat.util.net.URL;
 import org.apache.tomcat.util.res.StringManager;
@@ -913,21 +913,21 @@ public class Response
             AccessController.doPrivileged(new PrivilegedAction<Void>() {
                 @Override
                 public Void run(){
-                    ServerCookie.appendCookieValue
-                        (sb, cookie.getVersion(), cookie.getName(),
-                         cookie.getValue(), cookie.getPath(),
-                         cookie.getDomain(), cookie.getComment(),
-                         cookie.getMaxAge(), cookie.getSecure(),
-                         cookie.isHttpOnly());
+                    SetCookieSupport.appendCookieValue
+                            (sb, cookie.getVersion(), cookie.getName(),
+                                    cookie.getValue(), cookie.getPath(),
+                                    cookie.getDomain(), cookie.getComment(),
+                                    cookie.getMaxAge(), cookie.getSecure(),
+                                    cookie.isHttpOnly());
                     return null;
                 }
             });
         } else {
-            ServerCookie.appendCookieValue
-                (sb, cookie.getVersion(), cookie.getName(), cookie.getValue(),
-                     cookie.getPath(), cookie.getDomain(), cookie.getComment(),
-                     cookie.getMaxAge(), cookie.getSecure(),
-                     cookie.isHttpOnly());
+            SetCookieSupport.appendCookieValue
+                    (sb, cookie.getVersion(), cookie.getName(), 
cookie.getValue(),
+                            cookie.getPath(), cookie.getDomain(), 
cookie.getComment(),
+                            cookie.getMaxAge(), cookie.getSecure(),
+                            cookie.isHttpOnly());
         }
         return sb;
     }

Modified: tomcat/trunk/java/org/apache/tomcat/util/http/ServerCookie.java
URL: 
http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/tomcat/util/http/ServerCookie.java?rev=1556328&r1=1556327&r2=1556328&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/tomcat/util/http/ServerCookie.java (original)
+++ tomcat/trunk/java/org/apache/tomcat/util/http/ServerCookie.java Tue Jan  7 
19:21:20 2014
@@ -17,12 +17,6 @@
 package org.apache.tomcat.util.http;
 
 import java.io.Serializable;
-import java.text.DateFormat;
-import java.text.FieldPosition;
-import java.text.SimpleDateFormat;
-import java.util.Date;
-import java.util.Locale;
-import java.util.TimeZone;
 
 import org.apache.tomcat.util.buf.MessageBytes;
 
@@ -51,30 +45,9 @@ public class ServerCookie implements Ser
     private final MessageBytes comment=MessageBytes.newInstance();
     private int version = 0;
 
-    // Other fields
-    private static final String OLD_COOKIE_PATTERN =
-        "EEE, dd-MMM-yyyy HH:mm:ss z";
-    private static final ThreadLocal<DateFormat> OLD_COOKIE_FORMAT =
-        new ThreadLocal<DateFormat>() {
-        @Override
-        protected DateFormat initialValue() {
-            DateFormat df =
-                new SimpleDateFormat(OLD_COOKIE_PATTERN, Locale.US);
-            df.setTimeZone(TimeZone.getTimeZone("GMT"));
-            return df;
-        }
-    };
-    private static final String ancientDate;
+    // Note: Servlet Spec =< 3.0 only refers to Netscape and RFC2109, not 
RFC2965
 
-    static {
-        ancientDate = OLD_COOKIE_FORMAT.get().format(new Date(10000));
-    }
-
-    // Note: Servlet Spec =< 3.0 only refers to Netscape and RFC2109,
-    // not RFC2965
-
-    // Version 2 (RFC2965) attributes that would need to be added to support
-    // v2 cookies
+    // Version 2 (RFC2965) attributes that would need to be added to support 
v2 cookies
     // CommentURL
     // Discard - implied by maxAge <0
     // Port
@@ -129,192 +102,5 @@ public class ServerCookie implements Ser
         return "Cookie " + getName() + "=" + getValue() + " ; "
             + getVersion() + " " + getPath() + " " + getDomain();
     }
-
-    // -------------------- Cookie parsing tools
-
-
-    public static void appendCookieValue( StringBuffer headerBuf,
-                                          int version,
-                                          String name,
-                                          String value,
-                                          String path,
-                                          String domain,
-                                          String comment,
-                                          int maxAge,
-                                          boolean isSecure,
-                                          boolean isHttpOnly)
-    {
-        StringBuffer buf = new StringBuffer();
-        // Servlet implementation checks name
-        buf.append( name );
-        buf.append("=");
-        // Servlet implementation does not check anything else
-
-        /*
-         * The spec allows some latitude on when to send the version attribute
-         * with a Set-Cookie header. To be nice to clients, we'll make sure the
-         * version attribute is first. That means checking the various things
-         * that can cause us to switch to a v1 cookie first.
-         *
-         * Note that by checking for tokens we will also throw an exception if 
a
-         * control character is encountered.
-         */
-        // Start by using the version we were asked for
-        int newVersion = version;
-
-        // If it is v0, check if we need to switch
-        if (newVersion == 0 &&
-                (!CookieSupport.ALLOW_HTTP_SEPARATORS_IN_V0 &&
-                 CookieSupport.isHttpToken(value) ||
-                 CookieSupport.ALLOW_HTTP_SEPARATORS_IN_V0 &&
-                 CookieSupport.isV0Token(value))) {
-            // HTTP token in value - need to use v1
-            newVersion = 1;
-        }
-
-        if (newVersion == 0 && comment != null) {
-            // Using a comment makes it a v1 cookie
-           newVersion = 1;
-        }
-
-        if (newVersion == 0 &&
-                (!CookieSupport.ALLOW_HTTP_SEPARATORS_IN_V0 &&
-                 CookieSupport.isHttpToken(path) ||
-                 CookieSupport.ALLOW_HTTP_SEPARATORS_IN_V0 &&
-                 CookieSupport.isV0Token(path))) {
-            // HTTP token in path - need to use v1
-            newVersion = 1;
-        }
-
-        if (newVersion == 0 &&
-                (!CookieSupport.ALLOW_HTTP_SEPARATORS_IN_V0 &&
-                 CookieSupport.isHttpToken(domain) ||
-                 CookieSupport.ALLOW_HTTP_SEPARATORS_IN_V0 &&
-                 CookieSupport.isV0Token(domain))) {
-            // HTTP token in domain - need to use v1
-            newVersion = 1;
-        }
-
-        // Now build the cookie header
-        // Value
-        maybeQuote(buf, value);
-        // Add version 1 specific information
-        if (newVersion == 1) {
-            // Version=1 ... required
-            buf.append ("; Version=1");
-
-            // Comment=comment
-            if ( comment!=null ) {
-                buf.append ("; Comment=");
-                maybeQuote(buf, comment);
-            }
-        }
-
-        // Add domain information, if present
-        if (domain!=null) {
-            buf.append("; Domain=");
-            maybeQuote(buf, domain);
-        }
-
-        // Max-Age=secs ... or use old "Expires" format
-        if (maxAge >= 0) {
-            if (newVersion > 0) {
-                buf.append ("; Max-Age=");
-                buf.append (maxAge);
-            }
-            // IE6, IE7 and possibly other browsers don't understand Max-Age.
-            // They do understand Expires, even with V1 cookies!
-            if (newVersion == 0 || CookieSupport.ALWAYS_ADD_EXPIRES) {
-                // Wdy, DD-Mon-YY HH:MM:SS GMT ( Expires Netscape format )
-                buf.append ("; Expires=");
-                // To expire immediately we need to set the time in past
-                if (maxAge == 0) {
-                    buf.append( ancientDate );
-                } else {
-                    OLD_COOKIE_FORMAT.get().format(
-                            new Date(System.currentTimeMillis() +
-                                    maxAge*1000L),
-                            buf, new FieldPosition(0));
-                }
-            }
-        }
-
-        // Path=path
-        if (path!=null) {
-            buf.append ("; Path=");
-            maybeQuote(buf, path);
-        }
-
-        // Secure
-        if (isSecure) {
-          buf.append ("; Secure");
-        }
-
-        // HttpOnly
-        if (isHttpOnly) {
-            buf.append("; HttpOnly");
-        }
-        headerBuf.append(buf);
-    }
-
-    /**
-     * Quotes values if required.
-     * @param buf
-     * @param value
-     */
-    private static void maybeQuote (StringBuffer buf, String value) {
-        if (value==null || value.length()==0) {
-            buf.append("\"\"");
-        } else if (CookieSupport.alreadyQuoted(value)) {
-            buf.append('"');
-            buf.append(escapeDoubleQuotes(value,1,value.length()-1));
-            buf.append('"');
-        } else if (CookieSupport.isHttpToken(value) &&
-                !CookieSupport.ALLOW_HTTP_SEPARATORS_IN_V0 ||
-                CookieSupport.isV0Token(value) &&
-                CookieSupport.ALLOW_HTTP_SEPARATORS_IN_V0) {
-            buf.append('"');
-            buf.append(escapeDoubleQuotes(value,0,value.length()));
-            buf.append('"');
-        } else {
-            buf.append(value);
-        }
-    }
-
-
-    /**
-     * Escapes any double quotes in the given string.
-     *
-     * @param s the input string
-     * @param beginIndex start index inclusive
-     * @param endIndex exclusive
-     * @return The (possibly) escaped string
-     */
-    private static String escapeDoubleQuotes(String s, int beginIndex, int 
endIndex) {
-
-        if (s == null || s.length() == 0 || s.indexOf('"') == -1) {
-            return s;
-        }
-
-        StringBuffer b = new StringBuffer();
-        for (int i = beginIndex; i < endIndex; i++) {
-            char c = s.charAt(i);
-            if (c == '\\' ) {
-                b.append(c);
-                //ignore the character after an escape, just append it
-                if (++i>=endIndex) {
-                    throw new IllegalArgumentException("Invalid escape 
character in cookie value.");
-                }
-                b.append(s.charAt(i));
-            } else if (c == '"') {
-                b.append('\\').append('"');
-            } else {
-                b.append(c);
-            }
-        }
-
-        return b.toString();
-    }
-
 }
 

Added: tomcat/trunk/java/org/apache/tomcat/util/http/SetCookieSupport.java
URL: 
http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/tomcat/util/http/SetCookieSupport.java?rev=1556328&view=auto
==============================================================================
--- tomcat/trunk/java/org/apache/tomcat/util/http/SetCookieSupport.java (added)
+++ tomcat/trunk/java/org/apache/tomcat/util/http/SetCookieSupport.java Tue Jan 
 7 19:21:20 2014
@@ -0,0 +1,229 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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;
+
+import java.text.DateFormat;
+import java.text.FieldPosition;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+import java.util.Locale;
+import java.util.TimeZone;
+
+/**
+ * Support class for generating Set-Cookie header values.
+ */
+public class SetCookieSupport {
+    // Other fields
+    private static final String OLD_COOKIE_PATTERN = "EEE, dd-MMM-yyyy 
HH:mm:ss z";
+    private static final ThreadLocal<DateFormat> OLD_COOKIE_FORMAT =
+        new ThreadLocal<DateFormat>() {
+        @Override
+        protected DateFormat initialValue() {
+            DateFormat df =
+                new SimpleDateFormat(OLD_COOKIE_PATTERN, Locale.US);
+            df.setTimeZone(TimeZone.getTimeZone("GMT"));
+            return df;
+        }
+    };
+    private static final String ancientDate;
+
+    static {
+        ancientDate = OLD_COOKIE_FORMAT.get().format(new Date(10000));
+    }
+
+    public static void appendCookieValue( StringBuffer headerBuf,
+                                          int version,
+                                          String name,
+                                          String value,
+                                          String path,
+                                          String domain,
+                                          String comment,
+                                          int maxAge,
+                                          boolean isSecure,
+                                          boolean isHttpOnly)
+    {
+        StringBuffer buf = new StringBuffer();
+        // Servlet implementation checks name
+        buf.append( name );
+        buf.append("=");
+        // Servlet implementation does not check anything else
+
+        /*
+         * The spec allows some latitude on when to send the version attribute
+         * with a Set-Cookie header. To be nice to clients, we'll make sure the
+         * version attribute is first. That means checking the various things
+         * that can cause us to switch to a v1 cookie first.
+         *
+         * Note that by checking for tokens we will also throw an exception if 
a
+         * control character is encountered.
+         */
+        // Start by using the version we were asked for
+        int newVersion = version;
+
+        // If it is v0, check if we need to switch
+        if (newVersion == 0 &&
+                (!CookieSupport.ALLOW_HTTP_SEPARATORS_IN_V0 &&
+                 CookieSupport.isHttpToken(value) ||
+                 CookieSupport.ALLOW_HTTP_SEPARATORS_IN_V0 &&
+                 CookieSupport.isV0Token(value))) {
+            // HTTP token in value - need to use v1
+            newVersion = 1;
+        }
+
+        if (newVersion == 0 && comment != null) {
+            // Using a comment makes it a v1 cookie
+           newVersion = 1;
+        }
+
+        if (newVersion == 0 &&
+                (!CookieSupport.ALLOW_HTTP_SEPARATORS_IN_V0 &&
+                 CookieSupport.isHttpToken(path) ||
+                 CookieSupport.ALLOW_HTTP_SEPARATORS_IN_V0 &&
+                 CookieSupport.isV0Token(path))) {
+            // HTTP token in path - need to use v1
+            newVersion = 1;
+        }
+
+        if (newVersion == 0 &&
+                (!CookieSupport.ALLOW_HTTP_SEPARATORS_IN_V0 &&
+                 CookieSupport.isHttpToken(domain) ||
+                 CookieSupport.ALLOW_HTTP_SEPARATORS_IN_V0 &&
+                 CookieSupport.isV0Token(domain))) {
+            // HTTP token in domain - need to use v1
+            newVersion = 1;
+        }
+
+        // Now build the cookie header
+        // Value
+        maybeQuote(buf, value);
+        // Add version 1 specific information
+        if (newVersion == 1) {
+            // Version=1 ... required
+            buf.append ("; Version=1");
+
+            // Comment=comment
+            if ( comment!=null ) {
+                buf.append ("; Comment=");
+                maybeQuote(buf, comment);
+            }
+        }
+
+        // Add domain information, if present
+        if (domain!=null) {
+            buf.append("; Domain=");
+            maybeQuote(buf, domain);
+        }
+
+        // Max-Age=secs ... or use old "Expires" format
+        if (maxAge >= 0) {
+            if (newVersion > 0) {
+                buf.append ("; Max-Age=");
+                buf.append (maxAge);
+            }
+            // IE6, IE7 and possibly other browsers don't understand Max-Age.
+            // They do understand Expires, even with V1 cookies!
+            if (newVersion == 0 || CookieSupport.ALWAYS_ADD_EXPIRES) {
+                // Wdy, DD-Mon-YY HH:MM:SS GMT ( Expires Netscape format )
+                buf.append ("; Expires=");
+                // To expire immediately we need to set the time in past
+                if (maxAge == 0) {
+                    buf.append( ancientDate );
+                } else {
+                    OLD_COOKIE_FORMAT.get().format(
+                            new Date(System.currentTimeMillis() +
+                                    maxAge*1000L),
+                            buf, new FieldPosition(0));
+                }
+            }
+        }
+
+        // Path=path
+        if (path!=null) {
+            buf.append ("; Path=");
+            maybeQuote(buf, path);
+        }
+
+        // Secure
+        if (isSecure) {
+          buf.append ("; Secure");
+        }
+
+        // HttpOnly
+        if (isHttpOnly) {
+            buf.append("; HttpOnly");
+        }
+        headerBuf.append(buf);
+    }
+
+    /**
+     * Quotes values if required.
+     * @param buf
+     * @param value
+     */
+    private static void maybeQuote (StringBuffer buf, String value) {
+        if (value==null || value.length()==0) {
+            buf.append("\"\"");
+        } else if (CookieSupport.alreadyQuoted(value)) {
+            buf.append('"');
+            buf.append(escapeDoubleQuotes(value,1,value.length()-1));
+            buf.append('"');
+        } else if (CookieSupport.isHttpToken(value) &&
+                !CookieSupport.ALLOW_HTTP_SEPARATORS_IN_V0 ||
+                CookieSupport.isV0Token(value) &&
+                CookieSupport.ALLOW_HTTP_SEPARATORS_IN_V0) {
+            buf.append('"');
+            buf.append(escapeDoubleQuotes(value,0,value.length()));
+            buf.append('"');
+        } else {
+            buf.append(value);
+        }
+    }
+
+    /**
+     * Escapes any double quotes in the given string.
+     *
+     * @param s the input string
+     * @param beginIndex start index inclusive
+     * @param endIndex exclusive
+     * @return The (possibly) escaped string
+     */
+    private static String escapeDoubleQuotes(String s, int beginIndex, int 
endIndex) {
+
+        if (s == null || s.length() == 0 || s.indexOf('"') == -1) {
+            return s;
+        }
+
+        StringBuffer b = new StringBuffer();
+        for (int i = beginIndex; i < endIndex; i++) {
+            char c = s.charAt(i);
+            if (c == '\\' ) {
+                b.append(c);
+                //ignore the character after an escape, just append it
+                if (++i>=endIndex) {
+                    throw new IllegalArgumentException("Invalid escape 
character in cookie value.");
+                }
+                b.append(s.charAt(i));
+            } else if (c == '"') {
+                b.append('\\').append('"');
+            } else {
+                b.append(c);
+            }
+        }
+
+        return b.toString();
+    }
+}

Propchange: tomcat/trunk/java/org/apache/tomcat/util/http/SetCookieSupport.java
------------------------------------------------------------------------------
    svn:eol-style = native



---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org
For additional commands, e-mail: dev-h...@tomcat.apache.org

Reply via email to