From 400776d150a7e0e445ea361a8b50096a936071e1 Mon Sep 17 00:00:00 2001 From: Jaycee Li Date: Thu, 14 May 2026 16:20:43 -0700 Subject: [PATCH] fix: request URL is incorrectly rewritten when baseUrl is configured as a proxy address PiperOrigin-RevId: 915672634 --- src/main/java/com/google/genai/ApiClient.java | 19 ++++-- .../java/com/google/genai/ClientTest.java | 61 ++++++++++++++++--- 2 files changed, 69 insertions(+), 11 deletions(-) diff --git a/src/main/java/com/google/genai/ApiClient.java b/src/main/java/com/google/genai/ApiClient.java index 22448bce54e..67321d21c18 100644 --- a/src/main/java/com/google/genai/ApiClient.java +++ b/src/main/java/com/google/genai/ApiClient.java @@ -461,13 +461,24 @@ protected Request buildRequest( try { URI originalUri = new URI(url); URI baseUri = new URI(mergedHttpOptions.baseUrl().get()); + + String baseUriPath = baseUri.getRawPath() != null ? baseUri.getRawPath() : ""; + String originalUriPath = originalUri.getRawPath() != null ? originalUri.getRawPath() : ""; + + String combinedPath; + if (baseUriPath.endsWith("/") && originalUriPath.startsWith("/")) { + combinedPath = baseUriPath + originalUriPath.substring(1); + } else { + combinedPath = baseUriPath + originalUriPath; + } + finalUrl = new URI( baseUri.getScheme(), - baseUri.getAuthority(), - originalUri.getPath(), - originalUri.getQuery(), - originalUri.getFragment()) + baseUri.getRawAuthority(), + combinedPath, + originalUri.getRawQuery(), + originalUri.getRawFragment()) .toString(); } catch (URISyntaxException e) { logger.warning("Failed to rewrite upload URL with base URL: " + e.getMessage()); diff --git a/src/test/java/com/google/genai/ClientTest.java b/src/test/java/com/google/genai/ClientTest.java index 2b735fe7d8d..c6a170ee673 100644 --- a/src/test/java/com/google/genai/ClientTest.java +++ b/src/test/java/com/google/genai/ClientTest.java @@ -20,19 +20,15 @@ import static org.junit.jupiter.api.Assertions.assertFalse; import static org.junit.jupiter.api.Assertions.assertThrows; import static org.junit.jupiter.api.Assertions.assertTrue; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.when; -import org.mockito.MockedStatic; -import org.mockito.Mockito; import com.google.auth.oauth2.GoogleCredentials; import com.google.common.collect.ImmutableMap; import com.google.genai.types.HttpOptions; -import java.lang.reflect.Field; import java.util.Optional; -import okhttp3.OkHttpClient; +import java.util.concurrent.CompletableFuture; import org.junit.jupiter.api.Test; - +import org.mockito.MockedStatic; +import org.mockito.Mockito; public class ClientTest { private static final String API_KEY = "api-key"; @@ -365,4 +361,55 @@ void defaultIsFalse_whenNoFlagsOrEnvsAreSet() { assertFalse(client.vertexAI()); } } + + static class TestApiClient extends ApiClient { + TestApiClient(HttpOptions httpOptions) { + super(Optional.of("dummy-api-key"), Optional.of(httpOptions), Optional.empty()); + } + + @Override + public ApiResponse request( + String httpMethod, String path, String requestJson, Optional httpOptions) { + return null; + } + + @Override + public ApiResponse request( + String httpMethod, String path, byte[] requestBytes, Optional httpOptions) { + return null; + } + + @Override + public CompletableFuture asyncRequest( + String httpMethod, String path, String requestJson, Optional httpOptions) { + return null; + } + + @Override + public CompletableFuture asyncRequest( + String httpMethod, String path, byte[] requestBytes, Optional httpOptions) { + return null; + } + + @Override + public void close() {} + } + + @Test + void testBuildRequest_preservesBaseUrlPath() throws Exception { + HttpOptions httpOptions = + HttpOptions.builder().baseUrl("http://my-proxy.company.com/api/Gemini/Proxy").build(); + TestApiClient client = new TestApiClient(httpOptions); + + okhttp3.Request request = + client.buildRequest( + "POST", + "https://generativelanguage.googleapis.com/upload/v1beta/files?upload_id=xxx", + new byte[0], + Optional.empty()); + + assertEquals( + "http://my-proxy.company.com/api/Gemini/Proxy/upload/v1beta/files?upload_id=xxx", + request.url().toString()); + } }