Skip to content

Commit bf0fdfb

Browse files
committed
Make request body writing more efficient
1 parent 6b48593 commit bf0fdfb

File tree

3 files changed

+29
-30
lines changed

3 files changed

+29
-30
lines changed

firebase-appdistribution/src/main/java/com/google/firebase/appdistribution/impl/FirebaseAppDistributionTesterApiClient.java

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414

1515
package com.google.firebase.appdistribution.impl;
1616

17+
import static android.graphics.Bitmap.CompressFormat.PNG;
1718
import static com.google.firebase.appdistribution.impl.TaskUtils.runAsyncInTask;
1819

1920
import android.graphics.Bitmap;
@@ -27,7 +28,6 @@
2728
import com.google.firebase.inject.Provider;
2829
import com.google.firebase.installations.FirebaseInstallationsApi;
2930
import com.google.firebase.installations.InstallationTokenResult;
30-
import java.io.ByteArrayOutputStream;
3131
import java.util.concurrent.Executor;
3232
import java.util.concurrent.Executors;
3333
import org.json.JSONArray;
@@ -157,10 +157,11 @@ Task<String> attachScreenshot(String feedbackName, Bitmap screenshot) {
157157
LogWrapper.getInstance().i("Uploading screenshot for feedback: " + feedbackName);
158158
String path =
159159
String.format("upload/v1alpha/%s:uploadArtifact?type=SCREENSHOT", feedbackName);
160-
ByteArrayOutputStream stream = new ByteArrayOutputStream();
161-
screenshot.compress(Bitmap.CompressFormat.PNG, /* quality= */ 100, stream);
162-
byte[] bytes = stream.toByteArray();
163-
testerApiHttpClient.makeUploadRequest(UPLOAD_SCREENSHOT_TAG, path, token, bytes);
160+
testerApiHttpClient.makeUploadRequest(
161+
UPLOAD_SCREENSHOT_TAG,
162+
path,
163+
token,
164+
stream -> screenshot.compress(PNG, /* quality= */ 100, stream));
164165
return feedbackName;
165166
});
166167
}

firebase-appdistribution/src/main/java/com/google/firebase/appdistribution/impl/TesterApiHttpClient.java

Lines changed: 20 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -27,24 +27,27 @@
2727
import java.io.ByteArrayOutputStream;
2828
import java.io.IOException;
2929
import java.io.InputStream;
30+
import java.io.OutputStream;
3031
import java.io.UnsupportedEncodingException;
3132
import java.util.HashMap;
3233
import java.util.Map;
33-
import java.util.zip.GZIPOutputStream;
3434
import javax.net.ssl.HttpsURLConnection;
3535
import org.json.JSONException;
3636
import org.json.JSONObject;
3737

3838
/** Client that makes FIS-authenticated GET and POST requests to the App Distribution Tester API. */
3939
class TesterApiHttpClient {
4040

41+
/** Functional interface for a function that writes a request body to an output stream */
42+
interface RequestBodyWriter {
43+
void write(OutputStream os) throws IOException;
44+
}
45+
4146
private static final String APP_TESTERS_HOST = "firebaseapptesters.googleapis.com";
4247
private static final String REQUEST_METHOD_GET = "GET";
4348
private static final String REQUEST_METHOD_POST = "POST";
4449
private static final String CONTENT_TYPE_HEADER_KEY = "Content-Type";
4550
private static final String JSON_CONTENT_TYPE = "application/json";
46-
private static final String CONTENT_ENCODING_HEADER_KEY = "Content-Encoding";
47-
private static final String GZIP_CONTENT_ENCODING = "gzip";
4851
private static final String API_KEY_HEADER = "x-goog-api-key";
4952
private static final String INSTALLATION_AUTH_HEADER = "X-Goog-Firebase-Installations-Auth";
5053
private static final String X_ANDROID_PACKAGE_HEADER_KEY = "X-Android-Package";
@@ -110,7 +113,8 @@ JSONObject makePostRequest(String tag, String path, String token, String request
110113
throw new FirebaseAppDistributionException(
111114
"Unsupported encoding: " + UTF_8, Status.UNKNOWN, e);
112115
}
113-
return makePostRequest(tag, path, token, bytes, new HashMap<>());
116+
return makePostRequest(
117+
tag, path, token, new HashMap<>(), outputStream -> outputStream.write(bytes));
114118
}
115119

116120
/**
@@ -120,34 +124,38 @@ JSONObject makePostRequest(String tag, String path, String token, String request
120124
*
121125
* @return the response body
122126
*/
123-
JSONObject makeUploadRequest(String tag, String path, String token, byte[] requestBody)
127+
JSONObject makeUploadRequest(
128+
String tag, String path, String token, RequestBodyWriter requestBodyWriter)
124129
throws FirebaseAppDistributionException {
125130
Map<String, String> extraHeaders = new HashMap<>();
126131
extraHeaders.put(X_GOOG_UPLOAD_PROTOCOL_HEADER, X_GOOG_UPLOAD_PROTOCOL_RAW);
127132
extraHeaders.put(X_GOOG_UPLOAD_FILE_NAME_HEADER, X_GOOG_UPLOAD_FILE_NAME);
128-
return makePostRequest(tag, path, token, requestBody, extraHeaders);
133+
return makePostRequest(tag, path, token, extraHeaders, requestBodyWriter);
129134
}
130135

