Files
quark-go/pkg/builder/request.go
tangtanglove 5244508c40 first commit
2023-01-18 13:40:07 +08:00

230 lines
5.9 KiB
Go

package builder
import (
"encoding/json"
"strings"
"github.com/derekstavis/go-qs"
"github.com/gobeam/stringy"
)
type Request struct {
IPString string `json:"IPString"` // 请求的ip地址
HeaderString string `json:"headerString"` // 请求的Header字符串
MethodString string `json:"methodString"` // 请求方法
FullPathString string `json:"fullPathString"` // 路由
HostString string `json:"hostString"` // 主机地址
PathString string `json:"pathString"` // URL路径
QueryString string `json:"queryString"` // 请求参数
Headers map[string]string `json:"headers"` // 请求的Headers
Params map[string]string `json:"params"` // URL param
Querys map[string]interface{} `json:"querys"` // URL querys
BodyBuffer []byte `json:"bodyBuffer"` // 请求的Body数据
}
type ParamValue struct {
Key int
Value string
}
// 初始化
func (p *Request) Init() *Request {
p.parseParams()
p.parseHeaders()
p.parseQuerys()
return p
}
// Method return request method.
//
// Returned value is valid until returning from RequestHandler.
func (p *Request) Method() string {
return p.MethodString
}
// FullPath returns a matched route full path. For not found routes
// returns an empty string.
//
// router.GET("/user/:id", func(c *hertz.RequestContext) {
// c.FullPath() == "/user/:id" // true
// })
func (p *Request) FullPath() string {
return p.FullPathString
}
// Host returns requested host.
//
// The host is valid until returning from RequestHandler.
func (p *Request) Host() string {
return p.HostString
}
// Path returns requested path.
//
// The path is valid until returning from RequestHandler.
func (p *Request) Path() string {
return p.PathString
}
// IP tries to parse the headers in [X-Real-Ip, X-Forwarded-For]. It calls RemoteIP() under the hood
func (p *Request) IP() string {
return p.IPString
}
// OriginalURL returns url query data
func (p *Request) OriginalURL() string {
return p.QueryString
}
// Body returns body data
func (p *Request) Body() []byte {
return p.BodyBuffer
}
// Param returns the value of the URL param.
// It is a shortcut for c.Params.ByName(key)
func (p *Request) parseParams() {
params := map[string]string{}
fullPaths := strings.Split(p.FullPath(), "/")
paramValues := []*ParamValue{}
for k, v := range fullPaths {
if strings.Contains(v, ":") {
v = stringy.New(v).ReplaceFirst(":", "")
mapValue := &ParamValue{
Key: k,
Value: v,
}
paramValues = append(paramValues, mapValue)
}
}
paths := strings.Split(p.Path(), "/")
for _, v := range paramValues {
params[v.Value] = paths[v.Key]
}
p.Params = params
}
// Param returns the value of the URL param.
// It is a shortcut for c.Params.ByName(key)
//
// router.GET("/user/:id", func(c *hertz.RequestContext) {
// // a GET request to /user/john
// id := c.Param("id") // id == "john"
// })
func (p *Request) Param(key string) string {
return p.Params[key]
}
// Query returns the value of the URL Querys.
func (p *Request) parseQuerys() {
querys, err := qs.Unmarshal(p.QueryString)
if err == nil {
p.Querys = querys
}
}
// Query returns the value of the URL query.
func (p *Request) Query(params ...interface{}) interface{} {
if len(params) == 2 {
if p.Querys[params[0].(string)] == nil {
return params[1]
}
}
return p.Querys[params[0].(string)]
}
// AllQuerys returns all query arguments from RequestURI.
func (p *Request) AllQuerys() map[string]interface{} {
return p.Querys
}
// ResourceName returns the value of the URL Resource param.
// If request path is "/api/admin/login/index" and route is "/api/admin/login/:resource"
//
// resourceName := p.ResourceName() // resourceName = "index"
func (p *Request) ResourceName() string {
return p.Param("resource")
}
// BodyParser binds the request body to a struct.
// It supports decoding the following content types based on the Content-Type header:
// application/json, application/xml, application/x-www-form-urlencoded, multipart/form-data
// If none of the content types above are matched, it will return a ErrUnprocessableEntity error
func (p *Request) BodyParser(out interface{}) error {
return json.Unmarshal(p.BodyBuffer, out)
}
// 解析头部数据
func (p *Request) parseHeaders() {
params := map[string]string{}
headers := strings.Split(p.HeaderString, "\r\n")
for _, v := range headers {
header := strings.Split(v, ": ")
if len(header) == 2 {
params[header[0]] = header[1]
}
}
p.Headers = params
}
// 获取请求头数据
func (p *Request) Header(key string) string {
return p.Headers[key]
}
// 获取Header中的token
func (p *Request) Token() string {
authorization := p.Header("Authorization")
authorizations := strings.Split(authorization, " ")
if len(authorizations) == 2 {
return authorizations[1]
}
queryToken := p.Query("token", "")
if queryToken.(string) != "" {
return queryToken.(string)
}
return ""
}
// 判断当前页面是否为列表页面 todo
func (p *Request) IsIndex() bool {
uri := strings.Split(p.Path(), "/")
return (uri[len(uri)-1] == "index")
}
//判断当前页面是否为创建页面
func (p *Request) IsCreating() bool {
uri := strings.Split(p.Path(), "/")
return (uri[len(uri)-1] == "create") || (uri[len(uri)-1] == "store")
}
// 判断当前页面是否为编辑页面
func (p *Request) IsEditing() bool {
uri := strings.Split(p.Path(), "/")
return (uri[len(uri)-1] == "edit") || (uri[len(uri)-1] == "update")
}
// 判断当前页面是否为详情页面
func (p *Request) IsDetail() bool {
uri := strings.Split(p.Path(), "/")
return (uri[len(uri)-1] == "detail")
}
// 判断当前页面是否为导出页面
func (p *Request) isExport() bool {
uri := strings.Split(p.Path(), "/")
return (uri[len(uri)-1] == "export")
}