代码拉取完成,页面将自动刷新
package app
import (
"bytes"
"context"
"encoding/json"
"errors"
"fmt"
"gitee.com/zhucheer/orange/database"
"gitee.com/zhucheer/orange/logger"
"gitee.com/zhucheer/orange/request"
"gitee.com/zhucheer/orange/session"
"gitee.com/zhucheer/orange/utils"
"github.com/gomodule/redigo/redis"
"github.com/google/uuid"
"gorm.io/gorm"
"io"
"net/http"
"os"
"path"
"strconv"
"strings"
"sync"
"time"
)
type Context struct {
CsrfToken string
OrangeInput *request.OrangeInput
response http.ResponseWriter
request *http.Request
path string
pnames []string
pvalues []string
ctx context.Context
session session.Store
responseBody *bytes.Buffer
responseStatus int
panicMsg interface{}
ms time.Duration
userParams map[string]interface{}
redirect string
view *viewTmpl
afterDelayDoFuncs []afterDelayFunc
mutx sync.Mutex
dbConn map[string]interface{}
srvType string
}
type afterDelayFunc struct {
doFunc func(ctx *Context)
delay time.Duration
}
func NewCtx(ctx context.Context, w http.ResponseWriter, r *http.Request) *Context {
traceId := uuid.New().String()
orangeCtx := &Context{
srvType: srvTypeHttp,
ctx: context.WithValue(ctx, TraceName, traceId),
response: &orangeWrite{ResponseWriter: w},
request: r,
pnames: make([]string, 0),
pvalues: make([]string, *routers.maxParam),
view: newViewTmpl(),
responseBody: new(bytes.Buffer),
}
orangeCtx.SetCtxParam(TraceName, traceId)
logger.WithContext(orangeCtx.ctx)
return orangeCtx
}
func NewGrpcCtx(ctx context.Context) *Context {
traceId := uuid.New().String()
orangeCtx := &Context{
srvType: srvTypeGrpc,
ctx: context.WithValue(ctx, TraceName, traceId),
pnames: make([]string, 0),
pvalues: make([]string, *routers.maxParam),
responseBody: new(bytes.Buffer),
}
orangeCtx.SetCtxParam(TraceName, traceId)
logger.WithContext(orangeCtx.ctx)
return orangeCtx
}
func (c *Context) SetRW(w http.ResponseWriter, r *http.Request) {
c.response = w
c.request = r
}
func (c *Context) Redirect(tourl string) error {
c.redirect = tourl
return nil
}
func (c *Context) HttpError(error string, code int) {
http.Error(c.response, error, code)
}
func (c *Context) ResponseWrite(b []byte) error {
_, err := c.responseBody.Write(b)
return err
}
func (c *Context) ResponseBody() []byte {
return c.responseBody.Bytes()
}
func (c *Context) ResponseReset() {
c.responseBody.Reset()
}
func (c *Context) ResponseWriteHeader(code int) {
c.response.WriteHeader(code)
}
func (c *Context) ResponseHeader() http.Header {
return c.response.Header()
}
func (c *Context) SetPanic(panicMsg interface{}) {
c.panicMsg = panicMsg
}
func (c *Context) SetResponseStatus(status int) {
c.responseStatus = status
}
func (c *Context) ResponseStatus() int {
w, _ := c.response.(*orangeWrite)
return w.statusCode
}
func (c *Context) Header() http.Header {
return c.request.Header
}
func (c *Context) Session() session.Store {
if c.session == nil {
logger.Warning("session is not open")
return nil
}
return c.session
}
func (c *Context) GetPathParam(name string) (val string) {
return c.getPathParam(name)
}
func (c *Context) GetPathParamToInt(name string) (val int) {
val, _ = strconv.Atoi(c.getPathParam(name))
return
}
func (c *Context) getPathParam(name string) (val string) {
var paramIndex *int
for k, item := range c.pnames {
if item == name {
indexNum := k
paramIndex = new(int)
paramIndex = &indexNum
break
}
}
if paramIndex != nil && *paramIndex < len(c.pvalues) {
val = c.pvalues[*paramIndex]
}
return
}
func (c *Context) SetCtxParam(key string, value interface{}) {
c.mutx.Lock()
defer c.mutx.Unlock()
if c.userParams == nil {
c.userParams = make(map[string]interface{})
}
c.userParams[key] = value
}
func (c *Context) GetCtxParam(key string) (val interface{}) {
if c.userParams == nil {
return
}
if val, ok := c.userParams[key]; ok {
return val
}
return
}
func (c *Context) SetCookie(cookie *http.Cookie) {
http.SetCookie(c.response, cookie)
}
func (c *Context) Request() *http.Request {
return c.request
}
// RunHttpHandler 执行自定义 http handler
func (c *Context) RunHttpHandler(h http.Handler) {
h.ServeHTTP(c.response, c.request)
}
func (c *Context) SetContext(ctx context.Context) context.Context {
c.ctx = ctx
return c.ctx
}
func (c *Context) Context() context.Context {
return c.ctx
}
func (c *Context) RoutePath() string {
return c.path
}
func (c *Context) GetMs() time.Duration {
return c.ms
}
func (c *Context) AddDelayAfterDo(handlerFunc func(ctx *Context), delay time.Duration) {
c.afterDelayDoFuncs = append(c.afterDelayDoFuncs, afterDelayFunc{
handlerFunc, delay,
})
}
func (c *Context) ToJson(data interface{}) error {
c.response.Header().Set("Content-Type", "application/json;charset=UTF-8")
jsonBytes, err := json.Marshal(data)
if err != nil {
c.response.WriteHeader(500)
c.response.Write([]byte(err.Error()))
return err
}
c.ResponseWrite(jsonBytes)
return nil
}
func (c *Context) ToString(data string) error {
c.response.Header().Set("Content-Type", "text/html;charset=UTF-8")
c.ResponseWrite([]byte(data))
return nil
}
// 通过文件流方式输出图片
func (c *Context) ToImage(filePath string) error {
if exists, _ := utils.FileExists(filePath); exists == false {
return NotFoundHandler(c)
}
file, err := os.Open(filePath)
if err != nil {
return NotFoundHandler(c)
}
defer file.Close()
ext := strings.TrimLeft(path.Ext(filePath), ".")
buf := make([]byte, 32)
c.response.Header().Set("Content-Type", "image/"+ext)
for {
_, err := file.Read(buf)
if err != nil {
if err == io.EOF {
break
} else {
panic(err)
}
}
c.response.Write(buf)
}
return nil
}
// 通过文件流方式输出
func (c *Context) ToFile(filePath string, fileName string) error {
if exists, _ := utils.FileExists(filePath); exists == false {
return NotFoundHandler(c)
}
file, err := os.Open(filePath)
if err != nil {
return NotFoundHandler(c)
}
defer file.Close()
if fileName == "" {
fileName = path.Base(filePath)
}
buf := make([]byte, 32)
c.response.Header().Set("Content-Disposition", "attachment;filename="+fileName)
c.response.Header().Set("Content-Type", " application/octet-stream")
for {
_, err := file.Read(buf)
if err != nil {
if err == io.EOF {
break
} else {
panic(err)
}
}
c.response.Write(buf)
}
return nil
}
// GetMysql 上下文中获取MySQL连接
func (c *Context) GetMysql(dbName string) (db *gorm.DB, err error) {
c.mutx.Lock()
defer c.mutx.Unlock()
if c.dbConn == nil {
c.dbConn = make(map[string]interface{})
}
dbKey := fmt.Sprintf("mysql:%s", dbName)
if item, ok := c.dbConn[dbKey]; ok && item != nil {
db, _ = item.(*gorm.DB)
if db == nil {
return nil, errors.New("db connect get error")
}
return
}
var put func()
db, put, err = database.GetMysql(dbName)
if err != nil {
return
}
c.dbConn[dbKey] = db
c.afterDelayDoFuncs = append(c.afterDelayDoFuncs, afterDelayFunc{
func(ctx *Context) {
c.mutx.Lock()
defer c.mutx.Unlock()
put()
delete(c.dbConn, dbKey)
}, 0,
})
return
}
// GetRedis 上下文中获取Redis连接
func (c *Context) GetRedis(dbName string) (db redis.Conn, err error) {
c.mutx.Lock()
defer c.mutx.Unlock()
if c.dbConn == nil {
c.dbConn = make(map[string]interface{})
}
dbKey := fmt.Sprintf("redis:%s", dbName)
if item, ok := c.dbConn[dbKey]; ok && item != nil {
db, _ = item.(redis.Conn)
if db == nil {
return nil, errors.New("redis connect get error")
}
return
}
var put func()
db, put, err = database.GetRedis(dbName)
if err != nil {
return
}
c.dbConn[dbKey] = db
c.afterDelayDoFuncs = append(c.afterDelayDoFuncs, afterDelayFunc{
func(ctx *Context) {
c.mutx.Lock()
defer c.mutx.Unlock()
put()
delete(c.dbConn, dbKey)
}, 0,
})
return
}
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。