1
0
mirror of https://github.com/astaxie/beego.git synced 2024-06-02 12:03:27 +00:00

Merge pull request #4275 from flycash/fix-4224

add MaxUploadFile to provide more safety uploading controll
This commit is contained in:
Ming Deng 2020-10-21 10:04:32 +08:00 committed by GitHub
commit 03ba495b7f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 23 additions and 10 deletions

View File

@ -43,7 +43,11 @@ type Config struct {
RecoverFunc func(*context.Context, *Config) RecoverFunc func(*context.Context, *Config)
CopyRequestBody bool CopyRequestBody bool
EnableGzip bool EnableGzip bool
// MaxMemory and MaxUploadSize are used to limit the request body
// if the request is not uploading file, MaxMemory is the max size of request body
// if the request is uploading file, MaxUploadSize is the max size of request body
MaxMemory int64 MaxMemory int64
MaxUploadSize int64
EnableErrorsShow bool EnableErrorsShow bool
EnableErrorsRender bool EnableErrorsRender bool
Listen Listen Listen Listen
@ -215,6 +219,7 @@ func newBConfig() *Config {
CopyRequestBody: false, CopyRequestBody: false,
EnableGzip: false, EnableGzip: false,
MaxMemory: 1 << 26, // 64MB MaxMemory: 1 << 26, // 64MB
MaxUploadSize: 1 << 30, // 1GB
EnableErrorsShow: true, EnableErrorsShow: true,
EnableErrorsRender: true, EnableErrorsRender: true,
Listen: Listen{ Listen: Listen{
@ -302,7 +307,7 @@ func assignConfig(ac config.Configer) error {
err := ac.Unmarshaler("", BConfig) err := ac.Unmarshaler("", BConfig)
if err != nil { if err != nil {
_, _ = fmt.Fprintln(os.Stderr, fmt.Sprintf("Unmarshaler config file to BConfig failed. " + _, _ = fmt.Fprintln(os.Stderr, fmt.Sprintf("Unmarshaler config file to BConfig failed. "+
"And if you are working on v1.x config file, please ignore this, err: %s", err)) "And if you are working on v1.x config file, please ignore this, err: %s", err))
return err return err
} }

View File

@ -423,8 +423,7 @@ func (input *BeegoInput) SetData(key, val interface{}) {
// ParseFormOrMultiForm parseForm or parseMultiForm based on Content-type // ParseFormOrMultiForm parseForm or parseMultiForm based on Content-type
func (input *BeegoInput) ParseFormOrMultiForm(maxMemory int64) error { func (input *BeegoInput) ParseFormOrMultiForm(maxMemory int64) error {
// Parse the body depending on the content type. // Parse the body depending on the content type.
input.Context.Request.Body = http.MaxBytesReader(input.Context.ResponseWriter, input.Context.Request.Body, maxMemory) if input.IsUpload() {
if strings.Contains(input.Header("Content-Type"), "multipart/form-data") {
if err := input.Context.Request.ParseMultipartForm(maxMemory); err != nil { if err := input.Context.Request.ParseMultipartForm(maxMemory); err != nil {
return errors.New("Error parsing request body:" + err.Error()) return errors.New("Error parsing request body:" + err.Error())
} }

View File

@ -710,7 +710,12 @@ func (p *ControllerRegister) serveHttp(ctx *beecontext.Context) {
} }
if r.Method != http.MethodGet && r.Method != http.MethodHead { if r.Method != http.MethodGet && r.Method != http.MethodHead {
if p.cfg.CopyRequestBody && !ctx.Input.IsUpload() {
if ctx.Input.IsUpload() {
ctx.Input.Context.Request.Body = http.MaxBytesReader(ctx.Input.Context.ResponseWriter,
ctx.Input.Context.Request.Body,
p.cfg.MaxUploadSize)
} else if p.cfg.CopyRequestBody {
// connection will close if the incoming data are larger (RFC 7231, 6.5.11) // connection will close if the incoming data are larger (RFC 7231, 6.5.11)
if r.ContentLength > p.cfg.MaxMemory { if r.ContentLength > p.cfg.MaxMemory {
logs.Error(errors.New("payload too large")) logs.Error(errors.New("payload too large"))
@ -718,6 +723,10 @@ func (p *ControllerRegister) serveHttp(ctx *beecontext.Context) {
goto Admin goto Admin
} }
ctx.Input.CopyBody(p.cfg.MaxMemory) ctx.Input.CopyBody(p.cfg.MaxMemory)
} else {
ctx.Input.Context.Request.Body = http.MaxBytesReader(ctx.Input.Context.ResponseWriter,
ctx.Input.Context.Request.Body,
p.cfg.MaxMemory)
} }
err = ctx.Input.ParseFormOrMultiForm(p.cfg.MaxMemory) err = ctx.Input.ParseFormOrMultiForm(p.cfg.MaxMemory)