WCKET-6010 new encoder for header

Project: http://git-wip-us.apache.org/repos/asf/wicket/repo
Commit: http://git-wip-us.apache.org/repos/asf/wicket/commit/7b4c7047
Tree: http://git-wip-us.apache.org/repos/asf/wicket/tree/7b4c7047
Diff: http://git-wip-us.apache.org/repos/asf/wicket/diff/7b4c7047

Branch: refs/heads/lambdas
Commit: 7b4c7047b9b9189872f09409c6c7dada70fb648d
Parents: 5d51aed
Author: Sven Meier <[email protected]>
Authored: Fri Oct 23 19:27:02 2015 +0200
Committer: Sven Meier <[email protected]>
Committed: Wed Oct 28 14:41:15 2015 +0100

----------------------------------------------------------------------
 .../http/servlet/ServletWebResponseTest.java    |  4 +-
 .../apache/wicket/request/http/WebResponse.java |  2 +-
 .../apache/wicket/util/encoding/UrlEncoder.java | 87 ++++++++++++--------
 .../wicket/util/encoding/UrlEncoderTest.java    | 43 ++++++++++
 4 files changed, 99 insertions(+), 37 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/wicket/blob/7b4c7047/wicket-core/src/test/java/org/apache/wicket/protocol/http/servlet/ServletWebResponseTest.java
----------------------------------------------------------------------
diff --git 
a/wicket-core/src/test/java/org/apache/wicket/protocol/http/servlet/ServletWebResponseTest.java
 
b/wicket-core/src/test/java/org/apache/wicket/protocol/http/servlet/ServletWebResponseTest.java
index 5c5e9eb..e9fd4fa 100644
--- 
a/wicket-core/src/test/java/org/apache/wicket/protocol/http/servlet/ServletWebResponseTest.java
+++ 
b/wicket-core/src/test/java/org/apache/wicket/protocol/http/servlet/ServletWebResponseTest.java
@@ -130,10 +130,10 @@ public class ServletWebResponseTest extends Assert
                HttpServletResponse httpResponse = new 
MockHttpServletResponse(httpRequest);
                ServletWebResponse response = new 
ServletWebResponse(webRequest, httpResponse);
 
-               response.setInlineHeader("name with spaces");
+               response.setInlineHeader("name with spaces and;,");
                String header = httpResponse.getHeader("Content-Disposition");
                assertEquals(
-                       "inline; filename=\"name%20with%20spaces\"; 
filename*=UTF-8''name%20with%20spaces",
+                       "inline; filename=\"name%20with%20spaces%20and%3B%2C\"; 
filename*=UTF-8''name%20with%20spaces%20and%3B%2C",
                        header);
 
                // says: "name with bulgarian"

http://git-wip-us.apache.org/repos/asf/wicket/blob/7b4c7047/wicket-request/src/main/java/org/apache/wicket/request/http/WebResponse.java
----------------------------------------------------------------------
diff --git 
a/wicket-request/src/main/java/org/apache/wicket/request/http/WebResponse.java 
b/wicket-request/src/main/java/org/apache/wicket/request/http/WebResponse.java
index a790d0b..4183940 100644
--- 
a/wicket-request/src/main/java/org/apache/wicket/request/http/WebResponse.java
+++ 
b/wicket-request/src/main/java/org/apache/wicket/request/http/WebResponse.java
@@ -175,7 +175,7 @@ public abstract class WebResponse extends Response
        {
                return (Strings.isEmpty(filename) ? "" : String.format(
                        "; filename=\"%1$s\"; filename*=UTF-8''%1$s",
-                       UrlEncoder.PATH_INSTANCE.encode(filename, "UTF-8")));
+                       UrlEncoder.HEADER_INSTANCE.encode(filename, "UTF-8")));
        }
 
        /**

http://git-wip-us.apache.org/repos/asf/wicket/blob/7b4c7047/wicket-util/src/main/java/org/apache/wicket/util/encoding/UrlEncoder.java
----------------------------------------------------------------------
diff --git 
a/wicket-util/src/main/java/org/apache/wicket/util/encoding/UrlEncoder.java 
b/wicket-util/src/main/java/org/apache/wicket/util/encoding/UrlEncoder.java
index d03b7f1..85b18bd 100644
--- a/wicket-util/src/main/java/org/apache/wicket/util/encoding/UrlEncoder.java
+++ b/wicket-util/src/main/java/org/apache/wicket/util/encoding/UrlEncoder.java
@@ -42,17 +42,15 @@ public class UrlEncoder
         * encoder types
         */
        public enum Type {
-               /**
-                * query type
-                */
                QUERY,
-               /**
-                * path type
-                */
-               PATH
+               PATH,
+               HEADER
        }
 
