From fb769d71b596063ef48102178460cefa15091aff Mon Sep 17 00:00:00 2001 From: martinpasaribu Date: Thu, 10 Oct 2024 23:37:33 +0700 Subject: [PATCH] =?UTF-8?q?=F0=9F=8E=A8=20:=20add=20some=20test=20case=20f?= =?UTF-8?q?or=20multipart=20file?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- bind.go | 35 +++++++++++++++++++---------------- bind_test.go | 40 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 59 insertions(+), 16 deletions(-) diff --git a/bind.go b/bind.go index a127f99f..157be09f 100644 --- a/bind.go +++ b/bind.go @@ -219,30 +219,26 @@ func (b *DefaultBinder) bindData(destination interface{}, data map[string][]stri } // Handle multiple file uploads ([]*multipart.FileHeader, *multipart.FileHeader, []multipart.FileHeader) - if len(files) > 0 { + if len(files) > 0 && isMultipartFile(structField.Type()) { for _, fileMap := range files { fileHeaders, exists := fileMap[inputFieldName] - if exists { - if structField.Type() == reflect.TypeOf([]*multipart.FileHeader(nil)) { + if exists && len(fileHeaders) > 0 { + switch structField.Type() { + case reflect.TypeOf([]*multipart.FileHeader(nil)): structField.Set(reflect.ValueOf(fileHeaders)) continue - } else if structField.Type() == reflect.TypeOf([]multipart.FileHeader(nil)) { - var headers []multipart.FileHeader - for _, fileHeader := range fileHeaders { - headers = append(headers, *fileHeader) + case reflect.TypeOf([]multipart.FileHeader(nil)): + headers := make([]multipart.FileHeader, len(fileHeaders)) + for i, fileHeader := range fileHeaders { + headers[i] = *fileHeader } structField.Set(reflect.ValueOf(headers)) continue - } else if structField.Type() == reflect.TypeOf(&multipart.FileHeader{}) { - - if len(fileHeaders) > 0 { - structField.Set(reflect.ValueOf(fileHeaders[0])) - } + case reflect.TypeOf(&multipart.FileHeader{}): + structField.Set(reflect.ValueOf(fileHeaders[0])) continue - } else if structField.Type() == reflect.TypeOf(multipart.FileHeader{}) { - if len(fileHeaders) > 0 { - structField.Set(reflect.ValueOf(*fileHeaders[0])) - } + case reflect.TypeOf(multipart.FileHeader{}): + structField.Set(reflect.ValueOf(*fileHeaders[0])) continue } } @@ -434,3 +430,10 @@ func setFloatField(value string, bitSize int, field reflect.Value) error { } return err } + +func isMultipartFile(field reflect.Type) bool { + return reflect.TypeOf(&multipart.FileHeader{}) == field || + reflect.TypeOf(multipart.FileHeader{}) == field || + reflect.TypeOf([]*multipart.FileHeader(nil)) == field || + reflect.TypeOf([]multipart.FileHeader(nil)) == field +} diff --git a/bind_test.go b/bind_test.go index f52c1319..2323a219 100644 --- a/bind_test.go +++ b/bind_test.go @@ -1177,6 +1177,46 @@ func TestFormMultipartBindTwoFiles(t *testing.T) { } } +func TestFormMultipartBindMultipleKeys(t *testing.T) { + var args struct { + Files []multipart.FileHeader `form:"files"` + File multipart.FileHeader `form:"file"` + } + + files := []testFile{ + { + Fieldname: "files", + Filename: "file1.txt", + Content: []byte("This is the content of file 1."), + }, + { + Fieldname: "files", + Filename: "file2.txt", + Content: []byte("This is the content of file 2."), + }, + } + file := testFile{ + Fieldname: "file", + Filename: "file3.txt", + Content: []byte("This is the content of file 3."), + } + + e := New() + req := createRequestMultipartFiles(t, append(files, file)...) + rec := httptest.NewRecorder() + c := e.NewContext(req, rec) + + err := c.Bind(&args) + assert.NoError(t, err) + + assert.Len(t, args.Files, len(files)) + for idx, file := range files { + argsFile := args.Files[idx] + assertMultipartFileHeader(t, &argsFile, file) + } + assertMultipartFileHeader(t, &args.File, file) +} + func TestFormMultipartBindOneFile(t *testing.T) { var args struct { File *multipart.FileHeader `form:"file"`