Merge pull request #196 from hanFengSan/master

support for range header
This commit is contained in:
Fenny 2020-02-29 16:12:39 -05:00 committed by GitHub
commit fa8e46f0a8
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 69 additions and 8 deletions

View File

@ -13,6 +13,7 @@ import (
"mime/multipart"
"net/url"
"path/filepath"
"strconv"
"strings"
"sync"
"time"
@ -36,6 +37,15 @@ type Ctx struct {
Fasthttp *fasthttp.RequestCtx
}
// RangeInfo info of range header
type RangeInfo struct {
Type string
Ranges []struct {
Start int64
End int64
}
}
// Ctx pool
var poolCtx = sync.Pool{
New: func() interface{} {
@ -548,11 +558,45 @@ func (ctx *Ctx) Query(key string) (value string) {
}
// Range : https://fiber.wiki/context#range
func (ctx *Ctx) Range() {
// https://expressjs.com/en/api.html#req.range
// https://github.com/jshttp/range-parser/blob/master/index.js
// r := ctx.Fasthttp.Request.Header.Peek(HeaderRange)
// *magic*
func (ctx *Ctx) Range(size int64) (rangeInfo RangeInfo, err error) {
rangeStr := string(ctx.Fasthttp.Request.Header.Peek("range"))
if rangeStr == "" || !strings.Contains(rangeStr, "=") {
return rangeInfo, fmt.Errorf("malformed range header string")
}
data := strings.Split(rangeStr, "=")
rangeInfo.Type = data[0]
arr := strings.Split(data[1], ",")
for i := 0; i < len(arr); i++ {
item := strings.Split(arr[i], "-")
if len(item) == 1 {
return rangeInfo, fmt.Errorf("malformed range header string")
}
start, startErr := strconv.ParseInt(item[0], 10, 64)
end, endErr := strconv.ParseInt(item[1], 10, 64)
if startErr != nil { // -nnn
start = size - end
end = size - 1
} else if endErr != nil { // nnn-
end = size - 1
}
if end > size-1 { // limit last-byte-pos to current length
end = size - 1
}
if start > end || start < 0 {
continue
}
rangeInfo.Ranges = append(rangeInfo.Ranges, struct {
Start int64
End int64
}{
start,
end,
})
}
if len(rangeInfo.Ranges) < 1 {
return rangeInfo, fmt.Errorf("unsatisfiable range")
}
return rangeInfo, nil
}
// Redirect : https://fiber.wiki/context#redirect

View File

@ -543,9 +543,26 @@ func Test_Query(t *testing.T) {
func Test_Range(t *testing.T) {
app := New()
app.Get("/test", func(c *Ctx) {
c.Range()
result, err := c.Range(1000)
if err != nil {
t.Fatalf(`%s: %s`, t.Name(), err)
return
}
expect := "bytes"
if result.Type != expect {
t.Fatalf(`%s: Expecting %s, got %s`, t.Name(), expect, result.Type)
}
expectNum := int64(500)
if result.Ranges[0].Start != expectNum {
t.Fatalf(`%s: Expecting %v, got %v`, t.Name(), expectNum, result.Ranges[0].Start)
}
expectNum = int64(700)
if result.Ranges[0].End != expectNum {
t.Fatalf(`%s: Expecting %v, got %v`, t.Name(), expectNum, result.Ranges[0].End)
}
})
req, _ := http.NewRequest("GET", "/test", nil)
req.Header.Set("range", "bytes=500-700")
_, err := app.Test(req)
if err != nil {
t.Fatalf(`%s: %s`, t.Name(), err)

4
go.mod
View File

@ -3,9 +3,9 @@ module github.com/gofiber/fiber
go 1.11
require (
github.com/gorilla/schema v1.1.0
github.com/fasthttp/websocket v1.4.2
github.com/gofiber/template v1.0.0
github.com/gorilla/schema v1.1.0
github.com/json-iterator/go v1.1.9
github.com/valyala/fasthttp v1.9.0
github.com/fasthttp/websocket v1.4.2
)