You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cxf.apache.org by se...@apache.org on 2013/05/20 14:19:02 UTC

svn commit: r1484443 - in /cxf/trunk: rt/rs/client/src/main/java/org/apache/cxf/jaxrs/client/ systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/

Author: sergeyb
Date: Mon May 20 12:19:02 2013
New Revision: 1484443

URL: http://svn.apache.org/r1484443
Log:
[CXF-5014] Do not split HTTP headers on the client side by default, to avoid unexpected splits and to be consistent with the way HTTP headers are treated on the server side

Modified:
    cxf/trunk/rt/rs/client/src/main/java/org/apache/cxf/jaxrs/client/AbstractClient.java
    cxf/trunk/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/JAXRS20ClientServerBookTest.java
    cxf/trunk/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/JAXRSClientServerBookTest.java

Modified: cxf/trunk/rt/rs/client/src/main/java/org/apache/cxf/jaxrs/client/AbstractClient.java
URL: http://svn.apache.org/viewvc/cxf/trunk/rt/rs/client/src/main/java/org/apache/cxf/jaxrs/client/AbstractClient.java?rev=1484443&r1=1484442&r2=1484443&view=diff
==============================================================================
--- cxf/trunk/rt/rs/client/src/main/java/org/apache/cxf/jaxrs/client/AbstractClient.java (original)
+++ cxf/trunk/rt/rs/client/src/main/java/org/apache/cxf/jaxrs/client/AbstractClient.java Mon May 20 12:19:02 2013
@@ -103,6 +103,8 @@ public abstract class AbstractClient imp
     
     private static final String HTTP_SCHEME = "http";
     private static final String PROXY_PROPERTY = "jaxrs.proxy";
+    private static final String HEADER_SPLIT_PROPERTY =
+        "org.apache.cxf.http.header.split";
     private static final Logger LOG = LogUtils.getL7dLogger(AbstractClient.class);
     private static final ResourceBundle BUNDLE = BundleUtils.getBundle(AbstractClient.class);
     
@@ -363,10 +365,11 @@ public abstract class AbstractClient imp
             return currentResponseBuilder;
         }
                 
-        @SuppressWarnings("unchecked")
         Map<String, List<String>> protocolHeaders = 
