1 Star 0 Fork 0

simple/simple.io

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
文件
克隆/下载
response_decoder.go 2.81 KB
一键复制 编辑 原始数据 按行查看 历史
package http
import (
"errors"
"fmt"
"net/http"
"net/textproto"
"strconv"
"strings"
)
// ResponseDecoder 解码器, 从io缓冲区读取字节流, 并解码为response对象
type ResponseDecoder struct{}
func NewResponseDecoder() *ResponseDecoder {
return &ResponseDecoder{}
}
func (r *ResponseDecoder) Decoder(response *Response) (err error) {
defer func() {
if e := recover(); e != nil {
err = errors.New(fmt.Sprintln("Error decoding request,", e))
}
}()
if response.BufReader == nil {
return errors.New("the fufReader has no data to read")
}
r.line(response)
r.header(response)
r.contentLength(response)
r.body(response)
return
}
func (r *ResponseDecoder) line(response *Response) {
line, err := response.BufReader.ReadLine()
if err != nil {
panic(err)
}
proto, rest, ok1 := strings.Cut(line, " ")
statusCode, statusText, ok2 := strings.Cut(rest, " ")
if ok1 && ok2 {
response.Proto = proto
response.statusText = statusText
} else {
panic(errors.New("HTTP request line format error, " + line))
}
if code, err := strconv.Atoi(statusCode); err != nil {
panic(errors.New("malformed HTTP statusCode " + statusCode))
} else if http.StatusText(code) == "" {
panic(errors.New("unknown HTTP statusCode " + statusCode))
} else {
response.statusCode = code
}
var ok bool
if response.ProtoMajor, response.ProtoMinor, ok = http.ParseHTTPVersion(response.Proto); !ok {
panic(errors.New("malformed HTTP version " + response.Proto))
}
}
func (r *ResponseDecoder) header(response *Response) {
header := make(http.Header, 4)
for {
line, err := response.BufReader.ReadLine()
if err != nil {
panic(err)
}
if len(line) == 0 {
break
}
if line[0] == ' ' || line[0] == '\t' {
panic(errors.New("malformed MIME header initial line: " + line))
}
name, value, found := strings.Cut(line, string(colonSpace))
name = strings.TrimSpace(name)
value = strings.TrimSpace(value)
if name == "" || value == "" || !found {
panic(errors.New("Hearer format error: " + line))
}
if header.Get(name) == "" {
header.Add(name, value)
} else {
header.Set(name, value)
}
}
PragmaCacheControl(header)
response.Header = header
if header.Get("Server") != "" {
response.Server = header.Get("Server")
}
}
func (r *ResponseDecoder) contentLength(response *Response) {
contentLength := textproto.TrimString(response.Header.Get("Content-Length"))
if contentLength == "" {
response.contentLength = 0
return
}
if n, err := strconv.ParseUint(contentLength, 10, 63); err != nil {
response.contentLength = -1
panic(errors.New("bad Content-Length: " + contentLength))
} else {
response.contentLength = int64(n)
}
}
func (r *ResponseDecoder) body(response *Response) {
if response.contentLength > 0 {
response.body = NewReadBody(response.contentLength, response.BufReader)
return
}
}
Loading...
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化
Go
1
https://gitee.com/simple-set/simple.io.git
git@gitee.com:simple-set/simple.io.git
simple-set
simple.io
simple.io
v1.6.5

搜索帮助