代码拉取完成,页面将自动刷新
package http
import (
"errors"
"fmt"
"golang.org/x/net/http/httpguts"
"net/http"
"net/textproto"
"net/url"
"strconv"
"strings"
)
// RequestDecoder 请求解码器, 从io缓冲区读取字节流, 并解码为http请求对象, 缓冲区一般为socket连接, 也可以使字节数组等
type RequestDecoder struct {
}
// Decoder 解码入口
func (r *RequestDecoder) Decoder(request *Request) (err error) {
defer func() {
if e := recover(); e != nil {
err = errors.New(fmt.Sprintln("Error decoding request, ", e))
}
}()
if request.BufReadr == nil {
return errors.New("request buffer is empty")
}
r.line(request)
r.header(request)
r.uri(request)
r.contentLength(request)
r.body(request)
return
}
// 解码请求行
func (r *RequestDecoder) line(request *Request) {
str, err := request.BufReadr.ReadLine()
if err != nil {
panic(errors.New("HTTP request line format error, " + err.Error()))
}
line := strings.TrimSpace(str)
method, rest, ok1 := strings.Cut(line, " ")
requestURI, proto, ok2 := strings.Cut(rest, " ")
if ok1 && ok2 {
request.Method = method
request.RequestURI = requestURI
request.Proto = proto
} else {
panic(errors.New("HTTP request line format error, " + line))
}
if len(request.Method) < 0 || !ValidMethod(request.Method) || !ValidPath(request.RequestURI) {
panic(errors.New("invalid request " + request.Method + " " + request.RequestURI))
}
var ok bool
if request.ProtoMajor, request.ProtoMinor, ok = http.ParseHTTPVersion(request.Proto); !ok {
panic(errors.New("malformed HTTP version " + request.Proto))
}
}
// 解码请求头
func (r *RequestDecoder) header(request *Request) {
header := make(http.Header, 4)
for {
str, err := request.BufReadr.ReadLine()
if err != nil {
panic(errors.New("HTTP request line format error, " + err.Error()))
}
line := strings.TrimSpace(str)
if len(line) == 0 {
break
}
if line[0] == ' ' || line[0] == '\t' {
panic(badRequestError("malformed MIME header initial line: " + line))
}
name, value, found := strings.Cut(line, ":")
name = strings.TrimSpace(name)
value = strings.TrimSpace(value)
if name == "" || value == "" || !found {
panic(badRequestError("Hearer format error: " + line))
}
if !httpguts.ValidHeaderFieldName(name) {
panic(badRequestError("invalid header name: " + value))
}
if !httpguts.ValidHeaderFieldValue(value) {
panic(badRequestError("invalid header value: " + value))
}
if header.Get(name) == "" {
header.Add(name, value)
} else {
header.Set(name, value)
}
}
request.Header = header
request.Host = header.Get("Host")
// 解析表单数据
_ = request.ParseForm()
// 调整缓存头
PragmaCacheControl(header)
}
// 解码请求URL, RFC 7230, Request-URI: "*" | absoluteURI | abs_path | authority
func (r *RequestDecoder) uri(request *Request) {
var err error
if strings.HasPrefix(request.RequestURI, "http://") {
// absoluteURI
request.URL, err = url.ParseRequestURI(request.RequestURI)
} else if strings.HasPrefix(request.RequestURI, "/") {
// abs_path
request.URL, err = url.ParseRequestURI("http://" + request.Host + request.RequestURI)
} else if !strings.HasPrefix(request.RequestURI, "*") {
// authority
request.URL, err = url.ParseRequestURI("http://" + request.RequestURI)
request.URL.Path = "/"
}
if err != nil {
panic(errors.New("HTTP request uri format error, " + err.Error()))
}
if request.URL.Host != "" {
request.Host = request.URL.Host
}
}
// 解码请求体长度
func (r *RequestDecoder) contentLength(request *Request) {
contentLength := textproto.TrimString(request.Header.Get("Content-Length"))
if contentLength == "" {
request.ContentLength = 0
} else if n, err := strconv.ParseUint(contentLength, 10, 63); err != nil {
request.ContentLength = -1
panic(errors.New("bad Content-Length: " + contentLength))
} else {
request.ContentLength = int64(n)
}
}
// 解码请求体
func (r *RequestDecoder) body(request *Request) {
if request.ContentLength > 0 {
request.body = NewReadBody(request.ContentLength, request.BufReadr)
}
}
// NewRequestDecoder 构造函数
func NewRequestDecoder() *RequestDecoder {
return &RequestDecoder{}
}
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。