mirror of
https://github.com/rclone/rclone.git
synced 2025-12-11 22:14:05 +01:00
backend/http: support content-range response header
This commit is contained in:
39
lib/rest/headers.go
Normal file
39
lib/rest/headers.go
Normal file
@@ -0,0 +1,39 @@
|
||||
package rest
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
"strconv"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// ParseSizeFromHeaders parses HTTP response headers to get the full file size.
|
||||
// Returns -1 if the headers did not exist or were invalid.
|
||||
func ParseSizeFromHeaders(headers http.Header) (size int64) {
|
||||
size = -1
|
||||
|
||||
var contentLength = headers.Get("Content-Length")
|
||||
if len(contentLength) != 0 {
|
||||
var err error
|
||||
if size, err = strconv.ParseInt(contentLength, 10, 64); err != nil {
|
||||
return -1
|
||||
}
|
||||
}
|
||||
|
||||
var contentRange = headers.Get("Content-Range")
|
||||
if len(contentRange) == 0 {
|
||||
return size
|
||||
}
|
||||
|
||||
if !strings.HasPrefix(contentRange, "bytes ") {
|
||||
return -1
|
||||
}
|
||||
slash := strings.IndexRune(contentRange, '/')
|
||||
if slash < 0 {
|
||||
return -1
|
||||
}
|
||||
ret, err := strconv.ParseInt(contentRange[slash+1:], 10, 64)
|
||||
if err != nil {
|
||||
return -1
|
||||
}
|
||||
return ret
|
||||
}
|
||||
41
lib/rest/headers_test.go
Normal file
41
lib/rest/headers_test.go
Normal file
@@ -0,0 +1,41 @@
|
||||
package rest
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func TestParseSizeFromHeaders(t *testing.T) {
|
||||
testCases := []struct {
|
||||
ContentLength, ContentRange string
|
||||
Size int64
|
||||
}{{
|
||||
"", "", -1,
|
||||
}, {
|
||||
"42", "", 42,
|
||||
}, {
|
||||
"42", "invalid", -1,
|
||||
}, {
|
||||
"", "bytes 22-33/42", 42,
|
||||
}, {
|
||||
"12", "bytes 22-33/42", 42,
|
||||
}, {
|
||||
"12", "otherUnit 22-33/42", -1,
|
||||
}, {
|
||||
"12", "bytes 22-33/*", -1,
|
||||
}, {
|
||||
"0", "bytes */42", 42,
|
||||
}}
|
||||
for _, testCase := range testCases {
|
||||
headers := make(http.Header, 2)
|
||||
if len(testCase.ContentLength) > 0 {
|
||||
headers.Set("Content-Length", testCase.ContentLength)
|
||||
}
|
||||
if len(testCase.ContentRange) > 0 {
|
||||
headers.Set("Content-Range", testCase.ContentRange)
|
||||
}
|
||||
assert.Equalf(t, testCase.Size, ParseSizeFromHeaders(headers), "%+v", testCase)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user