GH-3641: Handle duplicate cookies properly

Fixes https://github.com/spring-projects/spring-integration/issues/3641

When a duplicate cookie name appears in a request, an `IllegalStateException` is thrown.
The default `Collectors.toMap()` does not allow a duplicated keys.

* Handle `servletRequest.getCookies()` as a `MultiValueMap`
* Call `toSingleValueMap()` for the evaluation context variable to restore previous behavior.
The next major version must expose the `MultiValueMap` as is to give access to all cookies from end-user expressions
* Rework some HTTP tests to JUnit 5

**Cherry-pick to `5.4.x` & `5.3.x`**
This commit is contained in:
Anthony Schweigard
2021-10-08 22:35:46 -05:00
committed by Artem Bilan
parent 6c47593aef
commit 7e5fef9e45
7 changed files with 88 additions and 47 deletions

View File

@@ -19,11 +19,8 @@ package org.springframework.integration.http.inbound;
import java.io.IOException;
import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.function.Function;
import java.util.stream.Collectors;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
@@ -384,10 +381,13 @@ public abstract class HttpRequestHandlingEndpointSupport extends BaseHttpInbound
Cookie[] requestCookies = servletRequest.getCookies();
if (!ObjectUtils.isEmpty(requestCookies)) {
Map<String, Cookie> cookies =
Arrays.stream(requestCookies)
.collect(Collectors.toMap(Cookie::getName, Function.identity()));
evaluationContext.setVariable("cookies", cookies);
MultiValueMap<String, Cookie> cookies = new LinkedMultiValueMap<>(requestCookies.length);
for (Cookie requestCookie : requestCookies) {
cookies.add(requestCookie.getName(), requestCookie);
}
// TODO no toSingleValueMap() in the next major version
evaluationContext.setVariable("cookies", cookies.toSingleValueMap());
}
Map<?, ?> pathVariables =
@@ -500,7 +500,7 @@ public abstract class HttpRequestHandlingEndpointSupport extends BaseHttpInbound
return new RequestEntity<>(requestBody, request.getHeaders(), request.getMethod(), request.getURI());
}
@SuppressWarnings({"unchecked", "rawtypes"})
@SuppressWarnings({ "unchecked", "rawtypes" })
protected Object extractRequestBody(ServletServerHttpRequest request) throws IOException {
MediaType contentType = request.getHeaders().getContentType();
if (contentType == null) {