Skip to content

Commit c166499

Browse files
committed
Match streaming connection timeout
1 parent 6b109e4 commit c166499

File tree

6 files changed

+69
-31
lines changed

6 files changed

+69
-31
lines changed

src/main/java/io/split/android/client/network/HttpRequestHelper.java

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,8 @@ static HttpURLConnection createConnection(@NonNull URL url,
3030
boolean useProxyAuthentication,
3131
@Nullable SSLSocketFactory sslSocketFactory,
3232
@Nullable ProxyCredentialsProvider proxyCredentialsProvider,
33-
@Nullable String body) throws IOException {
33+
@Nullable String body,
34+
boolean isStreaming) throws IOException {
3435

3536
if (httpProxy != null && sslSocketFactory != null && (httpProxy.getCaCertStream() != null || httpProxy.getClientCertStream() != null)) {
3637
try {
@@ -41,7 +42,8 @@ static HttpURLConnection createConnection(@NonNull URL url,
4142
headers,
4243
body,
4344
sslSocketFactory,
44-
proxyCredentialsProvider
45+
proxyCredentialsProvider,
46+
isStreaming
4547
);
4648

4749
return new HttpResponseConnectionAdapter(url, response, response.getServerCertificates());

src/main/java/io/split/android/client/network/HttpRequestImpl.java

Lines changed: 18 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -190,23 +190,12 @@ private HttpURLConnection setUpConnection(boolean authenticate) throws IOExcepti
190190

191191
HttpURLConnection connection;
192192
try {
193-
connection = createConnection(
194-
url,
195-
mProxy,
196-
mHttpProxy,
197-
mProxyAuthenticator,
198-
mHttpMethod,
199-
mHeaders,
200-
authenticate,
201-
mSslSocketFactory,
202-
mProxyCredentialsProvider,
203-
mBody
204-
);
193+
connection = getConnection(authenticate, url);
205194
} catch (HttpRetryException e) {
206195
if (mProxyAuthenticator == null) {
207196
throw e;
208197
}
209-
connection = createConnection(url, mProxy, mHttpProxy, mProxyAuthenticator, mHttpMethod, mHeaders, authenticate, null, null, null);
198+
connection = getConnection(authenticate, url);
210199
}
211200
applyTimeouts(mReadTimeout, mConnectionTimeout, connection);
212201
applySslConfig(mSslSocketFactory, mDevelopmentSslConfig, connection);
@@ -226,6 +215,22 @@ private HttpURLConnection setUpConnection(boolean authenticate) throws IOExcepti
226215
return connection;
227216
}
228217

218+
@NonNull
219+
private HttpURLConnection getConnection(boolean authenticate, URL url) throws IOException {
220+
return createConnection(
221+
url,
222+
mProxy,
223+
mHttpProxy,
224+
mProxyAuthenticator,
225+
mHttpMethod,
226+
mHeaders,
227+
authenticate,
228+
mSslSocketFactory,
229+
mProxyCredentialsProvider,
230+
mBody,
231+
false);
232+
}
233+
229234
private static HttpResponse buildResponse(HttpURLConnection connection) throws IOException {
230235
int responseCode = connection.getResponseCode();
231236

src/main/java/io/split/android/client/network/HttpStreamRequestImpl.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -157,7 +157,8 @@ private HttpURLConnection setUpConnection(boolean useProxyAuthenticator) throws
157157
useProxyAuthenticator,
158158
mSslSocketFactory,
159159
mProxyCredentialsProvider,
160-
null
160+
null,
161+
true
161162
);
162163
applyTimeouts(HttpStreamRequestImpl.STREAMING_READ_TIMEOUT_IN_MILLISECONDS, mConnectionTimeout, connection);
163164
applySslConfig(mSslSocketFactory, mDevelopmentSslConfig, connection);

src/main/java/io/split/android/client/network/ProxyCacertConnectionHandler.java

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -33,14 +33,29 @@ public ProxyCacertConnectionHandler() {
3333
mTunnelExecutor = new HttpOverTunnelExecutor();
3434
}
3535

36+
/**
37+
* Executes an HTTP request through an SSL proxy tunnel.
38+
*
39+
* @param httpProxy The proxy configuration
40+
* @param targetUrl The target URL to connect to
41+
* @param method The HTTP method to use
42+
* @param headers The HTTP headers to include
43+
* @param body The request body (if any)
44+
* @param sslSocketFactory The SSL socket factory for proxy and origin connections
45+
* @param proxyCredentialsProvider Credentials provider for proxy authentication
46+
* @param isStreaming Whether this connection is for streaming (uses longer timeout)
47+
* @return The HTTP response
48+
* @throws IOException if the request fails
49+
*/
3650
@NonNull
37-
public HttpResponse executeRequest(@NonNull HttpProxy httpProxy,
51+
HttpResponse executeRequest(@NonNull HttpProxy httpProxy,
3852
@NonNull URL targetUrl,
3953
@NonNull HttpMethod method,
4054
@NonNull Map<String, String> headers,
4155
@Nullable String body,
4256
@NonNull SSLSocketFactory sslSocketFactory,
43-
@Nullable ProxyCredentialsProvider proxyCredentialsProvider) throws IOException {
57+
@Nullable ProxyCredentialsProvider proxyCredentialsProvider,
58+
boolean isStreaming) throws IOException {
4459

4560
try {
4661
SslProxyTunnelEstablisher tunnelEstablisher = new SslProxyTunnelEstablisher();
@@ -55,7 +70,8 @@ public HttpResponse executeRequest(@NonNull HttpProxy httpProxy,
5570
targetUrl.getHost(),
5671
getTargetPort(targetUrl),
5772
sslSocketFactory,
58-
proxyCredentialsProvider
73+
proxyCredentialsProvider,
74+
isStreaming
5975
);
6076

6177
Logger.v("SSL tunnel established successfully");

src/main/java/io/split/android/client/network/SslProxyTunnelEstablisher.java

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,9 @@ class SslProxyTunnelEstablisher {
2929
// Default timeout for regular connections (10 seconds)
3030
private static final int DEFAULT_SOCKET_TIMEOUT = 10000;
3131

32+
// Timeout for streaming connections (80 seconds to match HttpStreamRequestImpl)
33+
private static final int STREAMING_SOCKET_TIMEOUT = 80000;
34+
3235
/**
3336
* Establishes an SSL tunnel through the proxy using the CONNECT method.
3437
* After successful tunnel establishment, extracts the underlying socket
@@ -54,6 +57,7 @@ class SslProxyTunnelEstablisher {
5457
* @param targetPort The target server port
5558
* @param sslSocketFactory SSL socket factory for proxy authentication
5659
* @param proxyCredentialsProvider Credentials provider for proxy authentication
60+
* @param isStreaming Whether this connection is for streaming (uses longer timeout)
5761
* @return Raw socket with tunnel established (connection maintained)
5862
* @throws IOException if tunnel establishment fails
5963
*/
@@ -63,14 +67,15 @@ Socket establishTunnel(@NonNull String proxyHost,
6367
@NonNull String targetHost,
6468
int targetPort,
6569
@NonNull SSLSocketFactory sslSocketFactory,
66-
@Nullable ProxyCredentialsProvider proxyCredentialsProvider) throws IOException {
70+
@Nullable ProxyCredentialsProvider proxyCredentialsProvider,
71+
boolean isStreaming) throws IOException {
6772

6873
Socket rawSocket = null;
6974
SSLSocket sslSocket = null;
7075

7176
try {
7277
// Determine which timeout to use based on connection type
73-
int timeout = DEFAULT_SOCKET_TIMEOUT;
78+
int timeout = isStreaming ? STREAMING_SOCKET_TIMEOUT : DEFAULT_SOCKET_TIMEOUT;
7479

7580
// Step 1: Create raw TCP connection to proxy
7681
rawSocket = new Socket(proxyHost, proxyPort);

src/test/java/io/split/android/client/network/SslProxyTunnelEstablisherTest.java

Lines changed: 19 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,8 @@ public void establishTunnelWithValidSslProxySucceeds() throws Exception {
9595
targetHost,
9696
targetPort,
9797
clientSslSocketFactory,
98-
proxyCredentialsProvider);
98+
proxyCredentialsProvider,
99+
false);
99100

100101
assertNotNull("Tunnel socket should not be null", tunnelSocket);
101102
assertTrue("Tunnel socket should be connected", tunnelSocket.isConnected());
@@ -124,7 +125,8 @@ public void establishTunnelWithNotTrustedCertificatedThrows() throws Exception {
124125
"example.com",
125126
443,
126127
untrustedSocketFactory,
127-
proxyCredentialsProvider);
128+
proxyCredentialsProvider,
129+
false);
128130
fail("Should have thrown exception for untrusted certificate");
129131
} catch (IOException e) {
130132
assertTrue("Exception should be SSL-related", e.getMessage().contains("certification"));
@@ -143,7 +145,8 @@ public void establishTunnelWithFailingProxyConnectionThrows() {
143145
"example.com",
144146
443,
145147
clientSslSocketFactory,
146-
proxyCredentialsProvider);
148+
proxyCredentialsProvider,
149+
false);
147150
fail("Should have thrown exception for connection failure");
148151
} catch (IOException e) {
149152
// The implementation wraps the original exception with a descriptive message
@@ -165,7 +168,8 @@ public void bearerTokenIsPassedWhenSet() throws IOException, InterruptedExceptio
165168
public String getToken() {
166169
return "token";
167170
}
168-
});
171+
},
172+
false);
169173
boolean await = testProxy.getAuthorizationHeaderReceived().await(5, TimeUnit.SECONDS);
170174
assertTrue("Proxy should have received authorization header", await);
171175
}
@@ -180,7 +184,8 @@ public void establishTunnelWithNullCredentialsProviderDoesNotAddAuthHeader() thr
180184
"example.com",
181185
443,
182186
clientSslSocketFactory,
183-
null);
187+
null,
188+
false);
184189

