@@ -13,6 +13,7 @@ import (
13
13
"mime/multipart"
14
14
"net/url"
15
15
"path/filepath"
16
+ "strconv"
16
17
"strings"
17
18
"sync"
18
19
"time"
@@ -36,6 +37,15 @@ type Ctx struct {
36
37
Fasthttp * fasthttp.RequestCtx
37
38
}
38
39
40
+ // RangeInfo info of range header
41
+ type RangeInfo struct {
42
+ Type string
43
+ Ranges []struct {
44
+ Start int64
45
+ End int64
46
+ }
47
+ }
48
+
39
49
// Ctx pool
40
50
var poolCtx = sync.Pool {
41
51
New : func () interface {} {
@@ -548,11 +558,45 @@ func (ctx *Ctx) Query(key string) (value string) {
548
558
}
549
559
550
560
// Range : https://fiber.wiki/context#range
551
- func (ctx * Ctx ) Range () {
552
- // https://expressjs.com/en/api.html#req.range
553
- // https://github.com/jshttp/range-parser/blob/master/index.js
554
- // r := ctx.Fasthttp.Request.Header.Peek(HeaderRange)
555
- // *magic*
561
+ func (ctx * Ctx ) Range (size int64 ) (rangeInfo RangeInfo , err error ) {
562
+ rangeStr := string (ctx .Fasthttp .Request .Header .Peek ("range" ))
563
+ if rangeStr == "" || ! strings .Contains (rangeStr , "=" ) {
564
+ return rangeInfo , fmt .Errorf ("malformed range header string" )
565
+ }
566
+ data := strings .Split (rangeStr , "=" )
567
+ rangeInfo .Type = data [0 ]
568
+ arr := strings .Split (data [1 ], "," )
569
+ for i := 0 ; i < len (arr ); i ++ {
570
+ item := strings .Split (arr [i ], "-" )
571
+ if len (item ) == 1 {
572
+ return rangeInfo , fmt .Errorf ("malformed range header string" )
573
+ }
574
+ start , startErr := strconv .ParseInt (item [0 ], 10 , 64 )
575
+ end , endErr := strconv .ParseInt (item [1 ], 10 , 64 )
576
+ if startErr != nil { // -nnn
577
+ start = size - end
578
+ end = size - 1
579
+ } else if endErr != nil { // nnn-
580
+ end = size - 1
581
+ }
582
+ if end > size - 1 { // limit last-byte-pos to current length
583
+ end = size - 1
584
+ }
585
+ if start > end || start < 0 {
586
+ continue
587
+ }
588
+ rangeInfo .Ranges = append (rangeInfo .Ranges , struct {
589
+ Start int64
590
+ End int64
591
+ }{
592
+ start ,
593
+ end ,
594
+ })
595
+ }
596
+ if len (rangeInfo .Ranges ) < 1 {
597
+ return rangeInfo , fmt .Errorf ("unsatisfiable range" )
598
+ }
599
+ return rangeInfo , nil
556
600
}
557
601
558
602
// Redirect : https://fiber.wiki/context#redirect
0 commit comments