Skip to content

Commit 90ee6a1

Browse files
committed
Update client to check Http status codes before listening or connecting
1 parent 5bba4bc commit 90ee6a1

File tree

2 files changed

+45
-23
lines changed

2 files changed

+45
-23
lines changed

firebase-config/src/main/java/com/google/firebase/remoteconfig/internal/ConfigAutoFetch.java

Lines changed: 3 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -97,16 +97,9 @@ private String parseAndValidateConfigUpdateMessage(String message) {
9797
public void listenForNotifications() {
9898
if (httpURLConnection != null) {
9999
try {
100-
int responseCode = httpURLConnection.getResponseCode();
101-
if (responseCode == 200) {
102-
InputStream inputStream = httpURLConnection.getInputStream();
103-
handleNotifications(inputStream);
104-
inputStream.close();
105-
} else {
106-
propagateErrors(
107-
new FirebaseRemoteConfigRealtimeUpdateStreamException(
108-
"Http connection responded with error: " + responseCode));
109-
}
100+
InputStream inputStream = httpURLConnection.getInputStream();
101+
handleNotifications(inputStream);
102+
inputStream.close();
110103
} catch (IOException ex) {
111104
propagateErrors(
112105
new FirebaseRemoteConfigRealtimeUpdateFetchException(

firebase-config/src/main/java/com/google/firebase/remoteconfig/internal/ConfigRealtimeHttpClient.java

Lines changed: 42 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616

1717
import static com.google.firebase.remoteconfig.FirebaseRemoteConfig.TAG;
1818
import static com.google.firebase.remoteconfig.RemoteConfigConstants.REALTIME_REGEX_URL;
19+
import static com.google.firebase.remoteconfig.internal.ConfigFetchHandler.HTTP_TOO_MANY_REQUESTS;
1920

2021
import android.annotation.SuppressLint;
2122
import android.content.Context;
@@ -236,7 +237,9 @@ private URL getUrl() {
236237
return realtimeURL;
237238
}
238239

239-
private HttpURLConnection createRealtimeConnection() throws IOException {
240+
/** Create HTTP connection and set headers. */
241+
@SuppressLint("VisibleForTests")
242+
public HttpURLConnection createRealtimeConnection() throws IOException {
240243
URL realtimeUrl = getUrl();
241244
HttpURLConnection httpURLConnection = (HttpURLConnection) realtimeUrl.openConnection();
242245
setCommonRequestHeaders(httpURLConnection);
@@ -245,8 +248,9 @@ private HttpURLConnection createRealtimeConnection() throws IOException {
245248
return httpURLConnection;
246249
}
247250

248-
// Try to reopen HTTP connection after a random amount of time
249-
private synchronized void retryHTTPConnection() {
251+
/** Retries HTTP stream connection asyncly in random time intervals. */
252+
@SuppressLint("VisibleForTests")
253+
public synchronized void retryHTTPConnection() {
250254
if (canMakeHttpStreamConnection() && httpRetriesRemaining > 0) {
251255
if (httpRetriesRemaining < ORIGINAL_RETRIES) {
252256
httpRetrySeconds *= getRetryMultiplier();
@@ -273,7 +277,12 @@ synchronized void stopRealtime() {
273277
scheduledExecutorService.shutdownNow();
274278
}
275279

276-
private synchronized ConfigAutoFetch startAutoFetch(HttpURLConnection httpURLConnection) {
280+
/**
281+
* Create Autofetch class that listens on HTTP stream for ConfigUpdate messages and calls Fetch
282+
* accordingly.
283+
*/
284+
@SuppressLint("VisibleForTests")
285+
public synchronized ConfigAutoFetch startAutoFetch(HttpURLConnection httpURLConnection) {
277286
ConfigUpdateListener retryCallback =
278287
new ConfigUpdateListener() {
279288
@Override
@@ -298,6 +307,16 @@ public void onError(Exception error) {
298307
return new ConfigAutoFetch(httpURLConnection, configFetchHandler, listeners, retryCallback);
299308
}
300309

310+
// HTTP status code that the Realtime client should retry on.
311+
private boolean isStatusCodeRetryable(int statusCode) {
312+
return statusCode == HttpURLConnection.HTTP_CLIENT_TIMEOUT
313+
|| statusCode == HTTP_TOO_MANY_REQUESTS
314+
|| statusCode == HttpURLConnection.HTTP_BAD_GATEWAY
315+
|| statusCode == HttpURLConnection.HTTP_UNAVAILABLE
316+
|| statusCode == HttpURLConnection.HTTP_GATEWAY_TIMEOUT
317+
|| statusCode == HttpURLConnection.HTTP_OK;
318+
}
319+
301320
/**
302321
* Open the realtime connection, begin listening for updates, and auto-fetch when an update is
303322
* received.
@@ -306,32 +325,42 @@ public void onError(Exception error) {
306325
* chunk-encoded HTTP body. When the connection closes, it attempts to reestablish the stream.
307326
*/
308327
@SuppressLint("VisibleForTests")
309-
synchronized void beginRealtimeHttpStream() {
328+
public synchronized void beginRealtimeHttpStream() {
310329
if (!canMakeHttpStreamConnection()) {
311330
return;
312331
}
313332

333+
int responseCode = 200;
314334
try {
315335
// Create the open the connection.
316336
httpURLConnection = createRealtimeConnection();
317-
httpURLConnection.connect();
337+
responseCode = httpURLConnection.getResponseCode();
318338

319-
// Reset the retries remaining if we opened the connection without an exception.
320-
resetRetryParameters();
339+
// If the connection returned a 200 response code, start listening for messages.
340+
if (responseCode == HttpURLConnection.HTTP_OK) {
341+
// Reset the retries remaining if we opened the connection without an exception.
342+
resetRetryParameters();
321343

322-
// Start listening for realtime notifications.
323-
ConfigAutoFetch configAutoFetch = startAutoFetch(httpURLConnection);
324-
configAutoFetch.listenForNotifications();
344+
// Start listening for realtime notifications.
345+
ConfigAutoFetch configAutoFetch = startAutoFetch(httpURLConnection);
346+
configAutoFetch.listenForNotifications();
347+
}
325348
} catch (IOException e) {
326349
Log.d(TAG, "Exception connecting to realtime stream. Retrying the connection...");
327350
} finally {
328351
closeRealtimeHttpStream();
329-
retryHTTPConnection();
352+
if (isStatusCodeRetryable(responseCode)) {
353+
retryHTTPConnection();
354+
} else {
355+
propagateErrors(
356+
new FirebaseRemoteConfigRealtimeUpdateStreamException(
357+
"The server returned a status code that is not retryable. Realtime is shutting down."));
358+
}
330359
}
331360
}
332361

333362
// Pauses Http stream listening
334-
synchronized void closeRealtimeHttpStream() {
363+
public synchronized void closeRealtimeHttpStream() {
335364
if (httpURLConnection != null) {
336365
this.httpURLConnection.disconnect();
337366

0 commit comments

Comments
 (0)