Files
EdgeNode/internal/nodes/http_request_utils.go

128 lines
2.1 KiB
Go
Raw Normal View History

package nodes
import (
"crypto/rand"
"fmt"
"io"
"strconv"
"strings"
)
// 分解Range
func httpRequestParseContentRange(rangeValue string) (result [][]int, ok bool) {
// 参考RFChttps://tools.ietf.org/html/rfc7233
index := strings.Index(rangeValue, "=")
if index == -1 {
return
}
unit := rangeValue[:index]
if unit != "bytes" {
return
}
rangeSetString := rangeValue[index+1:]
if len(rangeSetString) == 0 {
ok = true
return
}
pieces := strings.Split(rangeSetString, ", ")
for _, piece := range pieces {
index := strings.Index(piece, "-")
if index == -1 {
return
}
first := piece[:index]
firstInt := -1
var err error
last := piece[index+1:]
var lastInt = -1
if len(first) > 0 {
firstInt, err = strconv.Atoi(first)
if err != nil {
return
}
if len(last) > 0 {
lastInt, err = strconv.Atoi(last)
if err != nil {
return
}
if lastInt < firstInt {
return
}
}
} else {
if len(last) == 0 {
return
}
lastInt, err = strconv.Atoi(last)
if err != nil {
return
}
lastInt = -lastInt
}
result = append(result, []int{firstInt, lastInt})
}
ok = true
return
}
// 读取内容Range
func httpRequestReadRange(reader io.Reader, buf []byte, start int, end int, callback func(buf []byte, n int) error) (ok bool, err error) {
if start < 0 || end < 0 {
return
}
seeker, ok := reader.(io.Seeker)
if !ok {
return
}
_, err = seeker.Seek(int64(start), io.SeekStart)
if err != nil {
return false, nil
}
offset := start
for {
n, err := reader.Read(buf)
if n > 0 {
offset += n
if end < offset {
err = callback(buf, n-(offset-end-1))
if err != nil {
return false, err
}
return true, nil
} else {
err = callback(buf, n)
if err != nil {
return false, err
}
}
}
if err != nil {
if err == io.EOF {
return true, nil
}
return false, err
}
}
}
// 生成boundary
// 仿照Golang自带的函数multipart包
func httpRequestGenBoundary() string {
var buf [30]byte
_, err := io.ReadFull(rand.Reader, buf[:])
if err != nil {
panic(err)
}
return fmt.Sprintf("%x", buf[:])
}