package httprange
import (
)
type contentRangeHeader struct {
Unit string
Resp string
}
func ( string) (contentRangeHeader, bool) {
, , := strings.Cut(, " ")
if ! || == "" {
return contentRangeHeader{}, false
}
for , := range {
if httpguts.IsTokenRune() {
continue
}
return contentRangeHeader{}, false
}
for , := range {
if > 0 && < 0x80 {
continue
}
return contentRangeHeader{}, false
}
return contentRangeHeader{
Unit: ,
Resp: ,
}, true
}
func ( http.Header, string) (string, error) {
:= .Get(httpHeaderContentRange)
, := parseContentRange()
if ! {
return "", fmt.Errorf(
"httprange: invalid Content-Range header value %q",
,
)
}
if !equalFoldASCII(.Unit, ) {
return "", fmt.Errorf(
"httprange: unexpected range unit %q (expected %q)",
.Unit, ,
)
}
return .Resp, nil
}
type unsatisfiedRangeResp struct {
CompleteLength int64
}
func ( string) (unsatisfiedRangeResp, bool) {
, := strings.CutPrefix(, "*/")
if ! || !isDigits() {
return unsatisfiedRangeResp{}, false
}
, := strconv.ParseInt(, 10, 64)
if != nil {
return unsatisfiedRangeResp{}, false
}
return unsatisfiedRangeResp{
CompleteLength: ,
}, true
}
type bytesRangeResp struct {
First, Last int64
CompleteLength int64
}
func ( string) (bytesRangeResp, bool) {
, , := strings.Cut(, "/")
if ! {
return bytesRangeResp{}, false
}
:= != "*"
if && !isDigits() {
return bytesRangeResp{}, false
}
, , := strings.Cut(, "-")
if ! || !isDigits() || !isDigits() {
return bytesRangeResp{}, false
}
, := strconv.ParseInt(, 10, 64)
if != nil {
return bytesRangeResp{}, false
}
, := strconv.ParseInt(, 10, 64)
if != nil {
return bytesRangeResp{}, false
}
if > {
return bytesRangeResp{}, false
}
var int64
if {
, = strconv.ParseInt(, 10, 64)
if != nil {
return bytesRangeResp{}, false
}
if >= {
return bytesRangeResp{}, false
}
}
return bytesRangeResp{
First: ,
Last: ,
CompleteLength: ,
}, true
}
func ( string) bool {
if == "" {
return false
}
for := range len() {
if !isDigitASCII([]) {
return false
}
}
return true
}
func ( byte) bool {
return '0' <= && <= '9'
}