mirror of
https://github.com/amir1376/ab-download-manager.git
synced 2025-02-20 11:43:24 +08:00
Merge pull request #135 from amir1376/fix/close-connection-when-response-is-not-2xx
close connection if download response is not successful
This commit is contained in:
commit
62a8bb73c4
@ -53,7 +53,7 @@ class PartDownloader(
|
|||||||
val part: Part,
|
val part: Part,
|
||||||
val client: DownloaderClient,
|
val client: DownloaderClient,
|
||||||
val speedLimiters: List<Throttler>,
|
val speedLimiters: List<Throttler>,
|
||||||
val strictMode:Boolean,
|
val strictMode: Boolean,
|
||||||
private val partSplitLock: Any,
|
private val partSplitLock: Any,
|
||||||
) {
|
) {
|
||||||
class ShouldNotHappened(msg: String?) : RuntimeException(msg)
|
class ShouldNotHappened(msg: String?) : RuntimeException(msg)
|
||||||
@ -66,7 +66,16 @@ class PartDownloader(
|
|||||||
): Connection {
|
): Connection {
|
||||||
val connect = client.connect(credentials, from, to)
|
val connect = client.connect(credentials, from, to)
|
||||||
// make sure this is a 2xx response
|
// make sure this is a 2xx response
|
||||||
connect.responseInfo.expectSuccess()
|
kotlin.runCatching {
|
||||||
|
connect.responseInfo.expectSuccess()
|
||||||
|
}
|
||||||
|
.onFailure {
|
||||||
|
// close connection before throwing exception
|
||||||
|
kotlin.runCatching {
|
||||||
|
connect.closeable.close()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.getOrThrow()
|
||||||
val source = speedLimiters.fold<Throttler, Source>(connect.source) { acc, throttler ->
|
val source = speedLimiters.fold<Throttler, Source>(connect.source) { acc, throttler ->
|
||||||
throttler.source(acc)
|
throttler.source(acc)
|
||||||
}
|
}
|
||||||
@ -132,7 +141,8 @@ class PartDownloader(
|
|||||||
iCantRetryAnymore(
|
iCantRetryAnymore(
|
||||||
PartTooManyErrorException(
|
PartTooManyErrorException(
|
||||||
part,
|
part,
|
||||||
lastException?:Exception("BUG : if you see me please report it to the developer! when we encounter error so it have to be a least one last exception"),
|
lastException
|
||||||
|
?: Exception("BUG : if you see me please report it to the developer! when we encounter error so it have to be a least one last exception"),
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@ -144,7 +154,7 @@ class PartDownloader(
|
|||||||
} catch (e: Exception) {
|
} catch (e: Exception) {
|
||||||
tries++
|
tries++
|
||||||
onCanceled(e)
|
onCanceled(e)
|
||||||
when(canRetry(e)){
|
when (canRetry(e)) {
|
||||||
CanRetryResult.Yes -> continue
|
CanRetryResult.Yes -> continue
|
||||||
CanRetryResult.No -> {}
|
CanRetryResult.No -> {}
|
||||||
CanRetryResult.NoAndStopDownloadJob -> iCantRetryAnymore(e)
|
CanRetryResult.NoAndStopDownloadJob -> iCantRetryAnymore(e)
|
||||||
@ -160,7 +170,7 @@ class PartDownloader(
|
|||||||
when (status) {
|
when (status) {
|
||||||
is PartDownloadStatus.Canceled -> {
|
is PartDownloadStatus.Canceled -> {
|
||||||
tries++
|
tries++
|
||||||
when(canRetry(status.e)){
|
when (canRetry(status.e)) {
|
||||||
CanRetryResult.Yes -> continue
|
CanRetryResult.Yes -> continue
|
||||||
CanRetryResult.No -> {}
|
CanRetryResult.No -> {}
|
||||||
CanRetryResult.NoAndStopDownloadJob -> iCantRetryAnymore(status.e)
|
CanRetryResult.NoAndStopDownloadJob -> iCantRetryAnymore(status.e)
|
||||||
@ -187,10 +197,10 @@ class PartDownloader(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private sealed interface CanRetryResult{
|
private sealed interface CanRetryResult {
|
||||||
data object Yes:CanRetryResult
|
data object Yes : CanRetryResult
|
||||||
data object No:CanRetryResult
|
data object No : CanRetryResult
|
||||||
data object NoAndStopDownloadJob:CanRetryResult
|
data object NoAndStopDownloadJob : CanRetryResult
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun canRetry(e: Throwable): CanRetryResult {
|
private fun canRetry(e: Throwable): CanRetryResult {
|
||||||
@ -198,13 +208,15 @@ class PartDownloader(
|
|||||||
ExceptionUtils.isNormalCancellation(e) -> {
|
ExceptionUtils.isNormalCancellation(e) -> {
|
||||||
CanRetryResult.No
|
CanRetryResult.No
|
||||||
}
|
}
|
||||||
e is DownloadValidationException -> if (e.isCritical()){
|
|
||||||
|
e is DownloadValidationException -> if (e.isCritical()) {
|
||||||
//download validation occurs, and also it is critical,
|
//download validation occurs, and also it is critical,
|
||||||
//so we can't proceed any further
|
//so we can't proceed any further
|
||||||
CanRetryResult.NoAndStopDownloadJob
|
CanRetryResult.NoAndStopDownloadJob
|
||||||
}else{
|
} else {
|
||||||
CanRetryResult.Yes
|
CanRetryResult.Yes
|
||||||
}
|
}
|
||||||
|
|
||||||
else -> {
|
else -> {
|
||||||
CanRetryResult.Yes
|
CanRetryResult.Yes
|
||||||
}
|
}
|
||||||
@ -252,7 +264,7 @@ class PartDownloader(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (contentLength != partCopy.remainingLength) {
|
if (contentLength != partCopy.remainingLength) {
|
||||||
if (strictMode){
|
if (strictMode) {
|
||||||
conn.closeable.close()
|
conn.closeable.close()
|
||||||
throw ServerPartIsNotTheSameAsWeExpectException(
|
throw ServerPartIsNotTheSameAsWeExpectException(
|
||||||
start = partCopy.current,
|
start = partCopy.current,
|
||||||
@ -411,12 +423,12 @@ suspend fun PartDownloader.awaitFinishOrError(): PartDownloadStatus {
|
|||||||
when (it) {
|
when (it) {
|
||||||
PartDownloadStatus.Completed,
|
PartDownloadStatus.Completed,
|
||||||
is PartDownloadStatus.Canceled,
|
is PartDownloadStatus.Canceled,
|
||||||
-> true
|
-> true
|
||||||
|
|
||||||
PartDownloadStatus.ReceivingData,
|
PartDownloadStatus.ReceivingData,
|
||||||
PartDownloadStatus.SendGet,
|
PartDownloadStatus.SendGet,
|
||||||
PartDownloadStatus.IDLE,
|
PartDownloadStatus.IDLE,
|
||||||
-> false
|
-> false
|
||||||
}
|
}
|
||||||
}.first()
|
}.first()
|
||||||
}
|
}
|
||||||
@ -427,12 +439,12 @@ suspend fun PartDownloader.awaitToEnsureDataBeingTransferred(): Boolean {
|
|||||||
when (it) {
|
when (it) {
|
||||||
PartDownloadStatus.Completed,
|
PartDownloadStatus.Completed,
|
||||||
PartDownloadStatus.ReceivingData,
|
PartDownloadStatus.ReceivingData,
|
||||||
-> true
|
-> true
|
||||||
|
|
||||||
is PartDownloadStatus.Canceled,
|
is PartDownloadStatus.Canceled,
|
||||||
PartDownloadStatus.SendGet,
|
PartDownloadStatus.SendGet,
|
||||||
PartDownloadStatus.IDLE,
|
PartDownloadStatus.IDLE,
|
||||||
-> false
|
-> false
|
||||||
}
|
}
|
||||||
}.first().let {
|
}.first().let {
|
||||||
when (it) {
|
when (it) {
|
||||||
@ -441,7 +453,7 @@ suspend fun PartDownloader.awaitToEnsureDataBeingTransferred(): Boolean {
|
|||||||
PartDownloadStatus.ReceivingData -> true
|
PartDownloadStatus.ReceivingData -> true
|
||||||
PartDownloadStatus.SendGet,
|
PartDownloadStatus.SendGet,
|
||||||
PartDownloadStatus.IDLE,
|
PartDownloadStatus.IDLE,
|
||||||
-> error("should not happen")
|
-> error("should not happen")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
isThatOk
|
isThatOk
|
||||||
@ -454,11 +466,11 @@ suspend fun PartDownloader.awaitIdle() {
|
|||||||
is PartDownloadStatus.Canceled,
|
is PartDownloadStatus.Canceled,
|
||||||
PartDownloadStatus.Completed,
|
PartDownloadStatus.Completed,
|
||||||
PartDownloadStatus.IDLE,
|
PartDownloadStatus.IDLE,
|
||||||
-> true
|
-> true
|
||||||
|
|
||||||
PartDownloadStatus.SendGet,
|
PartDownloadStatus.SendGet,
|
||||||
PartDownloadStatus.ReceivingData,
|
PartDownloadStatus.ReceivingData,
|
||||||
-> false
|
-> false
|
||||||
}
|
}
|
||||||
}.first()
|
}.first()
|
||||||
}
|
}
|
Loading…
x
Reference in New Issue
Block a user