Files
apinto/node/http-context/context.go
2021-08-09 11:10:46 +08:00

226 lines
5.3 KiB
Go

package http_context
import (
"encoding/json"
"net/http"
uuid2 "github.com/satori/go.uuid"
"github.com/valyala/fasthttp"
goku_plugin "github.com/eolinker/goku-standard-plugin"
access_field "github.com/eolinker/goku-eosc/node/common/access-field"
"github.com/eolinker/goku-eosc/utils"
)
var _ goku_plugin.ContextProxy = (*Context)(nil)
//Context context
type Context struct {
responseWriter *fasthttp.RequestCtx
*CookiesHandler
*PriorityHeader
*StatusHandler
*StoreHandler
RequestOrg *RequestReader
ProxyRequest *Request
ProxyResponseHandler *ResponseReader
Body []byte
requestID string
RestfulParam map[string]string
LogFields *access_field.Fields
labels map[string]string
}
func (ctx *Context) Labels() map[string]string {
if ctx.labels == nil {
ctx.labels = map[string]string{}
}
return ctx.labels
}
func (ctx *Context) SetLabels(labels map[string]string) {
if ctx.labels == nil {
ctx.labels = make(map[string]string)
}
if labels != nil {
for k, v := range labels {
ctx.labels[k] = v
}
}
}
//Finish finish
func (ctx *Context) Finish() (statusCode int) {
defer ctx.responseWriter.Done()
header := ctx.PriorityHeader.header
statusCode = ctx.StatusHandler.code
if statusCode == 0 {
statusCode = 504
}
ctx.LogFields.StatusCode = statusCode
bodyAllowed := true
switch {
case statusCode >= 100 && statusCode <= 199:
bodyAllowed = false
break
case statusCode == 204:
bodyAllowed = false
break
case statusCode == 304:
bodyAllowed = false
break
}
if ctx.PriorityHeader.appendHeader != nil {
for k, vs := range ctx.PriorityHeader.appendHeader.header {
for _, v := range vs {
header.Add(k, v)
}
}
}
if ctx.PriorityHeader.setHeader != nil {
for k, vs := range ctx.PriorityHeader.setHeader.header {
header.Del(k)
for _, v := range vs {
header.Add(k, v)
}
}
}
for k, vs := range ctx.PriorityHeader.header {
if k == "Content-Length" {
continue
//vs = []string{strconv.Itoa(len(string(ctx.body)))}
}
for _, v := range vs {
ctx.responseWriter.Response.Header.Add(k, v)
}
}
if ctx.ProxyResponseHandler.header.Get("Content-Type") == "" {
ctx.responseWriter.Response.Header.Set("Content-Type", "application/json")
}
if ctx.ProxyResponseHandler.header.Get("Content-Encoding") == "gzip" {
body, err := utils.GzipCompress(ctx.Body)
if err == nil {
ctx.Body = body
}
}
ctx.responseWriter.SetStatusCode(statusCode)
//ctx.LogFields.ResponseHeader = utils.HeaderToString(ctx.header)
if !bodyAllowed {
return statusCode
}
ctx.responseWriter.SetBody(ctx.Body)
ctx.LogFields.ResponseMsg = string(ctx.Body)
ctx.LogFields.ResponseMsgSize = len(ctx.Body)
return statusCode
}
//RequestId 请求ID
func (ctx *Context) RequestId() string {
return ctx.requestID
}
//NewContext 创建Context
func NewContext(requestCtx *fasthttp.RequestCtx) *Context {
//requestID := uuid.New()
id := uuid2.NewV4()
requestID := id.String()
requestReader := NewRequestReader(requestCtx.Request)
ctx := &Context{
responseWriter: requestCtx,
CookiesHandler: newCookieHandle(requestReader.header),
PriorityHeader: NewPriorityHeader(),
StatusHandler: NewStatusHandler(),
StoreHandler: NewStoreHandler(),
RequestOrg: requestReader,
ProxyRequest: NewRequest(requestReader),
ProxyResponseHandler: nil,
requestID: requestID,
LogFields: access_field.NewFields(),
}
//ctx.LogFields.RequestHeader = utils.HeaderToString(requestReader.Headers())
ctx.LogFields.RequestMsg = string(ctx.RequestOrg.rawBody)
ctx.LogFields.RequestMsgSize = len(ctx.RequestOrg.rawBody)
ctx.LogFields.RequestUri = requestReader.req.URL.RequestURI()
ctx.LogFields.RequestID = requestID
return ctx
}
//SetProxyResponse 设置转发响应
func (ctx *Context) SetProxyResponse(response *http.Response) {
ctx.SetProxyResponseHandler(newResponseReader(response))
}
//SetProxyResponseHandler 设置转发响应处理器
func (ctx *Context) SetProxyResponseHandler(response *ResponseReader) {
ctx.ProxyResponseHandler = response
if ctx.ProxyResponseHandler != nil {
ctx.Body = ctx.ProxyResponseHandler.body
ctx.SetStatus(ctx.ProxyResponseHandler.StatusCode(), ctx.ProxyResponseHandler.Status())
ctx.header = ctx.ProxyResponseHandler.header
}
}
//func (ctx *Context) Write(w http.ResponseWriter) {
// if ctx.StatusCode() == 0 {
// ctx.SetStatus(200, "200 ok")
// }
// if ctx.Body != nil {
// w.Write(ctx.Body)
// }
//
// w.WriteHeader(ctx.StatusCode())
//
//}
//GetBody 获取请求body
func (ctx *Context) GetBody() []byte {
return ctx.Body
}
//SetBody 设置body
func (ctx *Context) SetBody(data []byte) {
ctx.Body = data
}
func (ctx *Context) SetError(err error) {
result := map[string]string{
"status": "error",
"msg": err.Error(),
}
errByte, _ := json.Marshal(result)
ctx.Body = errByte
}
//ProxyResponse 返回响应
func (ctx *Context) ProxyResponse() goku_plugin.ResponseReader {
return ctx.ProxyResponseHandler
}
//Request 获取原始请求
func (ctx *Context) Request() goku_plugin.RequestReader {
return ctx.RequestOrg
}
//Proxy 代理
func (ctx *Context) Proxy() goku_plugin.Request {
return ctx.ProxyRequest
}
func NotFound(ctx *Context) {
ctx.responseWriter.SetStatusCode(404)
ctx.responseWriter.SetBody([]byte("404 Not Found"))
}