Skip to content

Commit 05d9166

Browse files
committed
Add test for HTTP authentication state propagation
Signed-off-by: raccoonback <[email protected]>
1 parent fbbd3dc commit 05d9166

File tree

1 file changed

+75
-0
lines changed

1 file changed

+75
-0
lines changed

reactor-netty-http/src/test/java/reactor/netty/http/client/HttpClientOperationsTest.java

Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -197,13 +197,15 @@ void testConstructorWithProvidedReplacement_1() {
197197
ops1.retrying = true;
198198
ops1.redirecting = new RedirectClientException(new DefaultHttpHeaders().add(HttpHeaderNames.LOCATION, "/"),
199199
HttpResponseStatus.MOVED_PERMANENTLY);
200+
ops1.authenticating = new HttpClientAuthenticationException();
200201

201202
HttpClientOperations ops2 = new HttpClientOperations(ops1);
202203

203204
assertThat(ops1.channel()).isSameAs(ops2.channel());
204205
assertThat(ops1.started).isSameAs(ops2.started);
205206
assertThat(ops1.retrying).isSameAs(ops2.retrying);
206207
assertThat(ops1.redirecting).isSameAs(ops2.redirecting);
208+
assertThat(ops1.authenticating).isSameAs(ops2.authenticating);
207209
assertThat(ops1.redirectedFrom).isSameAs(ops2.redirectedFrom);
208210
assertThat(ops1.isSecure).isSameAs(ops2.isSecure);
209211
assertThat(ops1.nettyRequest).isSameAs(ops2.nettyRequest);
@@ -535,6 +537,7 @@ private static void checkRequest(HttpClientRequest request, HttpClientResponse r
535537
assertThat(req.isSecure).isSameAs(res.isSecure);
536538
assertThat(req.nettyRequest).isSameAs(res.nettyRequest);
537539
assertThat(req.followRedirectPredicate).isSameAs(res.followRedirectPredicate);
540+
assertThat(req.authenticationPredicate).isSameAs(res.authenticationPredicate);
538541
assertThat(req.requestHeaders).isSameAs(res.requestHeaders);
539542
assertThat(req.cookieEncoder).isSameAs(res.cookieEncoder);
540543
assertThat(req.cookieDecoder).isSameAs(res.cookieDecoder);
@@ -555,6 +558,7 @@ private static void checkRequest(HttpClientRequest request, HttpClientResponse r
555558
else {
556559
assertThat(req.redirecting).isSameAs(res.redirecting);
557560
}
561+
assertThat(req.authenticating).isSameAs(res.authenticating);
558562
assertThat(req.responseState).isNotSameAs(res.responseState);
559563
assertThat(req.version).isNotSameAs(res.version);
560564
}
@@ -563,11 +567,82 @@ private static void checkRequest(HttpClientRequest request, HttpClientResponse r
563567
assertThat(req.asShortText()).isSameAs(res.asShortText());
564568
assertThat(req.started).isSameAs(res.started);
565569
assertThat(req.redirecting).isSameAs(res.redirecting);
570+
assertThat(req.authenticating).isSameAs(res.authenticating);
566571
assertThat(req.responseState).isSameAs(res.responseState);
567572
assertThat(req.version).isSameAs(res.version);
568573
}
569574
}
570575

576+
@ParameterizedTest
577+
@MethodSource("httpCompatibleProtocols")
578+
void testConstructorWithProvidedAuthentication(HttpProtocol[] serverProtocols, HttpProtocol[] clientProtocols,
579+
SslProvider.@Nullable ProtocolSslContextSpec serverCtx, SslProvider.@Nullable ProtocolSslContextSpec clientCtx) throws Exception {
580+
ConnectionProvider provider = ConnectionProvider.create("testConstructorWithProvidedReplacement_4", 1);
581+
try {
582+
HttpServer server = serverCtx == null ?
583+
createServer().protocol(serverProtocols) :
584+
createServer().protocol(serverProtocols).secure(spec -> spec.sslContext(serverCtx));
585+
586+
disposableServer =
587+
server.route(r -> r.get("/protected", (req, res) -> {
588+
String authHeader = req.requestHeaders().get(HttpHeaderNames.AUTHORIZATION);
589+
if (authHeader == null || !authHeader.equals("Bearer test-token")) {
590+
return res.status(HttpResponseStatus.UNAUTHORIZED).send();
591+
}
592+
return res.sendString(Mono.just("testConstructorWithProvidedReplacement_4"));
593+
}))
594+
.bindNow();
595+
596+
HttpClient client = clientCtx == null ?
597+
createClient(disposableServer.port()).protocol(clientProtocols) :
598+
createClient(disposableServer.port()).protocol(clientProtocols).secure(spec -> spec.sslContext(clientCtx));
599+
600+
AtomicReference<@Nullable HttpClientRequest> request = new AtomicReference<>();
601+
AtomicReference<@Nullable HttpClientResponse> response = new AtomicReference<>();
602+
AtomicReference<@Nullable Channel> requestChannel = new AtomicReference<>();
603+
AtomicReference<@Nullable Channel> responseChannel = new AtomicReference<>();
604+
AtomicReference<@Nullable ConnectionObserver> requestListener = new AtomicReference<>();
605+
AtomicReference<@Nullable ConnectionObserver> responseListener = new AtomicReference<>();
606+
String result = httpAuthentication(client, request, response, requestChannel, responseChannel,
607+
requestListener, responseListener);
608+
assertThat(result).isNotNull().isEqualTo("testConstructorWithProvidedReplacement_4");
609+
assertThat(requestListener.get()).isSameAs(responseListener.get());
610+
checkRequest(request.get(), response.get(), requestChannel.get(), responseChannel.get(), false, false);
611+
}
612+
finally {
613+
provider.disposeLater()
614+
.block(Duration.ofSeconds(5));
615+
}
616+
}
617+
618+
private static String httpAuthentication(HttpClient originalClient, AtomicReference<@Nullable HttpClientRequest> request,
619+
AtomicReference<@Nullable HttpClientResponse> response, AtomicReference<@Nullable Channel> requestChannel,
620+
AtomicReference<@Nullable Channel> responseChannel, AtomicReference<@Nullable ConnectionObserver> requestListener,
621+
AtomicReference<@Nullable ConnectionObserver> responseListener) {
622+
HttpClient client = originalClient.httpAuthentication((req, addr) -> {
623+
req.header(HttpHeaderNames.AUTHORIZATION, "Bearer test-token");
624+
return Mono.empty();
625+
});
626+
return client.doAfterRequest((req, conn) -> {
627+
if (request.get() == null) {
628+
requestChannel.set(conn.channel());
629+
requestListener.set(((HttpClientOperations) req).listener());
630+
request.set(req);
631+
}
632+
})
633+
.doAfterResponseSuccess((res, conn) -> {
634+
if (response.get() == null) {
635+
responseChannel.set(conn.channel());
636+
responseListener.set(((HttpClientOperations) res).listener());
637+
response.set(res);
638+
}
639+
})
640+
.get()
641+
.uri("/protected")
642+
.responseSingle((res, bytes) -> bytes.asString())
643+
.block(Duration.ofSeconds(5));
644+
}
645+
571646
static Stream<Arguments> httpCompatibleProtocols() {
572647
return Stream.of(
573648
Arguments.of(new HttpProtocol[]{HttpProtocol.HTTP11}, new HttpProtocol[]{HttpProtocol.HTTP11}, null, null),

0 commit comments

Comments
 (0)