-            (Map<String, List<String>>)responseMessage.get(Message.PROTOCOL_HEADERS);
-                
+            CastUtils.cast((Map<?, ?>)responseMessage.get(Message.PROTOCOL_HEADERS));
+        
+        boolean splitHeaders = 
+            MessageUtils.isTrue(outMessage.getContextualProperty(HEADER_SPLIT_PROPERTY));
         for (Map.Entry<String, List<String>> entry : protocolHeaders.entrySet()) {
             if (null == entry.getKey()) {
                 continue;
@@ -377,23 +380,27 @@ public abstract class AbstractClient imp
                     continue;                    
                 }
                 for (String val : entry.getValue()) {
-                    String[] values;
-                    if (val == null || val.length() == 0) {
-                        values = new String[]{""};
-                    } else if (val.charAt(0) == '"' && val.charAt(val.length() - 1) == '"') {
-                        // if the value starts with a quote and ends with a quote, we do a best
-                        // effort attempt to determine what the individual values are.
-                        values = parseQuotedHeaderValue(val);
-                    } else {
-                        boolean splitPossible = !(HttpHeaders.SET_COOKIE.equalsIgnoreCase(entry.getKey())
-                            && val.toUpperCase().contains(HttpHeaders.EXPIRES.toUpperCase()));
-                        values = splitPossible ? val.split(",") : new String[]{val};
-                    }
-                    for (String s : values) {
-                        String theValue = s.trim();
-                        if (theValue.length() > 0) {
-                            currentResponseBuilder.header(entry.getKey(), theValue);
+                    if (splitHeaders) {
+                        String[] values;
+                        if (val == null || val.length() == 0) {
+                            values = new String[]{""};
+                        } else if (val.charAt(0) == '"' && val.charAt(val.length() - 1) == '"') {
+                            // if the value starts with a quote and ends with a quote, we do a best
+                            // effort attempt to determine what the individual values are.
+                            values = parseQuotedHeaderValue(val);
+                        } else {
+                            boolean splitPossible = !(HttpHeaders.SET_COOKIE.equalsIgnoreCase(entry.getKey())
+                                && val.toUpperCase().contains(HttpHeaders.EXPIRES.toUpperCase()));
+                            values = splitPossible ? val.split(",") : new String[]{val};
+                        }
+                        for (String s : values) {
+                            String theValue = s.trim();
+                            if (theValue.length() > 0) {
+                                currentResponseBuilder.header(entry.getKey(), theValue);
+                            }
                         }
+                    } else {
+                        currentResponseBuilder.header(entry.getKey(), val);
                     }
                 }
             }

Modified: cxf/trunk/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/JAXRS20ClientServerBookTest.java
URL: http://svn.apache.org/viewvc/cxf/trunk/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/JAXRS20ClientServerBookTest.java?rev=1484443&r1=1484442&r2=1484443&view=diff
==============================================================================
--- cxf/trunk/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/JAXRS20ClientServerBookTest.java (original)
+++ cxf/trunk/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/JAXRS20ClientServerBookTest.java Mon May 20 12:19:02 2013
@@ -48,6 +48,7 @@ import org.apache.cxf.jaxrs.client.WebCl
 import org.apache.cxf.testutil.common.AbstractBusClientServerTestBase;
 
 import org.junit.BeforeClass;
+import org.junit.Ignore;
 import org.junit.Test;
 
 public class JAXRS20ClientServerBookTest extends AbstractBusClientServerTestBase {
@@ -100,6 +101,28 @@ public class JAXRS20ClientServerBookTest
     }
     
     @Test
+    @Ignore
+    public void testGetBookAsync404() throws Exception {
+        String address = "http://localhost:" + PORT + "/bookstore/bookheaders/404";
+        WebClient wc = createWebClient(address);
+        Future<Book> future = wc.async().get(Book.class);
+        Book book = future.get();
+        assertEquals(124L, book.getId());
+    }
+    
+    @Test
+    @Ignore
+    public void testGetBookAsync404Callback() throws Exception {
+        String address = "http://localhost:" + PORT + "/bookstore/bookheaders/404";
+        WebClient wc = createWebClient(address);
+        final Holder<Book> holder = new Holder<Book>();
+        InvocationCallback<Book> callback = createCallback(holder);
+        Future<Book> future = wc.async().get(callback);
+        Book book = future.get();
+        assertEquals(124L, book.getId());
+    }
+    
+    @Test
     public void testGetBookAsyncNoCallback() throws Exception {
         String address = "http://localhost:" + PORT + "/bookstore/bookheaders/simple";
         WebClient wc = createWebClient(address);
@@ -292,6 +315,7 @@ public class JAXRS20ClientServerBookTest
                 holder.value = response;
             }
             public void failed(Throwable error) {
+                error.printStackTrace();
             }
         };
     }

Modified: cxf/trunk/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/JAXRSClientServerBookTest.java
URL: http://svn.apache.org/viewvc/cxf/trunk/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/JAXRSClientServerBookTest.java?rev=1484443&r1=1484442&r2=1484443&view=diff
==============================================================================
--- cxf/trunk/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/JAXRSClientServerBookTest.java (original)
+++ cxf/trunk/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/JAXRSClientServerBookTest.java Mon May 20 12:19:02 2013
@@ -25,6 +25,7 @@ import java.net.HttpURLConnection;
 import java.net.URL;
 import java.net.URLEncoder;
 import java.util.ArrayList;
+import java.util.Arrays;
 import java.util.Collection;
 import java.util.Collections;
 import java.util.HashMap;
@@ -836,6 +837,7 @@ public class JAXRSClientServerBookTest e
         WebClient wc = 
             WebClient.create("http://localhost:" 
                              + PORT + "/bookstore/bookurl/http%3A%2F%2Ftest.com%2Frss%2F123");
+        WebClient.getConfig(wc).getRequestContext().put("org.apache.cxf.http.header.split", true);
         Response response = wc.options();
         List<Object> values = response.getMetadata().get("Allow");
         assertNotNull(values);
@@ -852,6 +854,7 @@ public class JAXRSClientServerBookTest e
         WebClient wc = 
             WebClient.create("http://localhost:" 
                              + PORT + "/bookstore/options");
+        WebClient.getConfig(wc).getRequestContext().put("org.apache.cxf.http.header.split", true);
         Response response = wc.options();
         List<Object> values = response.getMetadata().get("Allow");
         assertNotNull(values);