-       // list of what not to decode
+       /**
+        * List of what not to encode, i.e. characters (e.g. A-Z) and other 
allowed signs (e.g. !)
+        * that are allowed but don't have a special meaning.
+        */
        protected BitSet dontNeedEncoding;
 
        // used in decoding
@@ -67,7 +65,7 @@ public class UrlEncoder
        public static final UrlEncoder QUERY_INSTANCE = new 
UrlEncoder(Type.QUERY);
 
        /**
-        * Encoder used to encode components of a path.<br/>
+        * Encoder used to encode segments of a path.<br/>
         * <br/>
         * 
         * For example: http://org.acme/foo/thispart/orthispart?butnot=thispart
@@ -75,6 +73,11 @@ public class UrlEncoder
        public static final UrlEncoder PATH_INSTANCE = new 
UrlEncoder(Type.PATH);
 
        /**
+        * Encoder used to encode a header.
+        */
+       public static final UrlEncoder HEADER_INSTANCE = new 
UrlEncoder(Type.HEADER);
+
+       /**
         * Allow subclass to call constructor.
         * 
         * @param type
@@ -154,29 +157,25 @@ public class UrlEncoder
                // sub-delims
                dontNeedEncoding.set('!');
                dontNeedEncoding.set('$');
-               // "&" needs to be encoded for query stings
-               // "(" and ")" probably don't need encoding, but we'll be 
conservative
-               dontNeedEncoding.set('*');
-               // "+" needs to be encoded for query strings (since it means =
-               dontNeedEncoding.set(',');
-               // ";" encoded due to use in path and/or query as delim in some
-               // instances (e.g., jsessionid)
-               // "=" needs to be encoded for query strings
-
-               // pchar
-               dontNeedEncoding.set(':'); // allowed and used in wicket 
interface
-               // params
-               dontNeedEncoding.set('@');
 
                // encoding type-specific
                switch (type)
                {
-               // this code consistent with java.net.URLEncoder version
                        case QUERY :
+                               // this code consistent with 
java.net.URLEncoder version#
+                               
                                // encoding a space to a + is done in the 
encode() method
                                dontNeedEncoding.set(' ');
-                               // to allow direct passing of URL in query
-                               dontNeedEncoding.set('/');
+                               
+                               // sub-delims continued
+                               dontNeedEncoding.set('*');
+                               dontNeedEncoding.set('/'); // to allow direct 
passing of URL in query
+                               dontNeedEncoding.set(',');
+                               // "'" doesn't need encoding, but it will make 
it easier to use in in JavaScript  
+                               // "(" and ")" don't need encoding, but we'll 
be conservative
+
+                               dontNeedEncoding.set(':'); // allowed and used 
in wicket interface
+                               dontNeedEncoding.set('@');
 
                                /*
                                 * the below encoding of a ? is disabled 
because it interferes in portlet
@@ -185,21 +184,41 @@ public class UrlEncoder
                                 * re-enable it as portlet environments are not 
high priority. we can also add a
                                 * switch somewhere to enable/disable this on 
applicaiton level. (WICKET-4019)
                                 */
-
-                               // to allow direct passing of URL in query
-                               // dontNeedEncoding.set('?');
+                               // dontNeedEncoding.set('?'); // to allow 
direct passing of URL in query
                                break;
 
-                       // this added to deal with encoding a PATH component
                        case PATH :
-                               // encode ' ' with a % instead of + in path 
portion
-
-                               // path component sub-delim values we do not 
need to escape
+                               // this added to deal with encoding a PATH 
segment
+                               
+                               // sub-delims continued
+                               dontNeedEncoding.set('*');
                                dontNeedEncoding.set('&');
