diff --git a/CHANGELOG.md b/CHANGELOG.md index 4f8df02..6c9f67c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,18 +1,36 @@ # Changelog + All notable changes to this project will be documented in this file. ## [Unreleased](https://github.com/nstdio/http-client-ext/compare/v2.1.3...HEAD) +### ⭐ Features + +- Flag to disable insecure HTTP requests via + ExtendedHttpClient. ([bfbdcac](https://github.com/nstdio/http-client-ext/commit/bfbdcacb07e49ab460cd27cef66b329cd19222a6)) + +### ♻️ Improvements + +- Reformat code. ([e9ac5c9](https://github.com/nstdio/http-client-ext/commit/e9ac5c939c0c28d946af9b188c83578f190e5dac)) + ## [v2.1.3](https://github.com/nstdio/http-client-ext/compare/v2.1.2...v2.1.3) -### ⭐ Features - - Cache interface now extends Closeable ([2e9076a](https://github.com/nstdio/http-client-ext/commit/2e9076a7ae337c55c5817d15ddab9c8e9e3e5bb5)) +### ⭐ Features + +- Cache interface now extends + Closeable ([2e9076a](https://github.com/nstdio/http-client-ext/commit/2e9076a7ae337c55c5817d15ddab9c8e9e3e5bb5)) + ### ♻️ Improvements - - Improve cache write. ([b7f1289](https://github.com/nstdio/http-client-ext/commit/b7f128900372ee033aaef79b11ab09ed65f5c0ce)) + +- Improve cache + write. ([b7f1289](https://github.com/nstdio/http-client-ext/commit/b7f128900372ee033aaef79b11ab09ed65f5c0ce)) + ## [v2.1.2](https://github.com/nstdio/http-client-ext/compare/v2.1.1...v2.1.2) -### 🐞 Bug Fixes - - NPE when no `Content-Encoding` header present. ([b3afc61](https://github.com/nstdio/http-client-ext/commit/b3afc610c593024c013185ba93a3a3e7988bd9ca)) +### 🐞 Bug Fixes + +- NPE when no `Content-Encoding` header + present. ([b3afc61](https://github.com/nstdio/http-client-ext/commit/b3afc610c593024c013185ba93a3a3e7988bd9ca)) ### ♻️ Improvements - **perf** Tune decompression performance. ([1c3c581](https://github.com/nstdio/http-client-ext/commit/1c3c581f52db95cf4d88bc6dcea9e420b3015b5f)) ## [v2.1.1](https://github.com/nstdio/http-client-ext/compare/v2.1.0...v2.1.1) diff --git a/buildSrc/build.gradle.kts b/buildSrc/build.gradle.kts index 45790c2..2456420 100644 --- a/buildSrc/build.gradle.kts +++ b/buildSrc/build.gradle.kts @@ -38,7 +38,3 @@ dependencies { } implementation("com.github.spotbugs.snom:spotbugs-gradle-plugin:5.0.6") } - -kotlinDslPluginOptions { - jvmTarget.set(provider { java.targetCompatibility.toString() }) -} diff --git a/src/main/java/io/github/nstdio/http/ext/ExtendedHttpClient.java b/src/main/java/io/github/nstdio/http/ext/ExtendedHttpClient.java index f7f84bd..587e303 100644 --- a/src/main/java/io/github/nstdio/http/ext/ExtendedHttpClient.java +++ b/src/main/java/io/github/nstdio/http/ext/ExtendedHttpClient.java @@ -45,15 +45,17 @@ public class ExtendedHttpClient extends HttpClient { private final CachingInterceptor cachingInterceptor; private final HttpClient delegate; + private final boolean allowInsecure; ExtendedHttpClient(HttpClient delegate, Cache cache, Clock clock) { - this(delegate, cache, false, clock); + this(delegate, cache, false, true, clock); } - ExtendedHttpClient(HttpClient delegate, Cache cache, boolean transparentEncoding, Clock clock) { + ExtendedHttpClient(HttpClient delegate, Cache cache, boolean transparentEncoding, boolean allowInsecure, Clock clock) { this.delegate = delegate; this.cachingInterceptor = cache instanceof NullCache ? null : new CachingInterceptor(cache, clock); this.compressionInterceptor = transparentEncoding ? new CompressionInterceptor() : null; + this.allowInsecure = allowInsecure; } /** @@ -160,6 +162,10 @@ public CompletableFuture> sendAsync(HttpRequest request, Bod } private CompletableFuture> send0(HttpRequest request, BodyHandler bodyHandler, Sender sender) { + if (!allowInsecure && "http".equalsIgnoreCase(request.uri().getScheme())) { + throw new IllegalArgumentException("Client does not allow insecure HTTP requests."); + } + Chain chain = buildAndExecute(RequestContext.of(request, bodyHandler)); FutureHandler handler = chain.futureHandler(); @@ -223,6 +229,7 @@ interface Sender extends Function) { //given val request = HttpRequest.newBuilder().uri(URI.create("https://example.com")).build() - given(mockHttpClient.send(any(), any>())).willThrow(th) + given(mockDelegate.send(any(), any>())).willThrow(th) //when + then assertThatExceptionOfType(th) @@ -75,7 +75,7 @@ internal class ExtendedHttpClientTest { fun `Should throw CompletionException with cause`(th: Throwable) { //given val request = HttpRequest.newBuilder().uri(URI.create("https://example.com")).build() - given(mockHttpClient.send(any(), any>())).willThrow(th) + given(mockDelegate.send(any(), any>())).willThrow(th) //when + then @@ -98,17 +98,35 @@ internal class ExtendedHttpClientTest { client.newWebSocketBuilder() //then - val inOrder = inOrder(mockHttpClient) - inOrder.verify(mockHttpClient).cookieHandler() - inOrder.verify(mockHttpClient).connectTimeout() - inOrder.verify(mockHttpClient).followRedirects() - inOrder.verify(mockHttpClient).proxy() - inOrder.verify(mockHttpClient).sslContext() - inOrder.verify(mockHttpClient).sslParameters() - inOrder.verify(mockHttpClient).authenticator() - inOrder.verify(mockHttpClient).version() - inOrder.verify(mockHttpClient).executor() - inOrder.verify(mockHttpClient).newWebSocketBuilder() + val inOrder = inOrder(mockDelegate) + inOrder.verify(mockDelegate).cookieHandler() + inOrder.verify(mockDelegate).connectTimeout() + inOrder.verify(mockDelegate).followRedirects() + inOrder.verify(mockDelegate).proxy() + inOrder.verify(mockDelegate).sslContext() + inOrder.verify(mockDelegate).sslParameters() + inOrder.verify(mockDelegate).authenticator() + inOrder.verify(mockDelegate).version() + inOrder.verify(mockDelegate).executor() + inOrder.verify(mockDelegate).newWebSocketBuilder() + } + + @Test + fun `Should not allow insecure requests`() { + //given + val mockBuilderDelegate = mock(HttpClient.Builder::class.java) + given(mockBuilderDelegate.build()).willReturn(mockDelegate) + + client = Builder(mockBuilderDelegate) + .allowInsecure(false) + .build() + + val request = HttpRequest.newBuilder("HTTP://abc.local".toUri()).build() + + //when + then + shouldThrowExactly { + client.send(request, ofString()) + } } @Nested