INT-3903: user prefix as "" for HTTP headers

JIRA: https://jira.spring.io/browse/INT-3903

According to RFC-6648, the "X-" prefix has been deprecated and now any use-specific headers can be mapped without any prefix

* Fix `DefaultHttpHeaderMapper` for the `""` as a `userDefinedHeaderPrefix` by default

Document `X-` changes
This commit is contained in:
Artem Bilan
2016-10-10 12:17:01 -04:00
committed by Gary Russell
parent f9e93e0a72
commit 53d80b5694
6 changed files with 48 additions and 33 deletions

View File

@@ -291,7 +291,7 @@ public class DefaultHttpHeaderMapper implements HeaderMapper<HttpHeaders>, BeanF
private volatile String[] excludedInboundStandardResponseHeaderNames = new String[0];
private volatile String userDefinedHeaderPrefix = "X-";
private volatile String userDefinedHeaderPrefix = "";
private volatile boolean isDefaultOutboundMapper;
@@ -384,7 +384,8 @@ public class DefaultHttpHeaderMapper implements HeaderMapper<HttpHeaders>, BeanF
}
/**
* Sets the prefix to use with user-defined (non-standard) headers. Default is 'X-'.
* Sets the prefix to use with user-defined (non-standard) headers. Default is an
* empty string.
* @param userDefinedHeaderPrefix The user defined header prefix.
*/
public void setUserDefinedHeaderPrefix(String userDefinedHeaderPrefix) {

View File

@@ -202,7 +202,7 @@ public class HttpInboundGatewayParserTests {
headers = new HttpHeaders();
headerMapper.fromHeaders(mh, headers);
assertTrue(headers.size() == 1);
List<String> abc = headers.get("X-abc");
List<String> abc = headers.get("abc");
assertEquals("abc", abc.get(0));
}
@@ -211,6 +211,8 @@ public class HttpInboundGatewayParserTests {
DefaultHttpHeaderMapper headerMapper =
(DefaultHttpHeaderMapper) TestUtils.getPropertyValue(withMappedHeadersAndConverter, "headerMapper");
headerMapper.setUserDefinedHeaderPrefix("X-");
HttpHeaders headers = new HttpHeaders();
headers.set("foo", "foo");
headers.set("bar", "bar");

View File

@@ -331,10 +331,10 @@ public class DefaultHttpHeaderMapperFromMessageInboundTests {
HttpHeaders headers = new HttpHeaders();
mapper.fromHeaders(new MessageHeaders(messageHeaders), headers);
assertEquals(2, headers.size());
assertEquals(1, headers.get("X-foo").size());
assertEquals("abc", headers.getFirst("X-foo"));
assertEquals(1, headers.get("X-bar").size());
assertEquals("123", headers.getFirst("X-bar"));
assertEquals(1, headers.get("foo").size());
assertEquals("abc", headers.getFirst("foo"));
assertEquals(1, headers.get("bar").size());
assertEquals("123", headers.getFirst("bar"));
}
@Test
@@ -356,18 +356,19 @@ public class DefaultHttpHeaderMapperFromMessageInboundTests {
assertNull(headers.get("z1"));
assertNull(headers.get("abc"));
assertNull(headers.get("def"));
assertEquals(1, headers.get("X-x1").size());
assertEquals("x1-value", headers.getFirst("X-x1"));
assertEquals(1, headers.get("X-1z").size());
assertEquals("1z-value", headers.getFirst("X-1z"));
assertEquals(1, headers.get("X-abcdef").size());
assertEquals("abcdef-value", headers.getFirst("X-abcdef"));
assertEquals(1, headers.get("x1").size());
assertEquals("x1-value", headers.getFirst("x1"));
assertEquals(1, headers.get("1z").size());
assertEquals("1z-value", headers.getFirst("1z"));
assertEquals(1, headers.get("abcdef").size());
assertEquals("abcdef-value", headers.getFirst("abcdef"));
}
@Test
public void validateCustomHeaderNamePatternsAndStandardResponseHeadersMappedToHttpHeaders() throws Exception {
DefaultHttpHeaderMapper mapper = new DefaultHttpHeaderMapper();
mapper.setOutboundHeaderNames(new String[] { "foo*", "HTTP_RESPONSE_HEADERS" });
mapper.setUserDefinedHeaderPrefix("X-");
Map<String, Object> messageHeaders = new HashMap<String, Object>();
messageHeaders.put("foobar", "abc");
messageHeaders.put("Accept", "text/html");
@@ -518,9 +519,9 @@ public class DefaultHttpHeaderMapperFromMessageInboundTests {
messageHeaders.put("customHeaderB", new TestClass());
mapper.fromHeaders(new MessageHeaders(messageHeaders), headers);
assertNotNull(headers.get("X-customHeaderA"));
assertEquals("123", headers.get("X-customHeaderA").get(0));
assertNull(headers.get("X-customHeaderB"));
assertNotNull(headers.get("customHeaderA"));
assertEquals("123", headers.get("customHeaderA").get(0));
assertNull(headers.get("customHeaderB"));
}
@Test
@@ -540,10 +541,10 @@ public class DefaultHttpHeaderMapperFromMessageInboundTests {
messageHeaders.put("customHeaderB", new TestClass());
mapper.fromHeaders(new MessageHeaders(messageHeaders), headers);
assertNotNull(headers.get("X-customHeaderA"));
assertEquals("123", headers.get("X-customHeaderA").get(0));
assertNotNull(headers.get("X-customHeaderB"));
assertEquals("TestClass.class", headers.get("X-customHeaderB").get(0));
assertNotNull(headers.get("customHeaderA"));
assertEquals("123", headers.get("customHeaderA").get(0));
assertNotNull(headers.get("customHeaderB"));
assertEquals("TestClass.class", headers.get("customHeaderB").get(0));
}
@Test

View File

@@ -571,10 +571,10 @@ public class DefaultHttpHeaderMapperFromMessageOutboundTests {
messageHeaders.put("foo", "foo");
HttpHeaders headers = new HttpHeaders();
mapper.fromHeaders(new MessageHeaders(messageHeaders), headers);
assertNull(headers.get("foo"));
assertNotNull(headers.get("X-foo"));
assertTrue(headers.get("X-foo").size() == 1);
assertEquals("foo", headers.get("X-foo").get(0));
assertNull(headers.get("X-foo"));
assertNotNull(headers.get("foo"));
assertTrue(headers.get("foo").size() == 1);
assertEquals("foo", headers.get("foo").get(0));
}
@Test
@@ -596,12 +596,12 @@ public class DefaultHttpHeaderMapperFromMessageOutboundTests {
assertNull(headers.get("z1"));
assertNull(headers.get("abc"));
assertNull(headers.get("def"));
assertEquals(1, headers.get("X-x1").size());
assertEquals("x1-value", headers.getFirst("X-x1"));
assertEquals(1, headers.get("X-1z").size());
assertEquals("1z-value", headers.getFirst("X-1z"));
assertEquals(1, headers.get("X-abcdef").size());
assertEquals("abcdef-value", headers.getFirst("X-abcdef"));
assertEquals(1, headers.get("x1").size());
assertEquals("x1-value", headers.getFirst("x1"));
assertEquals(1, headers.get("1z").size());
assertEquals("1z-value", headers.getFirst("1z"));
assertEquals(1, headers.get("abcdef").size());
assertEquals("abcdef-value", headers.getFirst("abcdef"));
}
@Test
@@ -615,8 +615,8 @@ public class DefaultHttpHeaderMapperFromMessageOutboundTests {
HttpHeaders headers = new HttpHeaders();
mapper.fromHeaders(new MessageHeaders(messageHeaders), headers);
assertEquals(3, headers.size());
assertEquals(1, headers.get("X-foobar").size());
assertEquals("abc", headers.getFirst("X-foobar"));
assertEquals(1, headers.get("foobar").size());
assertEquals("abc", headers.getFirst("foobar"));
assertEquals("text/html", headers.getContentType().toString());
assertEquals(1, headers.getAccept().size());
assertEquals(MediaType.TEXT_XML, headers.getAccept().get(0));
@@ -663,6 +663,7 @@ public class DefaultHttpHeaderMapperFromMessageOutboundTests {
public void validateCustomHeaderCaseInsensitivity() throws ParseException {
DefaultHttpHeaderMapper mapper = new DefaultHttpHeaderMapper();
mapper.setOutboundHeaderNames(new String[] {"*", "HTTP_REQUEST_HEADERS"});
mapper.setUserDefinedHeaderPrefix("X-");
Map<String, Object> messageHeaders = new HashMap<String, Object>();
messageHeaders.put("foobar", "abc");
messageHeaders.put("X-bar", "xbar");

View File

@@ -515,7 +515,7 @@ The configuration looks very similar to the gateway:
[NOTE]
=====
To specify the URL; you can use either the 'url' attribute or the 'url-expression' attribute.
The 'url' is a simple string (with placedholders for URI variables, as described below); the 'url-expression' is a SpEL expression, with the Message as the root object, enabling dynamic urls.
The 'url' is a simple string (with placeholders for URI variables, as described below); the 'url-expression' is a SpEL expression, with the Message as the root object, enabling dynamic urls.
The url resulting from the expression evaluation can still have placeholders for URI variables.
In previous releases, some users used the place holders to replace the entire URL with a URI variable.
@@ -774,6 +774,11 @@ The adapters and gateways will use the `DefaultHttpHeaderMapper` which now provi
If further customization is required you can also configure a `DefaultHttpHeaderMapper` independently and inject it into the adapter via the `header-mapper` attribute.
Before _version 5.0_, the `DefaultHttpHeaderMapper` the default prefix for user-defined, non-standard HTTP headers was `X-`.
In `_version 5.0_` this has been changed to an empty string.
According to https://tools.ietf.org/html/rfc6648[RFC-6648], the use of such prefixes is now discouraged.
This option can still be customized by setting the `DefaultHttpHeaderMapper.setUserDefinedHeaderPrefix()` property.
[source,xml]
----
<int-http:outbound-gateway id="httpGateway"

View File

@@ -60,3 +60,8 @@ See <<barrier>> for more information.
The AMQP outbound endpoints now support setting a delay expression for when using the RabbitMQ Delayed Message Exchange plugin.
See <<amqp-delay>> for more information.
==== HTTP Changes
The `DefaultHttpHeaderMapper.userDefinedHeaderPrefix` property is now an empty string by default instead of `X-`.
See <<http-header-mapping>> for more information.