From c17f1f34251f6402f436259fa7635087428c6fcb Mon Sep 17 00:00:00 2001 From: Microsoft Graph DevX Tooling Date: Tue, 14 Jul 2026 16:32:57 -0700 Subject: [PATCH] Upgrade OkHttp from 4.12.0 to 5.4.0 - Bump okhttp version in gradle/libs.versions.toml (covers okhttp, logging-interceptor and mockwebserver via the shared version ref). - RedirectHandler: replace removed okhttp3.internal.http.StatusLine constants (HTTP_PERM_REDIRECT/HTTP_TEMP_REDIRECT) with local 308/307 constants, as that internal class is no longer exposed in OkHttp 5. - OkHttpRequestAdapterTest: OkHttp 5 Response.Builder.body is non-null, so drop .body(null) calls. Split the stream no-content test: 204/304 still return null; 200-203 with an empty body now yield a non-null empty stream (matching real OkHttp behavior, production code unchanged). Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 0b74528e-656e-4569-bb55-b833bbf51344 --- .../http/middleware/RedirectHandler.java | 7 ++-- .../kiota/http/OkHttpRequestAdapterTest.java | 35 +++++++++++++++++-- gradle/libs.versions.toml | 2 +- 3 files changed, 37 insertions(+), 7 deletions(-) diff --git a/components/http/okHttp/src/main/java/com/microsoft/kiota/http/middleware/RedirectHandler.java b/components/http/okHttp/src/main/java/com/microsoft/kiota/http/middleware/RedirectHandler.java index 543109ae..8353ac7a 100644 --- a/components/http/okHttp/src/main/java/com/microsoft/kiota/http/middleware/RedirectHandler.java +++ b/components/http/okHttp/src/main/java/com/microsoft/kiota/http/middleware/RedirectHandler.java @@ -1,8 +1,5 @@ package com.microsoft.kiota.http.middleware; -import static okhttp3.internal.http.StatusLine.HTTP_PERM_REDIRECT; -import static okhttp3.internal.http.StatusLine.HTTP_TEMP_REDIRECT; - import static java.net.HttpURLConnection.HTTP_MOVED_PERM; import static java.net.HttpURLConnection.HTTP_MOVED_TEMP; import static java.net.HttpURLConnection.HTTP_SEE_OTHER; @@ -28,6 +25,10 @@ * Middleware that determines whether a redirect information should be followed or not, and follows it if necessary. */ public class RedirectHandler implements Interceptor { + // 308 Permanent Redirect and 307 Temporary Redirect, previously sourced from + // okhttp3.internal.http.StatusLine which is no longer exposed in OkHttp 5. + private static final int HTTP_PERM_REDIRECT = 308; + private static final int HTTP_TEMP_REDIRECT = 307; @Nonnull private final RedirectHandlerOption mRedirectOption; @Nullable private final java.net.ProxySelector mProxySelector; diff --git a/components/http/okHttp/src/test/java/com/microsoft/kiota/http/OkHttpRequestAdapterTest.java b/components/http/okHttp/src/test/java/com/microsoft/kiota/http/OkHttpRequestAdapterTest.java index ec6ae90c..6d5b5a9e 100644 --- a/components/http/okHttp/src/test/java/com/microsoft/kiota/http/OkHttpRequestAdapterTest.java +++ b/components/http/okHttp/src/test/java/com/microsoft/kiota/http/OkHttpRequestAdapterTest.java @@ -124,7 +124,7 @@ void sendStreamReturnsUsableStream(int statusCode) throws Exception { } @ParameterizedTest - @ValueSource(ints = {200, 201, 202, 203, 204, 304}) + @ValueSource(ints = {204, 304}) void sendStreamReturnsNullOnNoContent(int statusCode) throws Exception { final var authenticationProviderMock = mock(AuthenticationProvider.class); authenticationProviderMock.authenticateRequest( @@ -136,7 +136,6 @@ void sendStreamReturnsNullOnNoContent(int statusCode) throws Exception { .message("OK") .protocol(Protocol.HTTP_1_1) .request(new Request.Builder().url("http://localhost").build()) - .body(null) .build()); final var requestAdapter = new OkHttpRequestAdapter(authenticationProviderMock, null, null, client); @@ -152,6 +151,37 @@ void sendStreamReturnsNullOnNoContent(int statusCode) throws Exception { assertNull(response); } + @ParameterizedTest + @ValueSource(ints = {200, 201, 202, 203}) + void sendStreamReturnsEmptyStreamOnEmptyBody(int statusCode) throws Exception { + // OkHttp 5 responses always carry a non-null (possibly empty) body, so a success + // response with an empty body yields an empty, non-null stream rather than null. + final var authenticationProviderMock = mock(AuthenticationProvider.class); + authenticationProviderMock.authenticateRequest( + any(RequestInformation.class), any(Map.class)); + final var client = + getMockClient( + new Response.Builder() + .code(statusCode) + .message("OK") + .protocol(Protocol.HTTP_1_1) + .request(new Request.Builder().url("http://localhost").build()) + .build()); + final var requestAdapter = + new OkHttpRequestAdapter(authenticationProviderMock, null, null, client); + final var requestInformation = + new RequestInformation() { + { + setUri(new URI("https://localhost")); + httpMethod = HttpMethod.GET; + } + }; + final var response = + requestAdapter.sendPrimitive(requestInformation, null, InputStream.class); + assertNotNull(response); + assertEquals(0, response.readAllBytes().length); + } + @ParameterizedTest @ValueSource(ints = {200, 201, 202, 203, 204, 205, 304}) void sendReturnsNullOnNoContent(int statusCode) throws Exception { @@ -165,7 +195,6 @@ void sendReturnsNullOnNoContent(int statusCode) throws Exception { .message("OK") .protocol(Protocol.HTTP_1_1) .request(new Request.Builder().url("http://localhost").build()) - .body(null) .build()); final var requestAdapter = new OkHttpRequestAdapter(authenticationProviderMock, null, null, client); diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index ddfab22b..179e0a24 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -1,5 +1,5 @@ [versions] -okhttp = "4.12.0" +okhttp = "5.4.0" opentelemetry = "1.64.0" [libraries]