@@ -864,10 +867,27 @@ public class JAXRSClientServerBookTest e
     }
     
     @Test
+    public void testExplicitOptionsNoSplitByDefault() throws Exception {
+        WebClient wc = 
+            WebClient.create("http://localhost:" 
+                             + PORT + "/bookstore/options");
+        Response response = wc.options();
+        List<String> values = Arrays.asList(response.getHeaderString("Allow").split(","));
+        assertNotNull(values);
+        assertTrue(values.contains("POST") && values.contains("GET")
+                   && values.contains("DELETE") && values.contains("PUT"));
+        assertEquals(0, ((InputStream)response.getEntity()).available());
+        List<Object> date = response.getMetadata().get("Date");
+        assertNotNull(date);
+        assertEquals(1, date.size());
+    }
+    
+    @Test
     public void testOptionsOnSubresource() throws Exception {
         WebClient wc = 
             WebClient.create("http://localhost:" 
                              + PORT + "/bookstore/booksubresource/123");
+        WebClient.getConfig(wc).getRequestContext().put("org.apache.cxf.http.header.split", true);
         Response response = wc.options();
         List<Object> values = response.getMetadata().get("Allow");
         assertNotNull(values);
@@ -2035,7 +2055,8 @@ public class JAXRSClientServerBookTest e
     public void testUriInfoMatchedUrisDecode() throws Exception {
         String expected = "[/bookstore/booksubresource/123/chapters/sub/1/matched!uris, "
                           + "/bookstore/booksubresource/123/chapters/sub/1/, "
-                          + "/bookstore/booksubresource/123/]";
+                          + "/bookstore/booksubresource/123/, "
+                          + "/bookstore]";
         getAndCompare("http://localhost:" + PORT + "/bookstore/"
                       + "booksubresource/123/chapters/sub/1/matched%21uris?decode=true", 
                       expected, "text/plain", "text/plain", 200);
@@ -2046,7 +2067,8 @@ public class JAXRSClientServerBookTest e
         //note '%21' instead of '!'
         String expected = "[/bookstore/booksubresource/123/chapters/sub/1/matched%21uris, "
             + "/bookstore/booksubresource/123/chapters/sub/1/, "
-            + "/bookstore/booksubresource/123/]";
+            + "/bookstore/booksubresource/123/, "
+            + "/bookstore]";
         getAndCompare("http://localhost:" + PORT + "/bookstore/"
                       + "booksubresource/123/chapters/sub/1/matched%21uris?decode=false", 
                       expected,
@@ -2058,7 +2080,9 @@ public class JAXRSClientServerBookTest e
 
         String endpointAddress =
             "http://localhost:" + PORT + "/bookstore/quotedheaders";
-        Response r = WebClient.create(endpointAddress).get();
+        WebClient wc = WebClient.create(endpointAddress);
+        WebClient.getConfig(wc).getRequestContext().put("org.apache.cxf.http.header.split", true);
+        Response r = wc.get();
 
         List<Object> header1 = r.getMetadata().get("SomeHeader1");
         assertEquals(1, header1.size());
@@ -2095,13 +2119,17 @@ public class JAXRSClientServerBookTest e
         // technically speaking, for these test cases, the client should return an error
         // however, servers do send bad data from time to time so we try to be forgiving
         for (int i = 0; i < 3; i++) {
-            Response r = WebClient.create(endpointAddress).query("type", Integer.toString(i)).get();
+            WebClient wc = WebClient.create(endpointAddress);
+            WebClient.getConfig(wc).getRequestContext().put("org.apache.cxf.http.header.split", true);
+            Response r = wc.query("type", Integer.toString(i)).get();
             assertEquals(responses[i], r.getMetadata().get("SomeHeader" + i).get(0));
         }
 
         // this test currently returns the WRONG result per RFC2616, however it is correct
         // per the discussion in CXF-3518
-        Response r3 = WebClient.create(endpointAddress).query("type", "3").get();
+        WebClient wc = WebClient.create(endpointAddress);
+        WebClient.getConfig(wc).getRequestContext().put("org.apache.cxf.http.header.split", true);
+        Response r3 = wc.query("type", "3").get();
         List<Object> r3values = r3.getMetadata().get("SomeHeader3");
         assertEquals(4, r3values.size());
         assertEquals("some text", r3values.get(0));