Skip to content

Commit

Permalink
Merge pull request #248 from MakarandNsd/246-fix-optional-file-paramter
Browse files Browse the repository at this point in the history
Fixes #246
  • Loading branch information
youyuanwu committed Jul 1, 2022
2 parents 3f9800f + c677fec commit 5bcfe65
Show file tree
Hide file tree
Showing 3 changed files with 113 additions and 2 deletions.
6 changes: 5 additions & 1 deletion middleware/parameter.go
Expand Up @@ -206,7 +206,11 @@ func (p *untypedParamBinder) Bind(request *http.Request, routeParams RouteParams
if p.parameter.Type == "file" {
file, header, ffErr := request.FormFile(p.parameter.Name)
if ffErr != nil {
return errors.NewParseError(p.Name, p.parameter.In, "", ffErr)
if p.parameter.Required {
return errors.NewParseError(p.Name, p.parameter.In, "", ffErr)
} else {
return nil
}
}
target.Set(reflect.ValueOf(runtime.File{Data: file, Header: header}))
return nil
Expand Down
61 changes: 60 additions & 1 deletion middleware/request_test.go
Expand Up @@ -406,7 +406,7 @@ type fileRequest struct {
func paramsForFileUpload() *UntypedRequestBinder {
nameParam := spec.FormDataParam("name").Typed("string", "")

fileParam := spec.FileParam("file")
fileParam := spec.FileParam("file").AsRequired()

params := map[string]spec.Parameter{"Name": *nameParam, "File": *fileParam}
return NewUntypedRequestBinder(params, new(spec.Swagger), strfmt.Default)
Expand Down Expand Up @@ -469,4 +469,63 @@ func TestBindingFileUpload(t *testing.T) {

data = fileRequest{}
assert.Error(t, binder.Bind(req, nil, runtime.JSONConsumer(), &data))

writer = multipart.NewWriter(body)
_ = writer.WriteField("name", "the-name")
assert.NoError(t, writer.Close())

req, _ = http.NewRequest("POST", urlStr, body)
req.Header.Set("Content-Type", writer.FormDataContentType())

data = fileRequest{}
assert.Error(t, binder.Bind(req, nil, runtime.JSONConsumer(), &data))
}

func paramsForOptionalFileUpload() *UntypedRequestBinder {
nameParam := spec.FormDataParam("name").Typed("string", "")
fileParam := spec.FileParam("file").AsOptional()

params := map[string]spec.Parameter{"Name": *nameParam, "File": *fileParam}
return NewUntypedRequestBinder(params, new(spec.Swagger), strfmt.Default)
}

func TestBindingOptionalFileUpload(t *testing.T) {
binder := paramsForOptionalFileUpload()

body := bytes.NewBuffer(nil)
writer := multipart.NewWriter(body)
_ = writer.WriteField("name", "the-name")
assert.NoError(t, writer.Close())

urlStr := "http://localhost:8002/hello"
req, _ := http.NewRequest("POST", urlStr, body)
req.Header.Set("Content-Type", writer.FormDataContentType())

data := fileRequest{}
assert.NoError(t, binder.Bind(req, nil, runtime.JSONConsumer(), &data))
assert.Equal(t, "the-name", data.Name)
assert.Nil(t, data.File.Data)
assert.Nil(t, data.File.Header)

writer = multipart.NewWriter(body)
part, err := writer.CreateFormFile("file", "plain-jane.txt")
assert.NoError(t, err)
_, _ = part.Write([]byte("the file contents"))
_ = writer.WriteField("name", "the-name")
assert.NoError(t, writer.Close())

req, _ = http.NewRequest("POST", urlStr, body)
req.Header.Set("Content-Type", writer.FormDataContentType())
assert.NoError(t, writer.Close())

data = fileRequest{}
assert.NoError(t, binder.Bind(req, nil, runtime.JSONConsumer(), &data))
assert.Equal(t, "the-name", data.Name)
assert.NotNil(t, data.File)
assert.NotNil(t, data.File.Header)
assert.Equal(t, "plain-jane.txt", data.File.Header.Filename)

bb, err := ioutil.ReadAll(data.File.Data)
assert.NoError(t, err)
assert.Equal(t, []byte("the file contents"), bb)
}
48 changes: 48 additions & 0 deletions middleware/untyped_request_test.go
Expand Up @@ -111,6 +111,54 @@ func TestUntypedFileUpload(t *testing.T) {

data = make(map[string]interface{})
assert.Error(t, binder.Bind(req, nil, runtime.JSONConsumer(), &data))

writer = multipart.NewWriter(body)
_ = writer.WriteField("name", "the-name")
assert.NoError(t, writer.Close())

req, _ = http.NewRequest("POST", urlStr, body)
req.Header.Set("Content-Type", writer.FormDataContentType())

data = make(map[string]interface{})
assert.Error(t, binder.Bind(req, nil, runtime.JSONConsumer(), &data))
}

func TestUntypedOptionalFileUpload(t *testing.T) {
binder := paramsForOptionalFileUpload()

body := bytes.NewBuffer(nil)
writer := multipart.NewWriter(body)
_ = writer.WriteField("name", "the-name")
assert.NoError(t, writer.Close())

urlStr := "http://localhost:8002/hello"
req, _ := http.NewRequest("POST", urlStr, body)
req.Header.Set("Content-Type", writer.FormDataContentType())

data := make(map[string]interface{})
assert.NoError(t, binder.Bind(req, nil, runtime.JSONConsumer(), &data))
assert.Equal(t, "the-name", data["name"])

writer = multipart.NewWriter(body)
part, err := writer.CreateFormFile("file", "plain-jane.txt")
assert.NoError(t, err)
_, _ = part.Write([]byte("the file contents"))
_ = writer.WriteField("name", "the-name")
assert.NoError(t, writer.Close())

req, _ = http.NewRequest("POST", urlStr, body)
req.Header.Set("Content-Type", writer.FormDataContentType())
assert.NoError(t, writer.Close())

data = make(map[string]interface{})
assert.NoError(t, binder.Bind(req, nil, runtime.JSONConsumer(), &data))
assert.Equal(t, "the-name", data["name"])
assert.NotNil(t, data["file"])
assert.IsType(t, runtime.File{}, data["file"])
file := data["file"].(runtime.File)
assert.NotNil(t, file.Header)
assert.Equal(t, "plain-jane.txt", file.Header.Filename)

}

func TestUntypedBindingTypesForValid(t *testing.T) {
Expand Down

0 comments on commit 5bcfe65

Please sign in to comment.