diff --git a/reactor-netty-http/src/main/java/reactor/netty/http/client/HttpClientOperations.java b/reactor-netty-http/src/main/java/reactor/netty/http/client/HttpClientOperations.java index 08ac18720f..b1f9cf72f7 100644 --- a/reactor-netty-http/src/main/java/reactor/netty/http/client/HttpClientOperations.java +++ b/reactor-netty-http/src/main/java/reactor/netty/http/client/HttpClientOperations.java @@ -20,7 +20,9 @@ import java.net.URISyntaxException; import java.nio.channels.ClosedChannelException; import java.time.Duration; +import java.util.ArrayList; import java.util.Collections; +import java.util.List; import java.util.Map; import java.util.Objects; import java.util.Set; @@ -110,6 +112,7 @@ class HttpClientOperations extends HttpOperations final HttpHeaders requestHeaders; final ClientCookieEncoder cookieEncoder; final ClientCookieDecoder cookieDecoder; + final List cookieList; final Sinks.One trailerHeaders; Supplier[] redirectedFrom = EMPTY_REDIRECTIONS; @@ -148,6 +151,7 @@ class HttpClientOperations extends HttpOperations this.requestHeaders = replaced.requestHeaders; this.cookieEncoder = replaced.cookieEncoder; this.cookieDecoder = replaced.cookieDecoder; + this.cookieList = replaced.cookieList; this.resourceUrl = replaced.resourceUrl; this.path = replaced.path; this.responseTimeout = replaced.responseTimeout; @@ -169,14 +173,14 @@ class HttpClientOperations extends HttpOperations this.requestHeaders = nettyRequest.headers(); this.cookieDecoder = decoder; this.cookieEncoder = encoder; + this.cookieList = new ArrayList<>(); this.trailerHeaders = Sinks.unsafe().one(); } @Override public HttpClientRequest addCookie(Cookie cookie) { if (!hasSentHeaders()) { - this.requestHeaders.add(HttpHeaderNames.COOKIE, - cookieEncoder.encode(cookie)); + this.cookieList.add(cookie); } else { throw new IllegalStateException("Status and headers already sent"); @@ -591,6 +595,10 @@ protected void afterMarkSentHeaders() { @Override protected void beforeMarkSentHeaders() { + if (!cookieList.isEmpty()) { + requestHeaders.add(HttpHeaderNames.COOKIE, cookieEncoder.encode(cookieList)); + } + if (redirectedFrom.length > 0) { if (redirectRequestConsumer != null) { redirectRequestConsumer.accept(this); diff --git a/reactor-netty-http/src/test/java/reactor/netty/http/HttpCookieHandlingTests.java b/reactor-netty-http/src/test/java/reactor/netty/http/HttpCookieHandlingTests.java index 711635c5ef..b964639951 100644 --- a/reactor-netty-http/src/test/java/reactor/netty/http/HttpCookieHandlingTests.java +++ b/reactor-netty-http/src/test/java/reactor/netty/http/HttpCookieHandlingTests.java @@ -17,11 +17,13 @@ import java.time.Duration; import java.util.Collection; +import java.util.List; import java.util.Map; import java.util.Set; import java.util.function.Function; import io.netty.handler.codec.http.HttpHeaderNames; +import io.netty.handler.codec.http.HttpMethod; import io.netty.handler.codec.http.cookie.ClientCookieDecoder; import io.netty.handler.codec.http.cookie.ClientCookieEncoder; import io.netty.handler.codec.http.cookie.Cookie; @@ -164,4 +166,38 @@ private void doTestServerCookiesDecodingMultipleCookiesSameName( .expectComplete() .verify(Duration.ofSeconds(5)); } + + @Test + void testIssue2983() { + disposableServer = + createServer() + .handle((req, res) -> { + List cookies = req.requestHeaders().getAll(HttpHeaderNames.COOKIE); + return cookies.size() == 1 ? res.sendString(Mono.just(cookies.get(0))) : + res.sendString(Mono.just("ERROR")); + }) + .bindNow(); + + createClient(disposableServer.port()) + .request(HttpMethod.GET) + .uri("/") + .send((req, out) -> { + Cookie cookie1 = new DefaultCookie("testIssue2983_1", "1"); + cookie1.setPath("/"); + Cookie cookie2 = new DefaultCookie("testIssue2983_2", "2"); + cookie2.setPath("/2"); + Cookie cookie3 = new DefaultCookie("testIssue2983_3", "3"); + req.addCookie(cookie1) + .addCookie(cookie2) + .addCookie(cookie3); + return out; + }) + .responseContent() + .aggregate() + .asString() + .as(StepVerifier::create) + .expectNext("testIssue2983_3=3; testIssue2983_2=2; testIssue2983_1=1") + .expectComplete() + .verify(Duration.ofSeconds(5)); + } } \ No newline at end of file