MCPcopy Create free account
hub / github.com/cloudreve/cloudreve / parseRange

Function parseRange

pkg/filemanager/manager/entitysource/entitysource.go:982–1054  ·  view source on GitHub ↗

parseRange parses a Range header string as per RFC 7233. errNoOverlap is returned if none of the ranges overlap.

(s string, size int64)

Source from the content-addressed store, hash-verified

980// parseRange parses a Range header string as per RFC 7233.
981// errNoOverlap is returned if none of the ranges overlap.
982func parseRange(s string, size int64) ([]httpRange, error) {
983 if s == "" {
984 return nil, nil // header not present
985 }
986 const b = "bytes="
987 if !strings.HasPrefix(s, b) {
988 return nil, errors.New("invalid range")
989 }
990 var ranges []httpRange
991 noOverlap := false
992 for _, ra := range strings.Split(s[len(b):], ",") {
993 ra = textproto.TrimString(ra)
994 if ra == "" {
995 continue
996 }
997 start, end, ok := strings.Cut(ra, "-")
998 if !ok {
999 return nil, errors.New("invalid range")
1000 }
1001 start, end = textproto.TrimString(start), textproto.TrimString(end)
1002 var r httpRange
1003 if start == "" {
1004 // If no start is specified, end specifies the
1005 // range start relative to the end of the file,
1006 // and we are dealing with <suffix-length>
1007 // which has to be a non-negative integer as per
1008 // RFC 7233 Section 2.1 "Byte-Ranges".
1009 if end == "" || end[0] == '-' {
1010 return nil, errors.New("invalid range")
1011 }
1012 i, err := strconv.ParseInt(end, 10, 64)
1013 if i < 0 || err != nil {
1014 return nil, errors.New("invalid range")
1015 }
1016 if i > size {
1017 i = size
1018 }
1019 r.start = size - i
1020 r.length = size - r.start
1021 } else {
1022 i, err := strconv.ParseInt(start, 10, 64)
1023 if err != nil || i < 0 {
1024 return nil, errors.New("invalid range")
1025 }
1026 if i >= size {
1027 // If the range begins after the size of the content,
1028 // then it does not overlap.
1029 noOverlap = true
1030 continue
1031 }
1032 r.start = i
1033 if end == "" {
1034 // If no end is specified, range extends to end of the file.
1035 r.length = size - r.start
1036 } else {
1037 i, err := strconv.ParseInt(end, 10, 64)
1038 if err != nil || r.start > i {
1039 return nil, errors.New("invalid range")

Callers 1

ServeMethod · 0.85

Calls 1

NewMethod · 0.65

Tested by

no test coverage detected