mirror of
https://github.com/quarkcloudio/quark-go.git
synced 2025-09-26 20:11:11 +08:00
230 lines
5.9 KiB
Go
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")
|
|
}
|