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
+
1
17
package com .google .firebase .internal ;
2
18
3
19
import com .google .api .client .http .LowLevelHttpRequest ;
4
20
import com .google .api .client .http .LowLevelHttpResponse ;
21
+ import com .google .common .annotations .VisibleForTesting ;
5
22
6
23
import java .io .IOException ;
24
+ import java .util .concurrent .CancellationException ;
7
25
import java .util .concurrent .CompletableFuture ;
8
26
import java .util .concurrent .ExecutionException ;
27
+ import java .util .concurrent .Future ;
9
28
import java .util .concurrent .TimeUnit ;
10
29
import java .util .concurrent .TimeoutException ;
11
30
31
+ import org .apache .hc .client5 .http .ConnectTimeoutException ;
12
32
import org .apache .hc .client5 .http .async .methods .SimpleHttpRequest ;
13
33
import org .apache .hc .client5 .http .async .methods .SimpleHttpResponse ;
14
34
import org .apache .hc .client5 .http .async .methods .SimpleRequestBuilder ;
17
37
import org .apache .hc .client5 .http .impl .async .CloseableHttpAsyncClient ;
18
38
import org .apache .hc .core5 .concurrent .FutureCallback ;
19
39
import org .apache .hc .core5 .http .nio .support .BasicRequestProducer ;
40
+ import org .apache .hc .core5 .http2 .H2StreamResetException ;
20
41
import org .apache .hc .core5 .util .Timeout ;
21
42
22
43
final class ApacheHttp2Request extends LowLevelHttpRequest {
@@ -25,6 +46,7 @@ final class ApacheHttp2Request extends LowLevelHttpRequest {
25
46
private SimpleHttpRequest request ;
26
47
private final RequestConfig .Builder requestConfig ;
27
48
private int writeTimeout ;
49
+ private ApacheHttp2AsyncEntityProducer entityProducer ;
28
50
29
51
ApacheHttp2Request (
30
52
CloseableHttpAsyncClient httpAsyncClient , SimpleRequestBuilder requestBuilder ) {
@@ -33,7 +55,7 @@ final class ApacheHttp2Request extends LowLevelHttpRequest {
33
55
this .writeTimeout = 0 ;
34
56
35
57
this .requestConfig = RequestConfig .custom ()
36
- .setRedirectsEnabled (false );
58
+ .setRedirectsEnabled (false );
37
59
}
38
60
39
61
@ Override
@@ -42,11 +64,10 @@ public void addHeader(String name, String value) {
42
64
}
43
65
44
66
@ Override
45
- @ SuppressWarnings ("deprecation" )
46
67
public void setTimeout (int connectionTimeout , int readTimeout ) throws IOException {
47
68
requestConfig
48
- .setConnectTimeout (Timeout .ofMilliseconds (connectionTimeout ))
49
- .setResponseTimeout (Timeout .ofMilliseconds (readTimeout ));
69
+ .setConnectTimeout (Timeout .ofMilliseconds (connectionTimeout ))
70
+ .setResponseTimeout (Timeout .ofMilliseconds (readTimeout ));
50
71
}
51
72
52
73
@ Override
@@ -64,44 +85,58 @@ public LowLevelHttpResponse execute() throws IOException {
64
85
65
86
// Make Producer
66
87
CompletableFuture <Void > writeFuture = new CompletableFuture <>();
67
- ApacheHttp2AsyncEntityProducer entityProducer =
68
- new ApacheHttp2AsyncEntityProducer (this , writeFuture );
88
+ entityProducer = new ApacheHttp2AsyncEntityProducer (this , writeFuture );
69
89
70
90
// 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
72
109
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
-
93
110
if (writeTimeout != 0 ) {
94
111
writeFuture .get (writeTimeout , TimeUnit .MILLISECONDS );
95
112
}
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
+ }
96
118
119
+ // Wait for response
120
+ try {
97
121
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
+ }
99
131
} catch (InterruptedException e ) {
100
132
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 );
105
135
}
106
136
}
137
+
138
+ @ VisibleForTesting
139
+ ApacheHttp2AsyncEntityProducer getEntityProducer () {
140
+ return entityProducer ;
141
+ }
107
142
}
0 commit comments