MCPcopy Create free account
hub / github.com/couchbase/sync_gateway / parseHTTPRangeHeader

Function parseHTTPRangeHeader

rest/handler.go:1748–1805  ·  view source on GitHub ↗

Given an HTTP "Range:" header value, parses it and returns the approppriate HTTP status code, and the numeric byte range if appropriate: - If the Range header is empty or syntactically invalid, it ignores it and returns status=200. - If the header is valid but exceeds the contentLength, it returns s

(rangeStr string, contentLength uint64)

Source from the content-addressed store, hash-verified

1746// - Otherwise it returns status=206 and sets the start and end values in HTTP terms, i.e. with
1747// the first byte numbered 0, and the end value inclusive (so the first 100 bytes are 0-99.)
1748func parseHTTPRangeHeader(rangeStr string, contentLength uint64) (status int, start uint64, end uint64) {
1749 // http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.35
1750 status = http.StatusOK
1751 if rangeStr == "" {
1752 return
1753 }
1754 match := kRangeRegex.FindStringSubmatch(rangeStr)
1755 if match == nil || (match[1] == "" && match[2] == "") {
1756 return
1757 }
1758 startStr, endStr := match[1], match[2]
1759 var err error
1760
1761 start = 0
1762 if startStr != "" {
1763 // byte-range-spec
1764 if start, err = strconv.ParseUint(startStr, 10, 64); err != nil {
1765 start = math.MaxUint64 // string is all digits, so must just be too big for uint64
1766 }
1767 } else if endStr == "" {
1768 return // "-" is an invalid range spec
1769 }
1770
1771 end = contentLength - 1
1772 if endStr != "" {
1773 if end, err = strconv.ParseUint(endStr, 10, 64); err != nil {
1774 end = math.MaxUint64 // string is all digits, so must just be too big for uint64
1775 }
1776 if startStr == "" {
1777 // suffix-range-spec ("-nnn" means the last nnn bytes)
1778 if end == 0 {
1779 return http.StatusRequestedRangeNotSatisfiable, 0, 0
1780 } else if contentLength == 0 {
1781 return
1782 } else if end > contentLength {
1783 end = contentLength
1784 }
1785 start = contentLength - end
1786 end = contentLength - 1
1787 } else {
1788 if end < start {
1789 return // invalid range
1790 }
1791 if end >= contentLength {
1792 end = contentLength - 1 // trim to end of content
1793 }
1794 }
1795 }
1796 if start >= contentLength {
1797 return http.StatusRequestedRangeNotSatisfiable, 0, 0
1798 } else if start == 0 && end == contentLength-1 {
1799 return // no-op
1800 }
1801
1802 // OK, it's a subrange:
1803 status = http.StatusPartialContent
1804 return
1805}

Callers 2

handleRangeMethod · 0.85
TestParseHTTPRangeHeaderFunction · 0.85

Calls

no outgoing calls

Tested by 1

TestParseHTTPRangeHeaderFunction · 0.68