优化文件传输占用内存问题

This commit is contained in:
Liujian
2025-10-29 16:51:44 +08:00
parent 1423c1707d
commit fbcc48fe5c
4 changed files with 52 additions and 22 deletions

View File

@@ -9,7 +9,7 @@ Version=$(genVersion $1)
echo ${Version} echo ${Version}
Username="eolinker" Username="eolinker"
if [[ "$1" != "" ]] if [[ "$2" != "" ]]
then then
Username=$2 Username=$2
fi fi

View File

@@ -31,10 +31,10 @@ func (a *additionalParam) Execute(ctx http_service.IHttpContext) error {
return nil return nil
} }
contentType, _, _ := mime.ParseMediaType(ctx.Proxy().Body().ContentType()) contentType, _, _ := mime.ParseMediaType(ctx.Proxy().Body().ContentType())
bodyParams, formParams, err := parseBodyParams(ctx) var bodyParams interface{}
if err != nil { var formParams map[string][]string
return fmt.Errorf(`fail to parse body! [err]: %v`, err) var err error
}
for _, p := range a.params { for _, p := range a.params {
conflict := p.Conflict conflict := p.Conflict
if conflict == "" { if conflict == "" {
@@ -45,6 +45,12 @@ func (a *additionalParam) Execute(ctx http_service.IHttpContext) error {
if ctx.Proxy().Method() != http.MethodPost && ctx.Proxy().Method() != http.MethodPut && ctx.Proxy().Method() != http.MethodPatch { if ctx.Proxy().Method() != http.MethodPost && ctx.Proxy().Method() != http.MethodPut && ctx.Proxy().Method() != http.MethodPatch {
continue continue
} }
if bodyParams == nil && formParams == nil {
bodyParams, formParams, err = parseBodyParams(ctx)
if err != nil {
return fmt.Errorf(`fail to parse body! [err]: %v`, err)
}
}
switch contentType { switch contentType {
case http_context.FormData, http_context.MultipartForm: case http_context.FormData, http_context.MultipartForm:
switch p.Conflict { switch p.Conflict {

View File

@@ -2,6 +2,7 @@ package http_context
import ( import (
"bytes" "bytes"
"github.com/eolinker/eosc/log"
"io" "io"
"strings" "strings"
@@ -32,7 +33,8 @@ const (
type BodyRequestHandler struct { type BodyRequestHandler struct {
request *fasthttp.Request request *fasthttp.Request
formdata *multipart.Form formdata *multipart.Form
isResetFile bool
} }
func (b *BodyRequestHandler) MultipartForm() (*multipart.Form, error) { func (b *BodyRequestHandler) MultipartForm() (*multipart.Form, error) {
@@ -52,7 +54,8 @@ func (b *BodyRequestHandler) MultipartForm() (*multipart.Form, error) {
File: form.File, File: form.File,
} }
return form, b.resetFile() //return form, b.resetFile()
return form, nil
} }
func (b *BodyRequestHandler) Files() (map[string][]*multipart.FileHeader, error) { func (b *BodyRequestHandler) Files() (map[string][]*multipart.FileHeader, error) {
form, err := b.MultipartForm() form, err := b.MultipartForm()
@@ -121,6 +124,18 @@ func (b *BodyRequestHandler) BodyForm() (url.Values, error) {
// RawBody 获取raw数据 // RawBody 获取raw数据
func (b *BodyRequestHandler) RawBody() ([]byte, error) { func (b *BodyRequestHandler) RawBody() ([]byte, error) {
if b.isResetFile == false {
contentType, _, _ := mime.ParseMediaType(string(b.request.Header.ContentType()))
if contentType == MultipartForm {
err := b.resetFile()
if err != nil {
log.Errorf("reset file error: %v", err)
return nil, err
}
b.isResetFile = true
}
}
return b.request.Body(), nil return b.request.Body(), nil
} }
@@ -148,7 +163,9 @@ func (b *BodyRequestHandler) SetToForm(key, value string) error {
return err return err
} }
multipartForm.Value[key] = []string{value} multipartForm.Value[key] = []string{value}
return b.resetFile() b.isResetFile = false
//return b.resetFile()
return nil
default: default:
return ErrorNotForm return ErrorNotForm
} }
@@ -169,7 +186,9 @@ func (b *BodyRequestHandler) AddForm(key, value string) error {
return err return err
} }
multipartForm.Value[key] = append(multipartForm.Value[key], value) multipartForm.Value[key] = append(multipartForm.Value[key], value)
return b.resetFile() b.isResetFile = false
//return b.resetFile()
return nil
default: default:
return ErrorNotForm return ErrorNotForm
} }
@@ -187,8 +206,9 @@ func (b *BodyRequestHandler) AddFile(key string, file *multipart.FileHeader) err
return err return err
} }
multipartForm.File[key] = append(multipartForm.File[key], file) multipartForm.File[key] = append(multipartForm.File[key], file)
b.isResetFile = false
return b.resetFile() //return b.resetFile()
return nil
} }
// SetFile 设置文件参数 // SetFile 设置文件参数
@@ -200,7 +220,8 @@ func (b *BodyRequestHandler) SetFile(files map[string][]*multipart.FileHeader) e
} }
multipartForm.File = files multipartForm.File = files
return b.resetFile() //return b.resetFile()
return nil
} }
func (b *BodyRequestHandler) resetFile() error { func (b *BodyRequestHandler) resetFile() error {
@@ -218,11 +239,6 @@ func (b *BodyRequestHandler) resetFile() error {
if err != nil { if err != nil {
return err return err
} }
//part, err := writer.CreateFormFile(name, f.Filename)
//if err != nil {
// fio.Close()
// return err
//}
part, err := writer.CreatePart(f.Header) part, err := writer.CreatePart(f.Header)
if err != nil { if err != nil {
return err return err
@@ -279,7 +295,8 @@ func (b *BodyRequestHandler) SetForm(values url.Values) error {
return err return err
} }
multipartForm.Value = values multipartForm.Value = values
return b.resetFile() //return b.resetFile()
return nil
} }
return ErrorNotForm return ErrorNotForm

View File

@@ -6,6 +6,7 @@ import (
"fmt" "fmt"
"io" "io"
"net" "net"
"runtime"
"strconv" "strconv"
"strings" "strings"
"time" "time"
@@ -183,7 +184,7 @@ func (ctx *HttpContext) SendTo(scheme string, node eoscContext.INode, timeout ti
host := node.Addr() host := node.Addr()
request := ctx.proxyRequest.Request() request := ctx.proxyRequest.Request()
request.CloseBodyStream() //request.CloseBodyStream()
rewriteHost := string(request.Host()) rewriteHost := string(request.Host())
upstreamHost := ctx.GetUpstreamHostHandler() upstreamHost := ctx.GetUpstreamHostHandler()
if upstreamHost != nil { if upstreamHost != nil {
@@ -203,6 +204,9 @@ func (ctx *HttpContext) SendTo(scheme string, node eoscContext.INode, timeout ti
rewriteHost = host rewriteHost = host
request.URI().SetHost(host) request.URI().SetHost(host)
} }
var m runtime.MemStats
runtime.ReadMemStats(&m)
log.DebugF("After: HeapAlloc=%.2f MB", float64(m.HeapAlloc)/(1024.0*1024.0))
beginTime := time.Now() beginTime := time.Now()
response := fasthttp.AcquireResponse() response := fasthttp.AcquireResponse()
@@ -363,6 +367,9 @@ func (ctx *HttpContext) Clone() (eoscContext.EoContext, error) {
// NewContext 创建Context // NewContext 创建Context
func NewContext(ctx *fasthttp.RequestCtx, port int) *HttpContext { func NewContext(ctx *fasthttp.RequestCtx, port int) *HttpContext {
var m runtime.MemStats
runtime.ReadMemStats(&m)
log.DebugF("Before: HeapAlloc=%.2f MB", float64(m.HeapAlloc)/(1024.0*1024.0))
remoteAddr := ctx.RemoteAddr().String() remoteAddr := ctx.RemoteAddr().String()
@@ -374,9 +381,9 @@ func NewContext(ctx *fasthttp.RequestCtx, port int) *HttpContext {
// 原始请求最大读取body为8k使用clone request // 原始请求最大读取body为8k使用clone request
request := fasthttp.AcquireRequest() request := fasthttp.AcquireRequest()
if ctx.Request.IsBodyStream() && ctx.Request.Header.ContentLength() > 8*1024 { //if ctx.Request.IsBodyStream() && ctx.Request.Header.ContentLength() > 8*1024 {
ctx.Request.Body() // ctx.Request.Body()
} //}
ctx.Request.CopyTo(request) ctx.Request.CopyTo(request)
httpContext.requestReader.reset(request, remoteAddr) httpContext.requestReader.reset(request, remoteAddr)