+                               dontNeedEncoding.set('+');
+                               // "'" doesn't need encoding, but it will make 
it easier to use in in JavaScript  
+                               // "(" and ")" don't need encoding, but we'll 
be conservative
+                               dontNeedEncoding.set(',');
+                               dontNeedEncoding.set(';'); // semicolon is used 
in ;jsessionid=
                                dontNeedEncoding.set('=');
+                               
+                               dontNeedEncoding.set(':'); // allowed and used 
in wicket interface
+                               dontNeedEncoding.set('@');
+
+                               break;
+                               
+                       // this added to deal with encoding a PATH component
+                       case HEADER :
+                               // this added to deal with encoding of header
+                               
+                               // ' ' is encoded
+
+                               // sub-delims continued
+                               dontNeedEncoding.set('#');
+                               dontNeedEncoding.set('&');
                                dontNeedEncoding.set('+');
-                               // don't encode semicolon because it is used in 
;jsessionid=
-                               dontNeedEncoding.set(';');
+                               
+                               dontNeedEncoding.set('^');
+                               dontNeedEncoding.set('`');
+                               dontNeedEncoding.set('|');
                                break;
                }
        }

http://git-wip-us.apache.org/repos/asf/wicket/blob/7b4c7047/wicket-util/src/test/java/org/apache/wicket/util/encoding/UrlEncoderTest.java
----------------------------------------------------------------------
diff --git 
a/wicket-util/src/test/java/org/apache/wicket/util/encoding/UrlEncoderTest.java 
b/wicket-util/src/test/java/org/apache/wicket/util/encoding/UrlEncoderTest.java
index c88e74d..1f86c05 100644
--- 
a/wicket-util/src/test/java/org/apache/wicket/util/encoding/UrlEncoderTest.java
+++ 
b/wicket-util/src/test/java/org/apache/wicket/util/encoding/UrlEncoderTest.java
@@ -24,6 +24,49 @@ import org.junit.Test;
 @SuppressWarnings("javadoc")
 public class UrlEncoderTest extends Assert
 {
+
+       // starts with &auml;
+       private static final char[] encodingCandidates = 
"\u00c4!\"§$%&/()=?`*'_:;><,.-#+´\\}][{|".toCharArray();
+       
+       @Test
+       public void pathUnencoded()  {
+               String unencoded = "azAZ09.-_~!$&*+,;=:@";
+               
+               assertEquals(unencoded,  
UrlEncoder.PATH_INSTANCE.encode(unencoded, CharEncoding.UTF_8));
+               
+               for (char candidate : encodingCandidates) {
+                       if (unencoded.indexOf(candidate) == -1) {
+                               assertNotEquals("" + candidate, 
UrlEncoder.PATH_INSTANCE.encode("" + candidate, CharEncoding.UTF_8));
+                       }
+               }
+       }
+       
+       @Test
+       public void queryStringUnencoded()  {
+               String unencoded = "azAZ09.-_~!$*,:@/";
+               
+               assertEquals(unencoded, 
UrlEncoder.QUERY_INSTANCE.encode(unencoded, CharEncoding.UTF_8));
+
+               for (char candidate : encodingCandidates) {
+                       if (unencoded.indexOf(candidate) == -1) {
+                               assertNotEquals("" + candidate, 
UrlEncoder.QUERY_INSTANCE.encode("" + candidate, CharEncoding.UTF_8));
+                       }
+               }
+       }
+       
+       @Test
+       public void headerUnencoded()  {
+               String unencoded = "azAZ09.-_~!$&+#^`|";
+               
+               assertEquals(unencoded, 
UrlEncoder.HEADER_INSTANCE.encode(unencoded, CharEncoding.UTF_8));
+               
+               for (char candidate : encodingCandidates) {
+                       if (unencoded.indexOf(candidate) == -1) {
+                               assertNotEquals("" + candidate, 
UrlEncoder.HEADER_INSTANCE.encode("" + candidate, CharEncoding.UTF_8));
+                       }
+               }
+       }
+
        /**
         * <a 
href="https://issues.apache.org/jira/browse/WICKET-3721";>WICKET-3721</a> Encode
         * apostrophes because otherwise they get XML encoded by 
ComponentTag#writeOutput() to

Reply via email to