1+ /*
2+ * Copyright 2024 Google Inc.
3+ *
4+ * Licensed under the Apache License, Version 2.0 (the "License");
5+ * you may not use this file except in compliance with the License.
6+ * You may obtain a copy of the License at
7+ *
8+ * http://www.apache.org/licenses/LICENSE-2.0
9+ *
10+ * Unless required by applicable law or agreed to in writing, software
11+ * distributed under the License is distributed on an "AS IS" BASIS,
12+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+ * See the License for the specific language governing permissions and
14+ * limitations under the License.
15+ */
16+
117package com .google .firebase .internal ;
218
319import com .google .api .client .http .LowLevelHttpRequest ;
420import com .google .api .client .http .LowLevelHttpResponse ;
21+ import com .google .common .annotations .VisibleForTesting ;
522
623import java .io .IOException ;
24+ import java .util .concurrent .CancellationException ;
725import java .util .concurrent .CompletableFuture ;
826import java .util .concurrent .ExecutionException ;
27+ import java .util .concurrent .Future ;
928import java .util .concurrent .TimeUnit ;
1029import java .util .concurrent .TimeoutException ;
1130
31+ import org .apache .hc .client5 .http .ConnectTimeoutException ;
1232import org .apache .hc .client5 .http .async .methods .SimpleHttpRequest ;
1333import org .apache .hc .client5 .http .async .methods .SimpleHttpResponse ;
1434import org .apache .hc .client5 .http .async .methods .SimpleRequestBuilder ;
1737import org .apache .hc .client5 .http .impl .async .CloseableHttpAsyncClient ;
1838import org .apache .hc .core5 .concurrent .FutureCallback ;
1939import org .apache .hc .core5 .http .nio .support .BasicRequestProducer ;
40+ import org .apache .hc .core5 .http2 .H2StreamResetException ;
2041import org .apache .hc .core5 .util .Timeout ;
2142
2243final class ApacheHttp2Request extends LowLevelHttpRequest {
@@ -25,6 +46,7 @@ final class ApacheHttp2Request extends LowLevelHttpRequest {
2546 private SimpleHttpRequest request ;
2647 private final RequestConfig .Builder requestConfig ;
2748 private int writeTimeout ;
49+ private ApacheHttp2AsyncEntityProducer entityProducer ;
2850
2951 ApacheHttp2Request (
3052 CloseableHttpAsyncClient httpAsyncClient , SimpleRequestBuilder requestBuilder ) {
@@ -33,7 +55,7 @@ final class ApacheHttp2Request extends LowLevelHttpRequest {
3355 this .writeTimeout = 0 ;
3456
3557 this .requestConfig = RequestConfig .custom ()
36- .setRedirectsEnabled (false );
58+ .setRedirectsEnabled (false );
3759 }
3860
3961 @ Override
@@ -42,11 +64,10 @@ public void addHeader(String name, String value) {
4264 }
4365
4466 @ Override
45- @ SuppressWarnings ("deprecation" )
4667 public void setTimeout (int connectionTimeout , int readTimeout ) throws IOException {
4768 requestConfig
48- .setConnectTimeout (Timeout .ofMilliseconds (connectionTimeout ))
49- .setResponseTimeout (Timeout .ofMilliseconds (readTimeout ));
69+ .setConnectTimeout (Timeout .ofMilliseconds (connectionTimeout ))
70+ .setResponseTimeout (Timeout .ofMilliseconds (readTimeout ));
5071 }
5172
5273 @ Override
@@ -64,44 +85,58 @@ public LowLevelHttpResponse execute() throws IOException {
6485
6586 // Make Producer
6687 CompletableFuture <Void > writeFuture = new CompletableFuture <>();
67- ApacheHttp2AsyncEntityProducer entityProducer =
68- new ApacheHttp2AsyncEntityProducer (this , writeFuture );
88+ entityProducer = new ApacheHttp2AsyncEntityProducer (this , writeFuture );
6989
7090 // Execute
71- final CompletableFuture <SimpleHttpResponse > responseFuture = new CompletableFuture <>();
91+ final Future <SimpleHttpResponse > responseFuture = httpAsyncClient .execute (
92+ new BasicRequestProducer (request , entityProducer ),
93+ SimpleResponseConsumer .create (),
94+ new FutureCallback <SimpleHttpResponse >() {
95+ @ Override
96+ public void completed (final SimpleHttpResponse response ) {
97+ }
98+
99+ @ Override
100+ public void failed (final Exception exception ) {
101+ }
102+
103+ @ Override
104+ public void cancelled () {
105+ }
106+ });
107+
108+ // Wait for write
72109 try {
73- httpAsyncClient .execute (
74- new BasicRequestProducer (request , entityProducer ),
75- SimpleResponseConsumer .create (),
76- new FutureCallback <SimpleHttpResponse >() {
77- @ Override
78- public void completed (final SimpleHttpResponse response ) {
79- responseFuture .complete (response );
80- }
81-
82- @ Override
83- public void failed (final Exception exception ) {
84- responseFuture .completeExceptionally (exception );
85- }
86-
87- @ Override
88- public void cancelled () {
89- responseFuture .cancel (false );
90- }
91- });
92-
93110 if (writeTimeout != 0 ) {
94111 writeFuture .get (writeTimeout , TimeUnit .MILLISECONDS );
95112 }
113+ } catch (TimeoutException e ) {
114+ throw new IOException ("Write Timeout" , e .getCause ());
115+ } catch (Exception e ) {
116+ throw new IOException ("Exception in write" , e .getCause ());
117+ }
96118
119+ // Wait for response
120+ try {
97121 final SimpleHttpResponse response = responseFuture .get ();
98- return new ApacheHttp2Response (request , response );
122+ return new ApacheHttp2Response (response );
123+ } catch (ExecutionException e ) {
124+ if (e .getCause () instanceof ConnectTimeoutException ) {
125+ throw new IOException ("Connection Timeout" , e .getCause ());
126+ } else if (e .getCause () instanceof H2StreamResetException ) {
127+ throw new IOException ("Stream exception in request" , e .getCause ());
128+ } else {
129+ throw new IOException ("Exception in request" , e );
130+ }
99131 } catch (InterruptedException e ) {
100132 throw new IOException ("Request Interrupted" , e );
101- } catch (ExecutionException e ) {
102- throw new IOException ("Exception in request" , e );
103- } catch (TimeoutException e ) {
104- throw new IOException ("Timed out" , e );
133+ } catch (CancellationException e ) {
134+ throw new IOException ("Request Cancelled" , e );
105135 }
106136 }
137+
138+ @ VisibleForTesting
139+ ApacheHttp2AsyncEntityProducer getEntityProducer () {
140+ return entityProducer ;
141+ }
107142}
0 commit comments