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));