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,12 +43,16 @@ type Config struct {
RecoverFunc func(*context.Context, *Config) RecoverFunc func(*context.Context, *Config)
CopyRequestBody bool CopyRequestBody bool
EnableGzip bool EnableGzip bool
MaxMemory int64 // MaxMemory and MaxUploadSize are used to limit the request body
EnableErrorsShow bool // if the request is not uploading file, MaxMemory is the max size of request body
EnableErrorsRender bool // if the request is uploading file, MaxUploadSize is the max size of request body
Listen Listen MaxMemory int64
WebConfig WebConfig MaxUploadSize int64
Log LogConfig EnableErrorsShow bool
EnableErrorsRender bool
Listen Listen
WebConfig WebConfig
Log LogConfig
} }
// Listen holds for http and https related config // Listen holds for http and https related config
@ -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)