dependencies: Don't retry downloading in case of bad HTTP response

#KT-20194 Fixed
This commit is contained in:
Ilya Matveev
2017-09-19 12:32:20 +03:00
committed by ilmat192
parent 2f4163ece6
commit c37e650da2
@@ -31,10 +31,25 @@ class DependencyDownloader(
RETURN_EXISTING RETURN_EXISTING
} }
class HTTPResponseException(val url: URL, val responseCode: Int)
: IOException("Server returned HTTP response code: $responseCode for URL: $url")
class DownloadingProgress(@Volatile var currentBytes: Long) { class DownloadingProgress(@Volatile var currentBytes: Long) {
fun update(readBytes: Int) { currentBytes += readBytes } fun update(readBytes: Int) { currentBytes += readBytes }
} }
private fun HttpURLConnection.checkHTTPResponse(expected: Int, originalUrl: URL = url) {
if (responseCode != expected) {
throw HTTPResponseException(originalUrl, responseCode)
}
}
private fun HttpURLConnection.checkHTTPResponse(originalUrl: URL, predicate: (Int) -> Boolean) {
if (!predicate(responseCode)) {
throw HTTPResponseException(originalUrl, responseCode)
}
}
private fun doDownload(originalUrl: URL, private fun doDownload(originalUrl: URL,
connection: URLConnection, connection: URLConnection,
tmpFile: File, tmpFile: File,
@@ -91,6 +106,9 @@ class DependencyDownloader(
val rangeConnection = originalUrl.openConnection() as HttpURLConnection val rangeConnection = originalUrl.openConnection() as HttpURLConnection
rangeConnection.setRequestProperty("range", "bytes=$currentBytes-") rangeConnection.setRequestProperty("range", "bytes=$currentBytes-")
rangeConnection.connect() rangeConnection.connect()
rangeConnection.checkHTTPResponse(originalUrl) {
it == HttpURLConnection.HTTP_PARTIAL || it == HttpURLConnection.HTTP_OK
}
doDownload(originalUrl, rangeConnection, tmpFile, currentBytes, totalBytes, true) doDownload(originalUrl, rangeConnection, tmpFile, currentBytes, totalBytes, true)
} }
} }
@@ -98,6 +116,9 @@ class DependencyDownloader(
/** Performs an attempt to download a specified file into the specified location */ /** Performs an attempt to download a specified file into the specified location */
private fun tryDownload(url: URL, tmpFile: File) { private fun tryDownload(url: URL, tmpFile: File) {
val connection = url.openConnection() val connection = url.openConnection()
(connection as? HttpURLConnection)?.checkHTTPResponse(HttpURLConnection.HTTP_OK, url)
if (connection is HttpURLConnection && tmpFile.exists()) { if (connection is HttpURLConnection && tmpFile.exists()) {
resumeDownload(url, connection, tmpFile) resumeDownload(url, connection, tmpFile)
} else { } else {
@@ -134,6 +155,8 @@ class DependencyDownloader(
try { try {
tryDownload(source, tmpFile) tryDownload(source, tmpFile)
break break
} catch (e: HTTPResponseException) {
throw e
} catch (e: IOException) { } catch (e: IOException) {
if (attempt >= maxAttempts) { if (attempt >= maxAttempts) {
throw e throw e