BundleDownloader/DevServerHelper: Close http responses
Reviewed By: amnn Differential Revision: D7067204 fbshipit-source-id: 9b3dde374280b8d7bdc028a14e9218f37cfc87f2
This commit is contained in:
parent
33a893e18b
commit
87f98bcd7c
|
@ -110,7 +110,8 @@ public class BundleDownloader {
|
|||
// .addHeader("Accept", "multipart/mixed")
|
||||
.build();
|
||||
mDownloadBundleFromURLCall = Assertions.assertNotNull(mClient.newCall(request));
|
||||
mDownloadBundleFromURLCall.enqueue(new Callback() {
|
||||
mDownloadBundleFromURLCall.enqueue(
|
||||
new Callback() {
|
||||
@Override
|
||||
public void onFailure(Call call, IOException e) {
|
||||
// ignore callback if call was cancelled
|
||||
|
@ -120,7 +121,8 @@ public class BundleDownloader {
|
|||
}
|
||||
mDownloadBundleFromURLCall = null;
|
||||
|
||||
callback.onFailure(DebugServerException.makeGeneric(
|
||||
callback.onFailure(
|
||||
DebugServerException.makeGeneric(
|
||||
"Could not connect to development server.",
|
||||
"URL: " + call.request().url().toString(),
|
||||
e));
|
||||
|
@ -141,14 +143,48 @@ public class BundleDownloader {
|
|||
String contentType = response.header("content-type");
|
||||
Pattern regex = Pattern.compile("multipart/mixed;.*boundary=\"([^\"]+)\"");
|
||||
Matcher match = regex.matcher(contentType);
|
||||
try (Response r = response) {
|
||||
if (match.find()) {
|
||||
String boundary = match.group(1);
|
||||
MultipartStreamReader bodyReader = new MultipartStreamReader(response.body().source(), boundary);
|
||||
boolean completed = bodyReader.readAllParts(new MultipartStreamReader.ChunkListener() {
|
||||
processMultipartResponse(
|
||||
url, r, match.group(1), outputFile, bundleInfo, callback);
|
||||
} else {
|
||||
// In case the server doesn't support multipart/mixed responses, fallback to normal
|
||||
// download.
|
||||
processBundleResult(
|
||||
url,
|
||||
r.code(),
|
||||
r.headers(),
|
||||
Okio.buffer(r.body().source()),
|
||||
outputFile,
|
||||
bundleInfo,
|
||||
callback);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void processMultipartResponse(
|
||||
final String url,
|
||||
final Response response,
|
||||
String boundary,
|
||||
final File outputFile,
|
||||
@Nullable final BundleInfo bundleInfo,
|
||||
final DevBundleDownloadListener callback)
|
||||
throws IOException {
|
||||
|
||||
MultipartStreamReader bodyReader =
|
||||
new MultipartStreamReader(response.body().source(), boundary);
|
||||
boolean completed =
|
||||
bodyReader.readAllParts(
|
||||
new MultipartStreamReader.ChunkListener() {
|
||||
@Override
|
||||
public void onChunkComplete(Map<String, String> headers, Buffer body, boolean isLastChunk) throws IOException {
|
||||
public void onChunkComplete(
|
||||
Map<String, String> headers, Buffer body, boolean isLastChunk)
|
||||
throws IOException {
|
||||
// This will get executed for every chunk of the multipart response. The last chunk
|
||||
// (isLastChunk = true) will be the JS bundle, the other ones will be progress events
|
||||
// (isLastChunk = true) will be the JS bundle, the other ones will be progress
|
||||
// events
|
||||
// encoded as JSON.
|
||||
if (isLastChunk) {
|
||||
// The http status code for each separate chunk is in the X-Http-Status header.
|
||||
|
@ -156,9 +192,11 @@ public class BundleDownloader {
|
|||
if (headers.containsKey("X-Http-Status")) {
|
||||
status = Integer.parseInt(headers.get("X-Http-Status"));
|
||||
}
|
||||
processBundleResult(url, status, Headers.of(headers), body, outputFile, bundleInfo, callback);
|
||||
processBundleResult(
|
||||
url, status, Headers.of(headers), body, outputFile, bundleInfo, callback);
|
||||
} else {
|
||||
if (!headers.containsKey("Content-Type") || !headers.get("Content-Type").equals("application/json")) {
|
||||
if (!headers.containsKey("Content-Type")
|
||||
|| !headers.get("Content-Type").equals("application/json")) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -182,27 +220,26 @@ public class BundleDownloader {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onChunkProgress(Map<String, String> headers, long loaded, long total) throws IOException {
|
||||
public void onChunkProgress(Map<String, String> headers, long loaded, long total)
|
||||
throws IOException {
|
||||
if ("application/javascript".equals(headers.get("Content-Type"))) {
|
||||
callback.onProgress(
|
||||
"Downloading JavaScript bundle",
|
||||
(int) (loaded / 1024),
|
||||
(int) (total / 1024));
|
||||
"Downloading JavaScript bundle", (int) (loaded / 1024), (int) (total / 1024));
|
||||
}
|
||||
}
|
||||
});
|
||||
if (!completed) {
|
||||
callback.onFailure(new DebugServerException(
|
||||
"Error while reading multipart response.\n\nResponse code: " + response.code() + "\n\n" +
|
||||
"URL: " + call.request().url().toString() + "\n\n"));
|
||||
callback.onFailure(
|
||||
new DebugServerException(
|
||||
"Error while reading multipart response.\n\nResponse code: "
|
||||
+ response.code()
|
||||
+ "\n\n"
|
||||
+ "URL: "
|
||||
+ url.toString()
|
||||
+ "\n\n"));
|
||||
}
|
||||
} else {
|
||||
// In case the server doesn't support multipart/mixed responses, fallback to normal download.
|
||||
processBundleResult(url, response.code(), response.headers(), Okio.buffer(response.body().source()), outputFile, bundleInfo, callback);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void processBundleResult(
|
||||
|
|
|
@ -629,8 +629,7 @@ public class DevServerHelper {
|
|||
.url(resourceURL)
|
||||
.build();
|
||||
|
||||
try {
|
||||
Response response = mClient.newCall(request).execute();
|
||||
try (Response response = mClient.newCall(request).execute()) {
|
||||
if (!response.isSuccessful()) {
|
||||
return null;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue