untested Range support

This commit is contained in:
Brad Fitzpatrick 2010-08-02 19:30:00 -07:00
parent e360dbee7c
commit 47de79266d
3 changed files with 77 additions and 1 deletions

View File

@ -29,8 +29,34 @@ func handleGet(conn *http.Conn, req *http.Request) {
serverError(conn, err)
return
}
reqRange := getRequestedRange(req)
if reqRange.SkipBytes != 0 {
_, err = file.Seek(reqRange.SkipBytes, 0)
if err != nil {
serverError(conn, err)
return
}
}
var input io.Reader = file
if reqRange.LimitBytes != -1 {
input = io.LimitReader(file, reqRange.LimitBytes)
}
conn.SetHeader("Content-Type", "application/octet-stream")
bytesCopied, err := io.Copy(conn, file)
if !reqRange.IsWholeFile() {
remainBytes := stat.Size - reqRange.SkipBytes
if reqRange.LimitBytes != -1 &&
reqRange.LimitBytes < remainBytes {
remainBytes = reqRange.LimitBytes
}
conn.SetHeader("Content-Range",
fmt.Sprintf("%d-%d/%d", reqRange.SkipBytes,
reqRange.SkipBytes + remainBytes,
stat.Size))
}
bytesCopied, err := io.Copy(conn, input)
// If there's an error at this point, it's too late to tell the client,
// as they've already been receiving bytes. But they should be smart enough

43
blobserver/go/range.go Normal file
View File

@ -0,0 +1,43 @@
package main
import (
"http"
"regexp"
"strconv"
)
// Default is {0, -1} to read all of a file.
type requestedRange struct {
SkipBytes int64
LimitBytes int64 // or -1 to read all
}
func (rr *requestedRange) IsWholeFile() bool {
return rr.SkipBytes == 0 && rr.LimitBytes == -1;
}
var wholeRange = &requestedRange{0, -1}
var rangePattern = regexp.MustCompile(`bytes=([0-9]+)-([0-9]*)`)
func getRequestedRange(req *http.Request) *requestedRange {
rrange, ok := req.Header["Range"]
if !ok {
return wholeRange
}
return getRequestedRangeFromString(rrange)
}
func getRequestedRangeFromString(rrange string) *requestedRange {
matches := rangePattern.MatchStrings(rrange)
if len(matches) == 0 {
return wholeRange;
}
limitBytes := int64(-1)
if len(matches[2]) > 0 {
limitBytes, _ = strconv.Atoi64(matches[2])
}
skipBytes, _ := strconv.Atoi64(matches[1])
limitBytes -= skipBytes
return &requestedRange{skipBytes, limitBytes}
}

View File

@ -0,0 +1,7 @@
package main
import "testing"
func testRange(t *t.Testing) {
}