From 1c09bb328246411b49da8d8e8f929046695bd13e Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 15 Sep 2026 21:09:07 +0000 Subject: [PATCH 1/4] chore(deps): Bump org.apache.httpcomponents.client5:httpclient5 Bumps [org.apache.httpcomponents.client5:httpclient5](https://github.com/apache/httpcomponents-client) from 5.3.1 to 5.6.3. - [Changelog](https://github.com/apache/httpcomponents-client/blob/rel/v5.6.3/RELEASE_NOTES.txt) - [Commits](https://github.com/apache/httpcomponents-client/compare/rel/v5.3.1...rel/v5.6.3) --- updated-dependencies: - dependency-name: org.apache.httpcomponents.client5:httpclient5 dependency-version: 5.6.3 dependency-type: direct:production ... Signed-off-by: dependabot[bot] --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 969987fe2..0e98d71fb 100644 --- a/pom.xml +++ b/pom.xml @@ -444,7 +444,7 @@ org.apache.httpcomponents.client5 httpclient5 - 5.3.1 + 5.6.3 com.nimbusds From a16041463e1759693682dbde4851d570c72076e7 Mon Sep 17 00:00:00 2001 From: Lahiru Maramba Date: Tue, 15 Sep 2026 18:32:32 -0400 Subject: [PATCH 2/4] test: use ServerBootstrap to construct test HttpServer --- .../internal/ApacheHttp2TransportTest.java | 46 ++++++++----------- 1 file changed, 19 insertions(+), 27 deletions(-) diff --git a/src/test/java/com/google/firebase/internal/ApacheHttp2TransportTest.java b/src/test/java/com/google/firebase/internal/ApacheHttp2TransportTest.java index ba604d3d1..d3a8f2587 100644 --- a/src/test/java/com/google/firebase/internal/ApacheHttp2TransportTest.java +++ b/src/test/java/com/google/firebase/internal/ApacheHttp2TransportTest.java @@ -58,10 +58,9 @@ import org.apache.hc.core5.http.HttpStatus; import org.apache.hc.core5.http.Message; import org.apache.hc.core5.http.impl.bootstrap.HttpServer; -import org.apache.hc.core5.http.impl.io.HttpService; +import org.apache.hc.core5.http.impl.bootstrap.ServerBootstrap; import org.apache.hc.core5.http.io.HttpRequestHandler; import org.apache.hc.core5.http.io.entity.ByteArrayEntity; -import org.apache.hc.core5.http.io.support.BasicHttpServerRequestHandler; import org.apache.hc.core5.http.message.BasicHttpResponse; import org.apache.hc.core5.http.nio.AsyncPushConsumer; import org.apache.hc.core5.http.nio.AsyncRequestProducer; @@ -434,31 +433,24 @@ public HttpRequestHandler resolve(HttpRequest request, HttpContext context) return httpHandler; } }; - server = new HttpServer( - 0, - HttpService.builder() - .withHttpProcessor( - new HttpProcessor() { - @Override - public void process( - HttpRequest request, EntityDetails entity, HttpContext context) - throws HttpException, IOException { - } - - @Override - public void process( - HttpResponse response, EntityDetails entity, HttpContext context) - throws HttpException, IOException { - } - }) - .withHttpServerRequestHandler(new BasicHttpServerRequestHandler(mapper)) - .build(), - null, - null, - null, - null, - null, - null); + server = ServerBootstrap.bootstrap() + .setListenerPort(0) + .setHttpProcessor( + new HttpProcessor() { + @Override + public void process( + HttpRequest request, EntityDetails entity, HttpContext context) + throws HttpException, IOException { + } + + @Override + public void process( + HttpResponse response, EntityDetails entity, HttpContext context) + throws HttpException, IOException { + } + }) + .setRequestRouter(mapper) + .create(); server.start(); } From 842c22d4fc00615ccaa89ac5032401c23d951332 Mon Sep 17 00:00:00 2001 From: Lahiru Maramba Date: Wed, 16 Sep 2026 16:29:28 -0400 Subject: [PATCH 3/4] fix(transport): Enforce read timeout on HTTP/2 requests in ApacheHttp2Request --- .../firebase/internal/ApacheHttp2Request.java | 11 ++++++- .../internal/ApacheHttp2TransportTest.java | 33 +++++++++++++++++++ 2 files changed, 43 insertions(+), 1 deletion(-) diff --git a/src/main/java/com/google/firebase/internal/ApacheHttp2Request.java b/src/main/java/com/google/firebase/internal/ApacheHttp2Request.java index ceb213c52..b06692ee8 100644 --- a/src/main/java/com/google/firebase/internal/ApacheHttp2Request.java +++ b/src/main/java/com/google/firebase/internal/ApacheHttp2Request.java @@ -49,6 +49,7 @@ final class ApacheHttp2Request extends LowLevelHttpRequest { private SimpleHttpRequest request; private final RequestConfig.Builder requestConfig; private int writeTimeout; + private int readTimeout; private ApacheHttp2AsyncEntityProducer entityProducer; private ApacheHttp2AsyncEntityConsumer entityConsumer; @@ -57,6 +58,7 @@ final class ApacheHttp2Request extends LowLevelHttpRequest { this.httpAsyncClient = httpAsyncClient; this.requestBuilder = requestBuilder; this.writeTimeout = 0; + this.readTimeout = 0; this.requestConfig = RequestConfig.custom() .setRedirectsEnabled(false); @@ -69,6 +71,7 @@ public void addHeader(String name, String value) { @Override public void setTimeout(int connectionTimeout, int readTimeout) throws IOException { + this.readTimeout = readTimeout; requestConfig .setConnectTimeout(Timeout.ofMilliseconds(connectionTimeout)) .setResponseTimeout(Timeout.ofMilliseconds(readTimeout)); @@ -125,7 +128,10 @@ public void cancelled() { // Wait for response try { - final Message response = responseFuture.get(); + final Message response = + readTimeout > 0 + ? responseFuture.get(readTimeout, TimeUnit.MILLISECONDS) + : responseFuture.get(); return new ApacheHttp2Response(response); } catch (ExecutionException e) { if (e.getCause() instanceof ConnectTimeoutException @@ -142,6 +148,9 @@ public void cancelled() { throw new IOException("Request Interrupted", e); } catch (CancellationException e) { throw new IOException("Request Cancelled", e); + } catch (TimeoutException e) { + responseFuture.cancel(true); + throw new IOException("Stream exception in request", e); } } diff --git a/src/test/java/com/google/firebase/internal/ApacheHttp2TransportTest.java b/src/test/java/com/google/firebase/internal/ApacheHttp2TransportTest.java index d3a8f2587..f8ad47026 100644 --- a/src/test/java/com/google/firebase/internal/ApacheHttp2TransportTest.java +++ b/src/test/java/com/google/firebase/internal/ApacheHttp2TransportTest.java @@ -422,6 +422,39 @@ public void handle( } } + @Test + public void testReadTimeout() throws Exception { + final HttpRequestHandler handler = new HttpRequestHandler() { + @Override + public void handle( + ClassicHttpRequest request, ClassicHttpResponse response, HttpContext context) + throws HttpException, IOException { + try { + Thread.sleep(1000L); + } catch (InterruptedException e) { + Thread.currentThread().interrupt(); + } + response.setCode(HttpStatus.SC_OK); + } + }; + + try (FakeServer server = new FakeServer(handler)) { + HttpTransport transport = new ApacheHttp2Transport(); + GenericUrl testUrl = new GenericUrl("http://localhost/timeout"); + testUrl.setPort(server.getPort()); + com.google.api.client.http.HttpRequest request = transport.createRequestFactory() + .buildGetRequest(testUrl); + request.setReadTimeout(100); + + try { + request.execute(); + Assert.fail("Expected IOException on read timeout"); + } catch (IOException e) { + assertEquals("Stream exception in request", e.getMessage()); + } + } + } + private static class FakeServer implements AutoCloseable { private final HttpServer server; From 5be629ffbca68d11c62af18f3b2af66f8af7398a Mon Sep 17 00:00:00 2001 From: Lahiru Maramba Date: Wed, 16 Sep 2026 16:39:24 -0400 Subject: [PATCH 4/4] test: simplify FakeServer HttpProcessor using HttpProcessorBuilder --- .../internal/ApacheHttp2TransportTest.java | 17 ++--------------- 1 file changed, 2 insertions(+), 15 deletions(-) diff --git a/src/test/java/com/google/firebase/internal/ApacheHttp2TransportTest.java b/src/test/java/com/google/firebase/internal/ApacheHttp2TransportTest.java index f8ad47026..e6d80847a 100644 --- a/src/test/java/com/google/firebase/internal/ApacheHttp2TransportTest.java +++ b/src/test/java/com/google/firebase/internal/ApacheHttp2TransportTest.java @@ -67,7 +67,7 @@ import org.apache.hc.core5.http.nio.AsyncResponseConsumer; import org.apache.hc.core5.http.nio.HandlerFactory; import org.apache.hc.core5.http.protocol.HttpContext; -import org.apache.hc.core5.http.protocol.HttpProcessor; +import org.apache.hc.core5.http.protocol.HttpProcessorBuilder; import org.junit.Assert; import org.junit.Test; @@ -468,20 +468,7 @@ public HttpRequestHandler resolve(HttpRequest request, HttpContext context) }; server = ServerBootstrap.bootstrap() .setListenerPort(0) - .setHttpProcessor( - new HttpProcessor() { - @Override - public void process( - HttpRequest request, EntityDetails entity, HttpContext context) - throws HttpException, IOException { - } - - @Override - public void process( - HttpResponse response, EntityDetails entity, HttpContext context) - throws HttpException, IOException { - } - }) + .setHttpProcessor(HttpProcessorBuilder.create().build()) .setRequestRouter(mapper) .create(); server.start();