Rework HttpDownloader for readability
This commit is contained in:
parent
bd6798d2af
commit
b53cec6795
|
@ -39,7 +39,6 @@ import okio.ByteString;
|
|||
|
||||
public class HttpDownloader extends Downloader {
|
||||
private static final String TAG = "HttpDownloader";
|
||||
|
||||
private static final int BUFFER_SIZE = 8 * 1024;
|
||||
|
||||
public HttpDownloader(@NonNull DownloadRequest request) {
|
||||
|
@ -57,7 +56,6 @@ public class HttpDownloader extends Downloader {
|
|||
return;
|
||||
}
|
||||
|
||||
OkHttpClient httpClient = AntennapodHttpClient.getHttpClient();
|
||||
RandomAccessFile out = null;
|
||||
InputStream connection;
|
||||
ResponseBody responseBody = null;
|
||||
|
@ -90,7 +88,6 @@ public class HttpDownloader extends Downloader {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
// add range header if necessary
|
||||
if (fileExists && destination.length() > 0) {
|
||||
request.setSoFar(destination.length());
|
||||
|
@ -98,22 +95,7 @@ public class HttpDownloader extends Downloader {
|
|||
Log.d(TAG, "Adding range header: " + request.getSoFar());
|
||||
}
|
||||
|
||||
Response response;
|
||||
|
||||
try {
|
||||
response = httpClient.newCall(httpReq.build()).execute();
|
||||
} catch (IOException e) {
|
||||
Log.e(TAG, e.toString());
|
||||
if (e.getMessage().contains("PROTOCOL_ERROR")) {
|
||||
httpClient = httpClient.newBuilder()
|
||||
.protocols(Collections.singletonList(Protocol.HTTP_1_1))
|
||||
.build();
|
||||
response = httpClient.newCall(httpReq.build()).execute();
|
||||
} else {
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
|
||||
Response response = newCall(httpReq);
|
||||
responseBody = response.body();
|
||||
String contentEncodingHeader = response.header("Content-Encoding");
|
||||
boolean isGzip = false;
|
||||
|
@ -122,65 +104,26 @@ public class HttpDownloader extends Downloader {
|
|||
}
|
||||
|
||||
Log.d(TAG, "Response code is " + response.code());
|
||||
|
||||
if (!response.isSuccessful() && response.code() == HttpURLConnection.HTTP_NOT_MODIFIED) {
|
||||
Log.d(TAG, "Feed '" + request.getSource() + "' not modified since last update, Download canceled");
|
||||
onCancelled();
|
||||
return;
|
||||
}
|
||||
|
||||
if (!response.isSuccessful() || response.body() == null) {
|
||||
final DownloadError error;
|
||||
final String details;
|
||||
if (response.code() == HttpURLConnection.HTTP_UNAUTHORIZED) {
|
||||
error = DownloadError.ERROR_UNAUTHORIZED;
|
||||
details = String.valueOf(response.code());
|
||||
} else if (response.code() == HttpURLConnection.HTTP_FORBIDDEN) {
|
||||
error = DownloadError.ERROR_FORBIDDEN;
|
||||
details = String.valueOf(response.code());
|
||||
} else if (response.code() == HttpURLConnection.HTTP_NOT_FOUND) {
|
||||
error = DownloadError.ERROR_NOT_FOUND;
|
||||
details = String.valueOf(response.code());
|
||||
} else {
|
||||
error = DownloadError.ERROR_HTTP_DATA_ERROR;
|
||||
details = String.valueOf(response.code());
|
||||
}
|
||||
onFail(error, details);
|
||||
} else if (!response.isSuccessful() || response.body() == null) {
|
||||
callOnFailByResponseCode(response);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!StorageUtils.storageAvailable()) {
|
||||
} else if (!StorageUtils.storageAvailable()) {
|
||||
onFail(DownloadError.ERROR_DEVICE_NOT_FOUND, null);
|
||||
return;
|
||||
}
|
||||
|
||||
// fail with a file type error when the content type is text and
|
||||
// the reported content length is less than 100kb (or no length is given)
|
||||
if (request.getFeedfileType() == FeedMedia.FEEDFILETYPE_FEEDMEDIA) {
|
||||
int contentLength = -1;
|
||||
String contentLen = response.header("Content-Length");
|
||||
if (contentLen != null) {
|
||||
try {
|
||||
contentLength = Integer.parseInt(contentLen);
|
||||
} catch (NumberFormatException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
Log.d(TAG, "content length: " + contentLength);
|
||||
String contentType = response.header("Content-Type");
|
||||
Log.d(TAG, "content type: " + contentType);
|
||||
if (contentType != null && contentType.startsWith("text/") &&
|
||||
contentLength < 100 * 1024) {
|
||||
onFail(DownloadError.ERROR_FILE_TYPE, null);
|
||||
return;
|
||||
}
|
||||
} else if (request.getFeedfileType() == FeedMedia.FEEDFILETYPE_FEEDMEDIA
|
||||
&& isContentTypeTextAndSmallerThan100kb(response)) {
|
||||
onFail(DownloadError.ERROR_FILE_TYPE, null);
|
||||
return;
|
||||
}
|
||||
checkIfRedirect(response);
|
||||
|
||||
connection = new BufferedInputStream(responseBody.byteStream());
|
||||
|
||||
String contentRangeHeader = (fileExists) ? response.header("Content-Range") : null;
|
||||
|
||||
if (fileExists && response.code() == HttpURLConnection.HTTP_PARTIAL
|
||||
&& !TextUtils.isEmpty(contentRangeHeader)) {
|
||||
String start = contentRangeHeader.substring("bytes ".length(),
|
||||
|
@ -211,7 +154,6 @@ public class HttpDownloader extends Downloader {
|
|||
|
||||
long freeSpace = StorageUtils.getFreeSpaceAvailable();
|
||||
Log.d(TAG, "Free space is " + freeSpace);
|
||||
|
||||
if (request.getSize() != DownloadStatus.SIZE_UNKNOWN && request.getSize() > freeSpace) {
|
||||
onFail(DownloadError.ERROR_NOT_ENOUGH_SPACE, null);
|
||||
return;
|
||||
|
@ -233,10 +175,10 @@ public class HttpDownloader extends Downloader {
|
|||
} else {
|
||||
// check if size specified in the response header is the same as the size of the
|
||||
// written file. This check cannot be made if compression was used
|
||||
if (!isGzip && request.getSize() != DownloadStatus.SIZE_UNKNOWN &&
|
||||
request.getSoFar() != request.getSize()) {
|
||||
onFail(DownloadError.ERROR_IO_WRONG_SIZE, "Download completed but size: " +
|
||||
request.getSoFar() + " does not equal expected size " + request.getSize());
|
||||
if (!isGzip && request.getSize() != DownloadStatus.SIZE_UNKNOWN
|
||||
&& request.getSoFar() != request.getSize()) {
|
||||
onFail(DownloadError.ERROR_IO_WRONG_SIZE, "Download completed but size: "
|
||||
+ request.getSoFar() + " does not equal expected size " + request.getSize());
|
||||
return;
|
||||
} else if (request.getSize() > 0 && request.getSoFar() == 0) {
|
||||
onFail(DownloadError.ERROR_IO_ERROR, "Download completed, but nothing was read");
|
||||
|
@ -282,6 +224,59 @@ public class HttpDownloader extends Downloader {
|
|||
}
|
||||
}
|
||||
|
||||
private Response newCall(Request.Builder httpReq) throws IOException {
|
||||
OkHttpClient httpClient = AntennapodHttpClient.getHttpClient();
|
||||
try {
|
||||
return httpClient.newCall(httpReq.build()).execute();
|
||||
} catch (IOException e) {
|
||||
Log.e(TAG, e.toString());
|
||||
if (e.getMessage() != null && e.getMessage().contains("PROTOCOL_ERROR")) {
|
||||
// Apparently some servers announce they support SPDY but then actually don't.
|
||||
httpClient = httpClient.newBuilder()
|
||||
.protocols(Collections.singletonList(Protocol.HTTP_1_1))
|
||||
.build();
|
||||
return httpClient.newCall(httpReq.build()).execute();
|
||||
} else {
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private boolean isContentTypeTextAndSmallerThan100kb(Response response) {
|
||||
int contentLength = -1;
|
||||
String contentLen = response.header("Content-Length");
|
||||
if (contentLen != null) {
|
||||
try {
|
||||
contentLength = Integer.parseInt(contentLen);
|
||||
} catch (NumberFormatException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
Log.d(TAG, "content length: " + contentLength);
|
||||
String contentType = response.header("Content-Type");
|
||||
Log.d(TAG, "content type: " + contentType);
|
||||
return contentType != null && contentType.startsWith("text/") && contentLength < 100 * 1024;
|
||||
}
|
||||
|
||||
private void callOnFailByResponseCode(Response response) {
|
||||
final DownloadError error;
|
||||
final String details;
|
||||
if (response.code() == HttpURLConnection.HTTP_UNAUTHORIZED) {
|
||||
error = DownloadError.ERROR_UNAUTHORIZED;
|
||||
details = String.valueOf(response.code());
|
||||
} else if (response.code() == HttpURLConnection.HTTP_FORBIDDEN) {
|
||||
error = DownloadError.ERROR_FORBIDDEN;
|
||||
details = String.valueOf(response.code());
|
||||
} else if (response.code() == HttpURLConnection.HTTP_NOT_FOUND) {
|
||||
error = DownloadError.ERROR_NOT_FOUND;
|
||||
details = String.valueOf(response.code());
|
||||
} else {
|
||||
error = DownloadError.ERROR_HTTP_DATA_ERROR;
|
||||
details = String.valueOf(response.code());
|
||||
}
|
||||
onFail(error, details);
|
||||
}
|
||||
|
||||
private void checkIfRedirect(Response response) {
|
||||
// detect 301 Moved permanently and 308 Permanent Redirect
|
||||
ArrayList<Response> responses = new ArrayList<>();
|
||||
|
@ -307,8 +302,7 @@ public class HttpDownloader extends Downloader {
|
|||
}
|
||||
|
||||
private void onFail(DownloadError reason, String reasonDetailed) {
|
||||
Log.d(TAG, "onFail() called with: " + "reason = [" + reason + "], " +
|
||||
"reasonDetailed = [" + reasonDetailed + "]");
|
||||
Log.d(TAG, "onFail() called with: " + "reason = [" + reason + "], reasonDetailed = [" + reasonDetailed + "]");
|
||||
result.setFailed(reason, reasonDetailed);
|
||||
if (request.isDeleteOnFailure()) {
|
||||
cleanup();
|
||||
|
|
Loading…
Reference in New Issue