131136
private JSONObject makePostRequest(
132-
String tag, String path, String token, byte[] requestBody, Map<String, String> extraHeaders)
137+
String tag,
138+
String path,
139+
String token,
140+
Map<String, String> extraHeaders,
141+
RequestBodyWriter requestBodyWriter)
133142
throws FirebaseAppDistributionException {
134143
HttpsURLConnection connection = null;
135144
try {
136145
connection = openHttpsUrlConnection(getTesterApiUrl(path), token);
137146
connection.setDoOutput(true);
138147
connection.setRequestMethod(REQUEST_METHOD_POST);
139148
connection.addRequestProperty(CONTENT_TYPE_HEADER_KEY, JSON_CONTENT_TYPE);
140-
connection.addRequestProperty(CONTENT_ENCODING_HEADER_KEY, GZIP_CONTENT_ENCODING);
141149
for (Map.Entry<String, String> e : extraHeaders.entrySet()) {
142150
connection.addRequestProperty(e.getKey(), e.getValue());
143151
}
144-
GZIPOutputStream gzipOutputStream = new GZIPOutputStream(connection.getOutputStream());
152+
OutputStream outputStream = connection.getOutputStream();
145153
try {
146-
gzipOutputStream.write(requestBody);
154+
requestBodyWriter.write(outputStream);
147155
} catch (IOException e) {
148-
throw getException(tag, "Error compressing network request body", Status.UNKNOWN, e);
156+
throw getException(tag, "Error writing network request body", Status.UNKNOWN, e);
149157
} finally {
150-
gzipOutputStream.close();
158+
outputStream.close();
151159
}
152160
return readResponse(tag, connection);
153161
} catch (IOException e) {

firebase-appdistribution/src/test/java/com/google/firebase/appdistribution/impl/TesterApiHttpClientTest.java

Lines changed: 3 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,6 @@
2323

2424
import androidx.test.core.app.ApplicationProvider;
2525
import com.google.common.collect.Iterators;
26-
import com.google.common.io.ByteStreams;
2726
import com.google.firebase.FirebaseApp;
2827
import com.google.firebase.FirebaseOptions;
2928
import com.google.firebase.appdistribution.FirebaseAppDistributionException;
@@ -32,7 +31,6 @@
3231
import java.io.ByteArrayOutputStream;
3332
import java.io.IOException;
3433
import java.io.InputStream;
35-
import java.util.zip.GZIPInputStream;
3634
import javax.net.ssl.HttpsURLConnection;
3735
import org.json.JSONObject;
3836
import org.junit.Before;
@@ -200,14 +198,10 @@ public void makePostRequest_zipsRequestBodyAndSetsCorrectHeaders() throws Except
200198

201199
testerApiHttpClient.makePostRequest(TAG, TEST_PATH, TEST_AUTH_TOKEN, TEST_POST_BODY);
202200

203-
byte[] unzippedPostBody =
204-
ByteStreams.toByteArray(
205-
new GZIPInputStream(new ByteArrayInputStream(requestBodyOutputStream.toByteArray())));
206-
assertThat(new String(unzippedPostBody, UTF_8)).isEqualTo(TEST_POST_BODY);
201+
assertThat(new String(requestBodyOutputStream.toByteArray(), UTF_8)).isEqualTo(TEST_POST_BODY);
207202
verify(mockHttpsURLConnection).setDoOutput(true);
208203
verify(mockHttpsURLConnection).setRequestMethod("POST");
209204
verify(mockHttpsURLConnection).addRequestProperty("Content-Type", "application/json");
210-
verify(mockHttpsURLConnection).addRequestProperty("Content-Encoding", "gzip");
211205
verify(mockHttpsURLConnection).disconnect();
212206
}
213207

@@ -238,16 +232,12 @@ public void makeUploadRequest_zipsRequestBodyAndSetsCorrectHeaders() throws Exce
238232
when(mockHttpsURLConnection.getOutputStream()).thenReturn(requestBodyOutputStream);
239233

240234
testerApiHttpClient.makeUploadRequest(
241-
TAG, TEST_PATH, TEST_AUTH_TOKEN, TEST_POST_BODY.getBytes(UTF_8));
235+
TAG, TEST_PATH, TEST_AUTH_TOKEN, stream -> stream.write(TEST_POST_BODY.getBytes(UTF_8)));
242236

243-
byte[] unzippedPostBody =
244-
ByteStreams.toByteArray(
245-
new GZIPInputStream(new ByteArrayInputStream(requestBodyOutputStream.toByteArray())));
246-
assertThat(new String(unzippedPostBody, UTF_8)).isEqualTo(TEST_POST_BODY);
237+
assertThat(new String(requestBodyOutputStream.toByteArray(), UTF_8)).isEqualTo(TEST_POST_BODY);
247238
verify(mockHttpsURLConnection).setDoOutput(true);
248239
verify(mockHttpsURLConnection).setRequestMethod("POST");
249240
verify(mockHttpsURLConnection).addRequestProperty("Content-Type", "application/json");
250-
verify(mockHttpsURLConnection).addRequestProperty("Content-Encoding", "gzip");
251241
verify(mockHttpsURLConnection).addRequestProperty("X-Goog-Upload-Protocol", "raw");
252242
verify(mockHttpsURLConnection).addRequestProperty("X-Goog-Upload-File-Name", "screenshot.png");
253243
verify(mockHttpsURLConnection).disconnect();

0 commit comments

Comments
 (0)