1 Star 0 Fork 0

carlmax_my/console-core-go

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
文件
克隆/下载
context.go 10.05 KB
一键复制 编辑 原始数据 按行查看 历史
carlmax_my 提交于 2024-12-02 21:32 . init project
package core
import (
"bytes"
stdctx "context"
"io"
"net/http"
"net/url"
"strings"
"sync"
"gitee.com/carlmax_my/console-core-go/pkg/errors"
"gitee.com/carlmax_my/console-core-go/pkg/trace"
"github.com/gin-gonic/gin"
"github.com/gin-gonic/gin/binding"
"go.uber.org/zap"
)
type HandlerFunc func(c Context)
type Trace = trace.T
const (
_Alias = "_alias_"
_TraceName = "_trace_"
_LoggerName = "_logger_"
_BodyName = "_body_"
_PayloadName = "_payload_"
_SessionUser = "_session_user_"
_SessionUserErr = "_session_user_err_"
_AbortErrorName = "_abort_error_"
_IsRecordMetrics = "_is_record_metrics_"
)
var contextPool = &sync.Pool{
New: func() interface{} {
return new(context)
},
}
func NewContext(ctx *gin.Context) Context {
context := contextPool.Get().(*context)
context.ctx = ctx
return context
}
func ReleaseContext(ctx Context) {
c := ctx.(*context)
c.ctx = nil
contextPool.Put(c)
}
var _ Context = (*context)(nil)
type Context interface {
Init()
// ShouldBindQuery 反序列化 querystring
// tag: `form:"xxx"` (注:不要写成 query)
ShouldBindQuery(obj interface{}) error
// ShouldBindPostForm 反序列化 postform (querystring会被忽略)
// tag: `form:"xxx"`
ShouldBindPostForm(obj interface{}) error
// ShouldBindForm 同时反序列化 querystring 和 postform;
// 当 querystring 和 postform 存在相同字段时,postform 优先使用。
// tag: `form:"xxx"`
ShouldBindForm(obj interface{}) error
// ShouldBindJSON 反序列化 postjson
// tag: `json:"xxx"`
ShouldBindJSON(obj interface{}) error
// ShouldBindURI 反序列化 path 参数(如路由路径为 /user/:name)
// tag: `uri:"xxx"`
ShouldBindURI(obj interface{}) error
// Redirect 重定向
Redirect(code int, location string)
// Trace 获取 Trace 对象
Trace() Trace
SetTrace(trace Trace)
disableTrace()
// Logger 获取 Logger 对象
Logger() *zap.Logger
SetLogger(logger *zap.Logger)
// Payload 正确返回
Payload(payload interface{})
GetPayload() interface{}
// HTML 返回界面
HTML(name string, obj interface{})
// AbortWithError 错误返回
AbortWithError(err BusinessError)
AbortError() BusinessError
Abort()
JSON(code int, data any)
// Header 获取 Header 对象
Header() http.Header
// GetHeader 获取 Header
GetHeader(key string) string
// SetHeader 设置 Header
SetHeader(key, value string)
// GetCookie 获取 cookie
GetCookie(key string) string
// SetCookie 设置 cookie
SetCookie(key, value string, maxAge int, path string, host string)
Get(key string) (any, bool)
Set(key string, value any)
Next()
UserAgent() string
// SessionUser 当前用户信息
SessionUser() (interface{}, error)
SetSessionUser(info interface{})
// SessionUserErr 当前用户error信息
SessionUserErr() *string
SetSessionUserErr(err *string)
Param(key string) string
Query(key string) string
// Alias 设置路由别名 for metrics path
Alias() string
setAlias(path string)
// disableRecordMetrics 设置禁止记录指标
disableRecordMetrics()
AbleRecordMetrics()
IsRecordMetrics() bool
// RequestInputParams 获取所有参数
RequestInputParams() url.Values
// RequestPostFormParams 获取 PostForm 参数
RequestPostFormParams() url.Values
// Request 获取 Request 对象
Request() *http.Request
// RawData 获取 Request.Body
RawData() []byte
// Method 获取 Request.Method
Method() string
// Host 获取 Request.Host
Host() string
// Path 获取 请求的路径 Request.URL.Path (不附带 querystring)
Path() string
// URI 获取 unescape 后的 Request.URL.RequestURI()
URI() string
// RequestContext 获取请求的 context (当 client 关闭后,会自动 canceled)
RequestContext() StdContext
// ResponseWriter 获取 ResponseWriter 对象
ResponseWriter() gin.ResponseWriter
}
type context struct {
ctx *gin.Context
}
type StdContext struct {
stdctx.Context
Trace
*zap.Logger
}
func (c *context) Init() {
body, err := c.ctx.GetRawData()
if err != nil {
panic(err)
}
c.ctx.Set(_BodyName, body) // cache body是为了trace使用
c.ctx.Request.Body = io.NopCloser(bytes.NewBuffer(body)) // re-construct req body
}
// ShouldBindQuery 反序列化querystring
// tag: `form:"xxx"` (注:不要写成query)
func (c *context) ShouldBindQuery(obj interface{}) error {
return c.ctx.ShouldBindWith(obj, binding.Query)
}
// ShouldBindPostForm 反序列化 postform (querystring 会被忽略)
// tag: `form:"xxx"`
func (c *context) ShouldBindPostForm(obj interface{}) error {
return c.ctx.ShouldBindWith(obj, binding.FormPost)
}
// ShouldBindForm 同时反序列化querystring和postform;
// 当querystring和postform存在相同字段时,postform优先使用。
// tag: `form:"xxx"`
func (c *context) ShouldBindForm(obj interface{}) error {
return c.ctx.ShouldBindWith(obj, binding.Form)
}
// ShouldBindJSON 反序列化postjson
// tag: `json:"xxx"`
func (c *context) ShouldBindJSON(obj interface{}) error {
return c.ctx.ShouldBindWith(obj, binding.JSON)
}
// ShouldBindURI 反序列化path参数(如路由路径为 /user/:name)
// tag: `uri:"xxx"`
func (c *context) ShouldBindURI(obj interface{}) error {
return c.ctx.ShouldBindUri(obj)
}
// Redirect redirect
func (c *context) Redirect(code int, location string) {
c.ctx.Redirect(code, location)
}
func (c *context) Trace() Trace {
t, ok := c.ctx.Get(_TraceName)
if !ok || t == nil {
return nil
}
return t.(Trace)
}
func (c *context) SetTrace(trace Trace) {
c.ctx.Set(_TraceName, trace)
}
func (c *context) disableTrace() {
c.SetTrace(nil)
}
func (c *context) Logger() *zap.Logger {
logger, ok := c.ctx.Get(_LoggerName)
if !ok {
return nil
}
return logger.(*zap.Logger)
}
func (c *context) SetLogger(logger *zap.Logger) {
c.ctx.Set(_LoggerName, logger)
}
func (c *context) GetPayload() interface{} {
if payload, ok := c.ctx.Get(_PayloadName); ok {
return payload
}
return nil
}
func (c *context) Payload(payload interface{}) {
c.ctx.Set(_PayloadName, payload)
}
func (c *context) HTML(name string, obj interface{}) {
c.ctx.HTML(200, name+".html", obj)
}
func (c *context) Header() http.Header {
header := c.ctx.Request.Header
clone := make(http.Header, len(header))
for k, v := range header {
value := make([]string, len(v))
copy(value, v)
clone[k] = value
}
return clone
}
func (c *context) GetHeader(key string) string {
return c.ctx.GetHeader(key)
}
func (c *context) SetHeader(key, value string) {
c.ctx.Header(key, value)
}
func (c *context) GetCookie(key string) (s string) {
s, _ = c.ctx.Cookie(key)
return
}
// TODO
func (c *context) SetCookie(key, value string, maxAge int, path string, host string) {
c.ctx.SetCookie(key, value, maxAge, path, host, false, false)
}
func (c *context) Get(key string) (any, bool) {
return c.ctx.Get(key)
}
func (c *context) Set(key string, value any) {
c.ctx.Set(key, value)
}
func (c *context) Next() {
c.ctx.Next()
}
func (c *context) UserAgent() string {
return c.GetHeader("User-Agent")
}
func (c *context) SessionUser() (interface{}, error) {
val, _ := c.ctx.Get(_SessionUser)
if val == nil {
err := c.SessionUserErr()
if err == nil {
return nil, errors.New("user not found from cache with unknown error")
} else if *err == "" {
return nil, errors.New("user not found from cache with empty error")
} else {
return nil, errors.New(*err)
}
}
return val, nil
}
func (c *context) SetSessionUser(info interface{}) {
c.ctx.Set(_SessionUser, info)
}
func (c *context) SessionUserErr() *string {
value, _ := c.ctx.Get(_SessionUserErr)
if value == nil {
return nil
}
return value.(*string)
}
func (c *context) SetSessionUserErr(err *string) {
c.ctx.Set(_SessionUserErr, err)
}
func (c *context) AbortWithError(err BusinessError) {
if err != nil {
httpCode := err.HTTPCode()
if httpCode == 0 {
httpCode = http.StatusInternalServerError
}
c.ctx.AbortWithStatus(httpCode)
c.ctx.Set(_AbortErrorName, err)
}
}
func (c *context) AbortError() BusinessError {
err, _ := c.ctx.Get(_AbortErrorName)
return err.(BusinessError)
}
func (c *context) Abort() {
c.ctx.Abort()
}
func (c *context) JSON(code int, data any) {
c.ctx.JSON(code, data)
}
func (c *context) Alias() string {
path, ok := c.ctx.Get(_Alias)
if !ok {
return ""
}
return path.(string)
}
func (c *context) setAlias(path string) {
if path = strings.TrimSpace(path); path != "" {
c.ctx.Set(_Alias, path)
}
}
func (c *context) IsRecordMetrics() bool {
val, ok := c.ctx.Get(_IsRecordMetrics)
if !ok {
return false
}
return val.(bool)
}
func (c *context) AbleRecordMetrics() {
c.ctx.Set(_IsRecordMetrics, true)
}
func (c *context) disableRecordMetrics() {
c.ctx.Set(_IsRecordMetrics, false)
}
// RequestInputParams 获取所有参数
func (c *context) RequestInputParams() url.Values {
_ = c.ctx.Request.ParseForm()
return c.ctx.Request.Form
}
// RequestPostFormParams 获取 PostForm 参数
func (c *context) RequestPostFormParams() url.Values {
_ = c.ctx.Request.ParseForm()
return c.ctx.Request.PostForm
}
// Request 获取 Request
func (c *context) Request() *http.Request {
return c.ctx.Request
}
func (c *context) RawData() []byte {
body, ok := c.ctx.Get(_BodyName)
if !ok {
return nil
}
return body.([]byte)
}
// Method 请求的method
func (c *context) Method() string {
return c.ctx.Request.Method
}
// Host 请求的host
func (c *context) Host() string {
return c.ctx.Request.Host
}
// Path 请求的路径(不附带querystring)
func (c *context) Path() string {
return c.ctx.Request.URL.Path
}
// URI unescape后的uri
func (c *context) URI() string {
uri, _ := url.QueryUnescape(c.ctx.Request.URL.RequestURI())
return uri
}
// RequestContext (包装 Trace + Logger) 获取请求的 context (当client关闭后,会自动canceled)
func (c *context) RequestContext() StdContext {
return StdContext{
//c.ctx.Request.Context(),
stdctx.Background(),
c.Trace(),
c.Logger(),
}
}
// ResponseWriter 获取 ResponseWriter
func (c *context) ResponseWriter() gin.ResponseWriter {
return c.ctx.Writer
}
func (c *context) Param(key string) string {
return c.ctx.Param(key)
}
func (c *context) Query(key string) string {
return c.ctx.Query(key)
}
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化
Go
1
https://gitee.com/carlmax_my/console-core-go.git
git@gitee.com:carlmax_my/console-core-go.git
carlmax_my
console-core-go
console-core-go
v0.0.20

搜索帮助

0d507c66 1850385 C8b1a773 1850385