Merge pull request #62 from amir1376/improve-download-engine-wrong-content-range-header-fix

some servers send wrong content-range headers now handled correctly
This commit is contained in:
AmirHossein Abdolmotallebi 2024-09-04 10:01:19 -07:00 committed by GitHub
commit 84b6497135
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 36 additions and 27 deletions

View File

@ -22,12 +22,16 @@ data class ResponseInfo(
responseHeaders["content-length"]?.toLongOrNull()?.takeIf { it >= 0L }
}
val contentRange by lazy {
getContentRange()
}
//total length of whole file even if it is partial content
val totalLength by lazy {
val responseLength = contentLength ?: return@lazy null
// partial length only valid when we have content-length header
if (isPartial) {
getContentRange()?.fullSize
contentRange?.fullSize ?: responseLength
} else responseLength
}
val requiresAuth by lazy {
@ -43,8 +47,8 @@ data class ResponseInfo(
}
val resumeSupport by lazy {
// maybe server does not give us content-length, so we ignore resume support
isPartial && contentLength != null
// maybe server does not give us content-length or content-range, so we ignore resume support
isPartial && contentLength != null && contentRange?.fullSize!=null
}
val fileName: String? by lazy {

View File

@ -7,37 +7,42 @@ data class ContentRangeValue(
val fullSize: Long?,
)
fun ResponseInfo.getContentRange(): ContentRangeValue?{
val value=responseHeaders["content-range"]?:return null
val actualValue=runCatching {
fun ResponseInfo.getContentRange(): ContentRangeValue? {
val value = responseHeaders["content-range"] ?: return null
val actualValue = runCatching {
value.substring("bytes ".length)
}.getOrNull()?:return null
if (actualValue.isBlank()){
}.getOrNull() ?: return null
if (actualValue.isBlank()) {
return null
}
var from:Long?=null
var to:Long?=null
var size:Long?=null
val (rangeString,sizeString)=actualValue.split("/")
if (rangeString!="*"){
rangeString.split("-").map {
it.toLong()
}.let {
from=it[0]
to=it[1]
val (rangeString, sizeString) = actualValue
.split("/")
.takeIf { it.size >= 2 } ?: return null
val range = try {
if (rangeString != "*") {
rangeString.split("-").map {
it.toLong()
}.let {
it[0]..it[1]
}
} else {
null
}
}
if (sizeString!="*"){
size=sizeString.toLong()
} catch (e: Exception) {
// NumberFormatException or IndexOutOfBoundException
return null
}
val size: Long? = if (sizeString != "*") {
// some servers not returning * nor integer value.
sizeString.toLongOrNull() ?: return null
} else null
return ContentRangeValue(
range = from?.let {f->
to?.let {t->
f..t
}
},
fullSize=size
range = range,
fullSize = size,
)
}