优化fasthttp的header 逻辑

This commit is contained in:
huangmengzhu
2023-03-30 10:31:00 +08:00
parent 74d098dee9
commit e2d5008fac
3 changed files with 102 additions and 52 deletions

View File

@@ -83,6 +83,7 @@ func (h *HttpComplete) Complete(org eocontext.EoContext) error {
} }
lastErr = ctx.SendTo(scheme, node, timeOut) lastErr = ctx.SendTo(scheme, node, timeOut)
if lastErr == nil { if lastErr == nil {
return nil return nil
} }
log.Error("http upstream send error: ", lastErr) log.Error("http upstream send error: ", lastErr)

View File

@@ -22,16 +22,16 @@ var _ http_service.IHttpContext = (*HttpContext)(nil)
// HttpContext fasthttpRequestCtx // HttpContext fasthttpRequestCtx
type HttpContext struct { type HttpContext struct {
fastHttpRequestCtx *fasthttp.RequestCtx fastHttpRequestCtx *fasthttp.RequestCtx
proxyRequest ProxyRequest proxyRequest ProxyRequest
proxyRequests []http_service.IProxy proxyRequests []http_service.IProxy
requestID string requestID string
response Response response Response
requestReader RequestReader requestReader RequestReader
ctx context.Context ctx context.Context
completeHandler eoscContext.CompleteHandler completeHandler eoscContext.CompleteHandler
finishHandler eoscContext.FinishHandler finishHandler eoscContext.FinishHandler
app eoscContext.EoApp
balance eoscContext.BalanceHandler balance eoscContext.BalanceHandler
upstreamHostHandler eoscContext.UpstreamHostHandler upstreamHostHandler eoscContext.UpstreamHostHandler
labels map[string]string labels map[string]string
@@ -138,6 +138,7 @@ func (ctx *HttpContext) SendTo(scheme string, node eoscContext.INode, timeout ti
if ctx.response.responseError != nil { if ctx.response.responseError != nil {
agent.setStatusCode(504) agent.setStatusCode(504)
} else { } else {
ctx.response.ResponseHeader.refresh()
agent.setStatusCode(ctx.fastHttpRequestCtx.Response.StatusCode()) agent.setStatusCode(ctx.fastHttpRequestCtx.Response.StatusCode())
} }
@@ -257,7 +258,6 @@ func (ctx *HttpContext) FastFinish() {
ctx.port = 0 ctx.port = 0
ctx.ctx = nil ctx.ctx = nil
ctx.app = nil
ctx.balance = nil ctx.balance = nil
ctx.upstreamHostHandler = nil ctx.upstreamHostHandler = nil
ctx.finishHandler = nil ctx.finishHandler = nil

View File

@@ -2,11 +2,10 @@ package http_context
import ( import (
"bytes" "bytes"
http_service "github.com/eolinker/eosc/eocontext/http-context"
"net/http" "net/http"
"strings" "strings"
http_service "github.com/eolinker/eosc/eocontext/http-context"
"github.com/valyala/fasthttp" "github.com/valyala/fasthttp"
) )
@@ -77,74 +76,124 @@ func (h *RequestHeader) SetHost(host string) {
h.header.SetHost(host) h.header.SetHost(host)
} }
type headerActionHandleFunc func(target *ResponseHeader, key string, value ...string)
var (
headerActionAdd = func(target *ResponseHeader, key string, value ...string) {
target.cache.Add(key, value[0])
target.header.Add(key, value[0])
}
headerActionSet = func(target *ResponseHeader, key string, value ...string) {
target.cache.Set(key, value[0])
target.header.Set(key, value[0])
}
headerActionDel = func(target *ResponseHeader, key string, value ...string) {
target.cache.Del(key)
target.header.Del(key)
}
)
type headerAction struct {
Action headerActionHandleFunc
Key string
Value string
}
type ResponseHeader struct { type ResponseHeader struct {
header *fasthttp.ResponseHeader header *fasthttp.ResponseHeader
tmp http.Header
cache http.Header
actions []*headerAction
afterProxy bool
} }
func (r *ResponseHeader) reset(header *fasthttp.ResponseHeader) { func (r *ResponseHeader) reset(header *fasthttp.ResponseHeader) {
r.header = header
r.tmp = nil r.header = header
r.cache = http.Header{}
r.actions = nil
r.refresh()
}
func (r *ResponseHeader) refresh() {
tmp := make(http.Header)
hs := strings.Split(r.header.String(), "\r\n")
for _, t := range hs {
vs := strings.Split(t, ":")
if len(vs) < 2 {
if vs[0] == "" {
continue
}
tmp[vs[0]] = []string{""}
continue
}
tmp[vs[0]] = []string{strings.TrimSpace(vs[1])}
}
r.cache = tmp
for _, ac := range r.actions {
ac.Action(r, ac.Key, ac.Value)
}
r.afterProxy = true
r.actions = nil
} }
func (r *ResponseHeader) Finish() { func (r *ResponseHeader) Finish() {
if r.tmp != nil {
for k, vs := range r.tmp {
r.header.Del(k)
for _, v := range vs {
r.header.Add(k, v)
}
}
}
r.reset(nil) r.reset(nil)
} }
func NewResponseHeader(header *fasthttp.ResponseHeader) *ResponseHeader {
return &ResponseHeader{header: header}
}
func (r *ResponseHeader) GetHeader(name string) string { func (r *ResponseHeader) GetHeader(name string) string {
return r.Headers().Get(name) return r.Headers().Get(name)
} }
func (r *ResponseHeader) Headers() http.Header { func (r *ResponseHeader) Headers() http.Header {
return r.cache
if r.tmp == nil {
r.tmp = make(http.Header)
hs := strings.Split(r.header.String(), "\r\n")
for _, t := range hs {
vs := strings.Split(t, ":")
if len(vs) < 2 {
if vs[0] == "" {
continue
}
r.tmp[vs[0]] = []string{""}
continue
}
r.tmp[vs[0]] = []string{strings.TrimSpace(vs[1])}
}
}
return r.tmp
} }
func (r *ResponseHeader) SetHeader(key, value string) { func (r *ResponseHeader) SetHeader(key, value string) {
if r.tmp != nil {
r.tmp.Set(key, value) r.cache.Set(key, value)
if r.afterProxy {
r.header.Set(key, value)
} else {
r.actions = append(r.actions, &headerAction{
Key: key,
Value: value,
Action: headerActionSet,
})
} }
r.header.Set(key, value)
} }
func (r *ResponseHeader) AddHeader(key, value string) { func (r *ResponseHeader) AddHeader(key, value string) {
if r.tmp != nil {
r.tmp.Add(key, value) r.cache.Add(key, value)
if r.afterProxy {
r.header.Add(key, value)
} else {
r.actions = append(r.actions, &headerAction{
Key: key,
Value: value,
Action: headerActionAdd,
})
} }
r.header.Add(key, value)
} }
func (r *ResponseHeader) DelHeader(key string) { func (r *ResponseHeader) DelHeader(key string) {
if r.tmp != nil {
r.tmp.Del(key) r.cache.Del(key)
if r.afterProxy {
r.header.Del(key)
} else {
r.actions = append(r.actions, &headerAction{
Key: key,
Action: headerActionDel,
})
} }
r.header.Del(key)
} }
func (h *RequestHeader) GetCookie(key string) string { func (h *RequestHeader) GetCookie(key string) string {