|
42 | 42 | import com.google.android.datatransport.runtime.time.Clock;
|
43 | 43 | import com.google.firebase.encoders.DataEncoder;
|
44 | 44 | import com.google.firebase.encoders.EncodingException;
|
45 |
| -import java.io.ByteArrayOutputStream; |
| 45 | +import java.io.BufferedReader; |
| 46 | +import java.io.BufferedWriter; |
46 | 47 | import java.io.IOException;
|
47 | 48 | import java.io.InputStream;
|
48 | 49 | import java.io.InputStreamReader;
|
| 50 | +import java.io.OutputStream; |
49 | 51 | import java.io.OutputStreamWriter;
|
50 | 52 | import java.net.HttpURLConnection;
|
51 | 53 | import java.net.MalformedURLException;
|
52 | 54 | import java.net.URL;
|
53 |
| -import java.nio.ByteBuffer; |
54 |
| -import java.nio.channels.Channels; |
55 |
| -import java.nio.channels.WritableByteChannel; |
56 | 55 | import java.nio.charset.Charset;
|
57 | 56 | import java.util.ArrayList;
|
58 | 57 | import java.util.Calendar;
|
@@ -264,50 +263,46 @@ private HttpResponse doSend(HttpRequest request) throws IOException {
|
264 | 263 | connection.setRequestProperty(API_KEY_HEADER_KEY, request.apiKey);
|
265 | 264 | }
|
266 | 265 |
|
267 |
| - WritableByteChannel channel = Channels.newChannel(connection.getOutputStream()); |
268 |
| - try { |
269 |
| - ByteArrayOutputStream output = new ByteArrayOutputStream(); |
270 |
| - GZIPOutputStream gzipOutputStream = new GZIPOutputStream(output); |
| 266 | + try (OutputStream conn = connection.getOutputStream(); |
| 267 | + OutputStream outputStream = new GZIPOutputStream(conn)) { |
| 268 | + // note: it's very important to use a BufferedWriter for efficient use of resources as the |
| 269 | + // JsonWriter often writes one character at a time. |
| 270 | + dataEncoder.encode( |
| 271 | + request.requestBody, new BufferedWriter(new OutputStreamWriter(outputStream))); |
| 272 | + } catch (EncodingException | IOException e) { |
| 273 | + Logging.e(LOG_TAG, "Couldn't encode request, returning with 400", e); |
| 274 | + return new HttpResponse(400, null, 0); |
| 275 | + } |
271 | 276 |
|
272 |
| - try { |
273 |
| - dataEncoder.encode(request.requestBody, new OutputStreamWriter(gzipOutputStream)); |
274 |
| - } catch (EncodingException | IOException e) { |
275 |
| - Logging.e(LOG_TAG, "Couldn't encode request, returning with 400", e); |
276 |
| - return new HttpResponse(400, null, 0); |
277 |
| - } finally { |
278 |
| - gzipOutputStream.close(); |
279 |
| - } |
280 |
| - channel.write(ByteBuffer.wrap(output.toByteArray())); |
281 |
| - int responseCode = connection.getResponseCode(); |
282 |
| - Logging.i(LOG_TAG, "Status Code: " + responseCode); |
283 |
| - Logging.i(LOG_TAG, "Content-Type: " + connection.getHeaderField("Content-Type")); |
284 |
| - Logging.i(LOG_TAG, "Content-Encoding: " + connection.getHeaderField("Content-Encoding")); |
285 |
| - |
286 |
| - if (responseCode == 302 || responseCode == 301 || responseCode == 307) { |
287 |
| - String redirect = connection.getHeaderField("Location"); |
288 |
| - return new HttpResponse(responseCode, new URL(redirect), 0); |
289 |
| - } |
290 |
| - if (responseCode != 200) { |
291 |
| - return new HttpResponse(responseCode, null, 0); |
292 |
| - } |
| 277 | + int responseCode = connection.getResponseCode(); |
| 278 | + Logging.i(LOG_TAG, "Status Code: " + responseCode); |
| 279 | + Logging.i(LOG_TAG, "Content-Type: " + connection.getHeaderField("Content-Type")); |
| 280 | + Logging.i(LOG_TAG, "Content-Encoding: " + connection.getHeaderField("Content-Encoding")); |
293 | 281 |
|
294 |
| - InputStream inputStream; |
295 |
| - String contentEncoding = connection.getHeaderField(CONTENT_ENCODING_HEADER_KEY); |
296 |
| - if (contentEncoding != null && contentEncoding.equals(GZIP_CONTENT_ENCODING)) { |
297 |
| - inputStream = new GZIPInputStream(connection.getInputStream()); |
298 |
| - } else { |
299 |
| - inputStream = connection.getInputStream(); |
300 |
| - } |
301 |
| - try { |
302 |
| - long nextRequestMillis = |
303 |
| - LogResponse.fromJson(new InputStreamReader(inputStream)).getNextRequestWaitMillis(); |
304 |
| - return new HttpResponse(responseCode, null, nextRequestMillis); |
305 |
| - } finally { |
306 |
| - inputStream.close(); |
307 |
| - } |
308 |
| - } finally { |
309 |
| - channel.close(); |
| 282 | + if (responseCode == 302 || responseCode == 301 || responseCode == 307) { |
| 283 | + String redirect = connection.getHeaderField("Location"); |
| 284 | + return new HttpResponse(responseCode, new URL(redirect), 0); |
| 285 | + } |
| 286 | + if (responseCode != 200) { |
| 287 | + return new HttpResponse(responseCode, null, 0); |
| 288 | + } |
| 289 | + |
| 290 | + try (InputStream connStream = connection.getInputStream(); |
| 291 | + InputStream inputStream = |
| 292 | + maybeUnGzip(connStream, connection.getHeaderField(CONTENT_ENCODING_HEADER_KEY))) { |
| 293 | + long nextRequestMillis = |
| 294 | + LogResponse.fromJson(new BufferedReader(new InputStreamReader(inputStream))) |
| 295 | + .getNextRequestWaitMillis(); |
| 296 | + return new HttpResponse(responseCode, null, nextRequestMillis); |
| 297 | + } |
| 298 | + } |
| 299 | + |
| 300 | + private static InputStream maybeUnGzip(InputStream input, String contentEncoding) |
| 301 | + throws IOException { |
| 302 | + if (GZIP_CONTENT_ENCODING.equals(contentEncoding)) { |
| 303 | + return new GZIPInputStream(input); |
310 | 304 | }
|
| 305 | + return input; |
311 | 306 | }
|
312 | 307 |
|
313 | 308 | @Override
|
|
0 commit comments