Skip to content

Commit

Permalink
Merge #3596 into 1.2.3
Browse files Browse the repository at this point in the history
Signed-off-by: Violeta Georgieva <[email protected]>
  • Loading branch information
violetagg committed Jan 21, 2025
2 parents f8602f4 + 6762a8b commit 09ea6a1
Show file tree
Hide file tree
Showing 2 changed files with 79 additions and 25 deletions.
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2011-2024 VMware, Inc. or its affiliates, All Rights Reserved.
* Copyright (c) 2011-2025 VMware, Inc. or its affiliates, All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand Down Expand Up @@ -646,16 +646,19 @@ public final HttpClient cookiesWhen(String name, Function<? super Cookie, Mono<?
Objects.requireNonNull(name, "name");
Objects.requireNonNull(cookieBuilder, "cookieBuilder");
HttpClient dup = duplicate();
dup.configuration().deferredConf(config ->
cookieBuilder.apply(new DefaultCookie(name, ""))
.map(c -> {
if (!c.value().isEmpty()) {
HttpHeaders headers = configuration().headers.copy();
headers.add(HttpHeaderNames.COOKIE, config.cookieEncoder.encode(c));
config.headers = headers;
}
return config;
}));
dup.configuration().deferredConf(config -> {
Mono<? extends Cookie> mono = cookieBuilder.apply(new DefaultCookie(name, ""));
return mono == Mono.<Cookie>empty() ?
Mono.just(config) :
mono.map(c -> {
if (!c.value().isEmpty()) {
HttpHeaders headers = configuration().headers.copy();
headers.add(HttpHeaderNames.COOKIE, config.cookieEncoder.encode(c));
config.headers = headers;
}
return config;
});
});
return dup;
}

Expand Down Expand Up @@ -1079,12 +1082,15 @@ public final HttpClient headers(Consumer<? super HttpHeaders> headerBuilder) {
public final HttpClient headersWhen(Function<? super HttpHeaders, Mono<? extends HttpHeaders>> headerBuilder) {
Objects.requireNonNull(headerBuilder, "headerBuilder");
HttpClient dup = duplicate();
dup.configuration().deferredConf(config ->
headerBuilder.apply(config.headers.copy())
.map(h -> {
config.headers = h;
return config;
}));
dup.configuration().deferredConf(config -> {
Mono<? extends HttpHeaders> mono = headerBuilder.apply(config.headers.copy());
return mono == Mono.<HttpHeaders>empty() ?
Mono.just(config) :
mono.map(h -> {
config.headers = h;
return config;
});
});
return dup;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,7 @@
import io.netty.handler.codec.http.HttpResponseStatus;
import io.netty.handler.codec.http.HttpVersion;
import io.netty.handler.codec.http.LastHttpContent;
import io.netty.handler.codec.http.cookie.Cookie;
import io.netty.handler.logging.LogLevel;
import io.netty.handler.ssl.SslContext;
import io.netty.handler.ssl.SslContextBuilder;
Expand Down Expand Up @@ -872,24 +873,71 @@ void testDeferredUri() {
.blockLast(Duration.ofSeconds(5));
}

@Test
void testDeferredHeader() {
@ParameterizedTest
@ValueSource(booleans = {true, false})
void testDeferredCookie(boolean provideEmptyPublisher) {
disposableServer =
createServer()
.host("localhost")
.route(r -> r.get("/201", (req, res) -> res.addHeader("Content-Length", "0")
.status(HttpResponseStatus.CREATED)
.sendHeaders()))
.route(r -> r.get("/", (req, res) -> {
Set<Cookie> cookies = req.cookies().get("testDeferredCookie");
return cookies != null ?
res.sendString(Mono.just(cookies.iterator().next().value())) :
res.sendString(Mono.just("empty"));
}))
.bindNow();

createHttpClientForContextWithAddress()
.headersWhen(h -> Mono.just(h.set("test", "test")).delayElement(Duration.ofSeconds(2)))
.cookiesWhen("testDeferredCookie", cookie -> {
if (provideEmptyPublisher) {
return Mono.empty();
}
else {
cookie.setValue("testDeferredCookie");
return Mono.just(cookie).delayElement(Duration.ofMillis(100));
}
})
.get()
.uri("/")
.responseSingle((res, bytes) -> bytes.asString())
.as(StepVerifier::create)
.expectNextMatches(s -> provideEmptyPublisher ? "empty".equals(s) : "testDeferredCookie".equals(s))
.expectComplete()
.verify(Duration.ofSeconds(30));
}

@ParameterizedTest
@ValueSource(booleans = {true, false})
void testDeferredHeader(boolean provideEmptyPublisher) {
disposableServer =
createServer()
.host("localhost")
.route(r -> r.get("/201", (req, res) -> {
String header = req.requestHeaders().get("test");
if (header != null) {
res.addHeader("test", header);
}
return res.addHeader("Content-Length", "0")
.status(HttpResponseStatus.CREATED)
.sendHeaders();
}))
.bindNow();

createHttpClientForContextWithAddress()
.headersWhen(h -> provideEmptyPublisher ?
Mono.empty() :
Mono.just(h.set("test", "test")).delayElement(Duration.ofMillis(100)))
.observe((c, s) -> log.debug(s + "" + c))
.get()
.uri("/201")
.responseContent()
.responseSingle((res, bytes) -> Mono.just(res.responseHeaders().get("test", "empty")))
.repeat(4)
.blockLast(Duration.ofSeconds(30));
.collectList()
.as(StepVerifier::create)
.assertNext(l -> assertThat(l).hasSize(5).allMatch(s -> provideEmptyPublisher ?
"empty".equals(s) : "test".equals(s)))
.expectComplete()
.verify(Duration.ofSeconds(30));
}

@Test
Expand Down

0 comments on commit 09ea6a1

Please sign in to comment.