185190
assertNotNull(tunnelSocket);
186191
assertTrue(testProxy.getConnectRequestReceived().await(5, TimeUnit.SECONDS));
@@ -205,7 +210,8 @@ public void establishTunnelWithNullBearerTokenDoesNotAddAuthHeader() throws Exce
205210
public String getToken() {
206211
return null;
207212
}
208-
});
213+
},
214+
false);
209215

210216
assertNotNull(tunnelSocket);
211217
assertTrue(testProxy.getConnectRequestReceived().await(5, TimeUnit.SECONDS));
@@ -230,7 +236,8 @@ public void establishTunnelWithEmptyBearerTokenDoesNotAddAuthHeader() throws Exc
230236
public String getToken() {
231237
return "";
232238
}
233-
});
239+
},
240+
false);
234241

235242
assertNotNull(tunnelSocket);
236243
assertTrue(testProxy.getConnectRequestReceived().await(5, TimeUnit.SECONDS));
@@ -251,7 +258,7 @@ public void establishTunnelWithNullStatusLineThrowsIOException() {
251258
"example.com",
252259
443,
253260
clientSslSocketFactory,
254-
null));
261+
null, false));
255262

256263
assertNotNull(exception);
257264
}
@@ -267,7 +274,8 @@ public void establishTunnelWithMalformedStatusLineThrowsIOException() {
267274
"example.com",
268275
443,
269276
clientSslSocketFactory,
270-
null));
277+
null,
278+
false));
271279

272280
assertNotNull(exception);
273281
}
@@ -283,7 +291,8 @@ public void establishTunnelWithProxyAuthRequiredThrowsHttpRetryException() {
283291
"example.com",
284292
443,
285293
clientSslSocketFactory,
286-
null));
294+
null,
295+
false));
287296

288297
assertEquals(407, exception.responseCode());
289298
}

0 commit comments

Comments
 (0)