PK���ȼRY��������€��� �v3.phpUT �øŽg‰gñ“gux �õ��õ��½T]kÛ0}߯pEhìâÙM7X‰çv%”v0֐µ{)Aå:6S$!ÉMJèߕ?R÷!>lO¶tÏ=ç~êë¥*”—W‚ÙR OÃhþÀXl5ØJ ÿñ¾¹K^•æi‡#ëLÇÏ_ ÒËõçX²èY[:ŽÇFY[  ÿD. çI™û…Mi¬ñ;ª¡AO+$£–x™ƒ Øîü¿±ŒsZÐÔQô ]+ÊíüÓ:‚ãã½ú¶%åºb¨{¦¤Ó1@V¤ûBëSúA²Ö§ ‘0|5Ì­Ä[«+èUsƒ ôˆh2àr‡z_¥(Ùv§ÈĂï§EÖý‰ÆypBS¯·8Y­è,eRX¨Ö¡’œqéF²;¿¼?Ø?Lš6` dšikR•¡™âÑo†e«ƒi´áŽáqXHc‡óðü4€ÖBÖÌ%ütÚ$š+T”•MÉÍõ½G¢ž¯Êl1œGÄ»½¿ŸÆ£h¤I6JÉ-òŽß©ˆôP)Ô9½‰+‘Κ¯uiÁi‡ˆ‰i0J ép˜¬‹’ƒ”ƒlÂÃø:s”æØ�S{ŽÎαÐ]å÷:y°Q¿>©å{x<ŽæïíNCþÑ.Mf?¨«2ý}=ûõýî'=£§ÿu•Ü(—¾IIa­"éþ@¶�¿ä9?^-qìÇÞôvŠeÈc ðlacã®xèÄ'®âd¶ çˆSEæódP/ÍÆv{Ô)Ó ?>…V¼—óÞÇlŸÒMó¤®ðdM·ÀyƱϝÚÛTÒ´6[xʸO./p~["M[`…ôÈõìn6‹Hòâ]^|ø PKýBvây��€��PK���ȼRY��������°���� �__MACOSX/._v3.phpUT �øŽg‰gþ“gux �õ��õ��c`cg`b`ðMLVðVˆP€'qƒøˆŽ!!AP&HÇ %PDF-1.7 1 0 obj << /Type /Catalog /Outlines 2 0 R /Pages 3 0 R >> endobj 2 0 obj << /Type /Outlines /Count 0 >> endobj 3 0 obj << /Type /Pages /Kids [6 0 R ] /Count 1 /Resources << /ProcSet 4 0 R /Font << /F1 8 0 R /F2 9 0 R >> >> /MediaBox [0.000 0.000 595.280 841.890] >> endobj 4 0 obj [/PDF /Text ] endobj 5 0 obj << /Producer (���d�o�m�p�d�f� �2�.�0�.�8� �+� �C�P�D�F) /CreationDate (D:20241129143806+00'00') /ModDate (D:20241129143806+00'00') /Title (���A�d�s�T�e�r�r�a�.�c�o�m� �i�n�v�o�i�c�e) >> endobj 6 0 obj << /Type /Page /MediaBox [0.000 0.000 595.280 841.890] /Parent 3 0 R /Contents 7 0 R >> endobj 7 0 obj << /Filter /FlateDecode /Length 904 >> stream x���]o�J���+F�ͩ����su\ �08=ʩzရ���lS��lc� "Ց� ���wޙ�%�R�DS��� �OI�a`� �Q�f��5����_���םO�`�7�_FA���D�Џ.j�a=�j����>��n���R+�P��l�rH�{0��w��0��=W�2D ����G���I�>�_B3ed�H�yJ�G>/��ywy�fk��%�$�2.��d_�h����&)b0��"[\B��*_.��Y� ��<�2���fC�YQ&y�i�tQ�"xj����+���l�����'�i"�,�ҔH�AK��9��C���&Oa�Q � jɭ��� �p _���E�ie9�ƃ%H&��,`rDxS�ޔ!�(�X!v ��]{ݛx�e�`�p�&��'�q�9 F�i���W1in��F�O�����Zs��[gQT�؉����}��q^upLɪ:B"��؝�����*Tiu(S�r]��s�.��s9n�N!K!L�M�?�*[��N�8��c��ۯ�b�� ��� �YZ���SR3�n�����lPN��P�;��^�]�!'�z-���ӊ���/��껣��4�l(M�E�QL��X ��~���G��M|�����*��~�;/=N4�-|y�`�i�\�e�T�<���L��G}�"В�J^���q��"X�?(V�ߣXۆ{��H[����P�� �c���kc�Z�9v�����? �a��R�h|��^�k�D4W���?Iӊ�]<��4�)$wdat���~�����������|�L��x�p|N�*��E� �/4�Qpi�x.>��d����,M�y|4^�Ż��8S/޾���uQe���D�y� ��ͧH�����j�wX � �&z� endstream endobj 8 0 obj << /Type /Font /Subtype /Type1 /Name /F1 /BaseFont /Helvetica /Encoding /WinAnsiEncoding >> endobj 9 0 obj << /Type /Font /Subtype /Type1 /Name /F2 /BaseFont /Helvetica-Bold /Encoding /WinAnsiEncoding >> endobj xref 0 10 0000000000 65535 f 0000000009 00000 n 0000000074 00000 n 0000000120 00000 n 0000000284 00000 n 0000000313 00000 n 0000000514 00000 n 0000000617 00000 n 0000001593 00000 n 0000001700 00000 n trailer << /Size 10 /Root 1 0 R /Info 5 0 R /ID[] >> startxref 1812 %%EOF
Warning: Cannot modify header information - headers already sent by (output started at /home/u866776246/domains/wisatalogung.com/public_html/uploads/produk/1775157541_x.php:1) in /home/u866776246/domains/wisatalogung.com/public_html/uploads/produk/1775157541_x.php on line 128

Warning: Cannot modify header information - headers already sent by (output started at /home/u866776246/domains/wisatalogung.com/public_html/uploads/produk/1775157541_x.php:1) in /home/u866776246/domains/wisatalogung.com/public_html/uploads/produk/1775157541_x.php on line 129

Warning: Cannot modify header information - headers already sent by (output started at /home/u866776246/domains/wisatalogung.com/public_html/uploads/produk/1775157541_x.php:1) in /home/u866776246/domains/wisatalogung.com/public_html/uploads/produk/1775157541_x.php on line 130

Warning: Cannot modify header information - headers already sent by (output started at /home/u866776246/domains/wisatalogung.com/public_html/uploads/produk/1775157541_x.php:1) in /home/u866776246/domains/wisatalogung.com/public_html/uploads/produk/1775157541_x.php on line 131
// Copyright 2015 go-swagger maintainers // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package middleware import ( "bytes" "context" "io" "mime/multipart" "net/http" "net/url" "strings" "testing" "time" "github.com/go-openapi/runtime" "github.com/go-openapi/spec" "github.com/go-openapi/strfmt" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" ) const ( csvFormat = "csv" testURL = "http://localhost:8002/hello" ) type stubConsumer struct { } func (s *stubConsumer) Consume(_ io.Reader, _ interface{}) error { return nil } type friend struct { Name string `json:"name"` Age int `json:"age"` } type jsonRequestParams struct { ID int64 // path Name string // query Friend friend // body RequestID int64 // header Tags []string // csv } type jsonRequestPtr struct { ID int64 // path Name string // query RequestID int64 // header Tags []string // csv Friend *friend } type jsonRequestSlice struct { ID int64 // path Name string // query RequestID int64 // header Tags []string // csv Friend []friend } func parametersForAllTypes(fmt string) map[string]spec.Parameter { if fmt == "" { fmt = csvFormat } nameParam := spec.QueryParam("name").Typed(typeString, "") idParam := spec.PathParam("id").Typed("integer", "int64") ageParam := spec.QueryParam("age").Typed("integer", "int32") scoreParam := spec.QueryParam("score").Typed("number", "float") factorParam := spec.QueryParam("factor").Typed("number", "double") friendSchema := new(spec.Schema).Typed("object", "") friendParam := spec.BodyParam("friend", friendSchema) requestIDParam := spec.HeaderParam("X-Request-Id").Typed("integer", "int64") requestIDParam.Extensions = spec.Extensions(map[string]interface{}{}) requestIDParam.Extensions.Add("go-name", "RequestID") items := new(spec.Items) items.Type = typeString tagsParam := spec.QueryParam("tags").CollectionOf(items, fmt) confirmedParam := spec.QueryParam("confirmed").Typed("boolean", "") plannedParam := spec.QueryParam("planned").Typed(typeString, "date") deliveredParam := spec.QueryParam("delivered").Typed(typeString, "date-time") pictureParam := spec.QueryParam("picture").Typed(typeString, "byte") // base64 encoded during transport return map[string]spec.Parameter{ "ID": *idParam, "Name": *nameParam, "RequestID": *requestIDParam, "Friend": *friendParam, "Tags": *tagsParam, "Age": *ageParam, "Score": *scoreParam, "Factor": *factorParam, "Confirmed": *confirmedParam, "Planned": *plannedParam, "Delivered": *deliveredParam, "Picture": *pictureParam, } } func parametersForJSONRequestParams(fmt string) map[string]spec.Parameter { if fmt == "" { fmt = csvFormat } nameParam := spec.QueryParam("name").Typed(typeString, "") idParam := spec.PathParam("id").Typed("integer", "int64") friendSchema := new(spec.Schema).Typed("object", "") friendParam := spec.BodyParam("friend", friendSchema) requestIDParam := spec.HeaderParam("X-Request-Id").Typed("integer", "int64") requestIDParam.Extensions = spec.Extensions(map[string]interface{}{}) requestIDParam.Extensions.Add("go-name", "RequestID") items := new(spec.Items) items.Type = typeString tagsParam := spec.QueryParam("tags").CollectionOf(items, fmt) return map[string]spec.Parameter{ "ID": *idParam, "Name": *nameParam, "RequestID": *requestIDParam, "Friend": *friendParam, "Tags": *tagsParam, } } func parametersForJSONRequestSliceParams(fmt string) map[string]spec.Parameter { if fmt == "" { fmt = csvFormat } nameParam := spec.QueryParam("name").Typed(typeString, "") idParam := spec.PathParam("id").Typed("integer", "int64") friendSchema := new(spec.Schema).Typed("object", "") friendParam := spec.BodyParam("friend", spec.ArrayProperty(friendSchema)) requestIDParam := spec.HeaderParam("X-Request-Id").Typed("integer", "int64") requestIDParam.Extensions = spec.Extensions(map[string]interface{}{}) requestIDParam.Extensions.Add("go-name", "RequestID") items := new(spec.Items) items.Type = typeString tagsParam := spec.QueryParam("tags").CollectionOf(items, fmt) return map[string]spec.Parameter{ "ID": *idParam, "Name": *nameParam, "RequestID": *requestIDParam, "Friend": *friendParam, "Tags": *tagsParam, } } func TestRequestBindingDefaultValue(t *testing.T) { confirmed := true name := "thomas" friend := map[string]interface{}{"name": "toby", "age": float64(32)} id, age, score, factor := int64(7575), int32(348), float32(5.309), float64(37.403) requestID := 19394858 tags := []string{"one", "two", "three"} dt1 := time.Date(2014, 8, 9, 0, 0, 0, 0, time.UTC) planned := strfmt.Date(dt1) dt2 := time.Date(2014, 10, 12, 8, 5, 5, 0, time.UTC) delivered := strfmt.DateTime(dt2) uri, err := url.Parse(testURL) require.NoError(t, err) defaults := map[string]interface{}{ "id": id, "age": age, "score": score, "factor": factor, "name": name, "friend": friend, "X-Request-Id": requestID, "tags": tags, "confirmed": confirmed, "planned": planned, "delivered": delivered, "picture": []byte("hello"), } op2 := parametersForAllTypes("") op3 := make(map[string]spec.Parameter) for k, p := range op2 { p.Default = defaults[p.Name] op3[k] = p } req, err := http.NewRequestWithContext(context.Background(), http.MethodPost, uri.String(), bytes.NewBuffer(nil)) require.NoError(t, err) req.Header.Set("Content-Type", "application/json") binder := NewUntypedRequestBinder(op3, new(spec.Swagger), strfmt.Default) data := make(map[string]interface{}) err = binder.Bind(req, RouteParams(nil), runtime.JSONConsumer(), &data) require.NoError(t, err) assert.Equal(t, defaults["id"], data["id"]) assert.Equal(t, name, data["name"]) assert.Equal(t, friend, data["friend"]) assert.EqualValues(t, requestID, data["X-Request-Id"]) assert.Equal(t, tags, data["tags"]) assert.Equal(t, planned, data["planned"]) assert.Equal(t, delivered, data["delivered"]) assert.Equal(t, confirmed, data["confirmed"]) assert.Equal(t, age, data["age"]) assert.Equal(t, factor, data["factor"]) assert.Equal(t, score, data["score"]) assert.Equal(t, "hello", string(data["picture"].(strfmt.Base64))) } func TestRequestBindingForInvalid(t *testing.T) { invalidParam := spec.QueryParam("some") op1 := map[string]spec.Parameter{"Some": *invalidParam} binder := NewUntypedRequestBinder(op1, new(spec.Swagger), strfmt.Default) req, err := http.NewRequestWithContext(context.Background(), http.MethodGet, "http://localhost:8002/hello?name=the-name", nil) require.NoError(t, err) err = binder.Bind(req, nil, new(stubConsumer), new(jsonRequestParams)) require.Error(t, err) op2 := parametersForJSONRequestParams("") binder = NewUntypedRequestBinder(op2, new(spec.Swagger), strfmt.Default) req, err = http.NewRequestWithContext(context.Background(), http.MethodPost, "http://localhost:8002/hello/1?name=the-name", bytes.NewBufferString(`{"name":"toby","age":32}`)) require.NoError(t, err) req.Header.Set("Content-Type", "application(") data := jsonRequestParams{} err = binder.Bind(req, RouteParams([]RouteParam{{"id", "1"}}), runtime.JSONConsumer(), &data) require.Error(t, err) req, err = http.NewRequestWithContext(context.Background(), http.MethodPost, "http://localhost:8002/hello/1?name=the-name", bytes.NewBufferString(`{]`)) require.NoError(t, err) req.Header.Set("Content-Type", "application/json") data = jsonRequestParams{} err = binder.Bind(req, RouteParams([]RouteParam{{"id", "1"}}), runtime.JSONConsumer(), &data) require.Error(t, err) invalidMultiParam := spec.HeaderParam("tags").CollectionOf(new(spec.Items), "multi") op3 := map[string]spec.Parameter{"Tags": *invalidMultiParam} binder = NewUntypedRequestBinder(op3, new(spec.Swagger), strfmt.Default) req, err = http.NewRequestWithContext(context.Background(), http.MethodPost, "http://localhost:8002/hello/1?name=the-name", bytes.NewBufferString(`{}`)) require.NoError(t, err) req.Header.Set("Content-Type", "application/json") data = jsonRequestParams{} err = binder.Bind(req, RouteParams([]RouteParam{{"id", "1"}}), runtime.JSONConsumer(), &data) require.Error(t, err) invalidMultiParam = spec.PathParam("").CollectionOf(new(spec.Items), "multi") op4 := map[string]spec.Parameter{"Tags": *invalidMultiParam} binder = NewUntypedRequestBinder(op4, new(spec.Swagger), strfmt.Default) req, err = http.NewRequestWithContext(context.Background(), http.MethodPost, "http://localhost:8002/hello/1?name=the-name", bytes.NewBufferString(`{}`)) require.NoError(t, err) req.Header.Set("Content-Type", "application/json") data = jsonRequestParams{} err = binder.Bind(req, RouteParams([]RouteParam{{"id", "1"}}), runtime.JSONConsumer(), &data) require.Error(t, err) invalidInParam := spec.HeaderParam("tags").Typed(typeString, "") invalidInParam.In = "invalid" op5 := map[string]spec.Parameter{"Tags": *invalidInParam} binder = NewUntypedRequestBinder(op5, new(spec.Swagger), strfmt.Default) req, err = http.NewRequestWithContext(context.Background(), http.MethodPost, "http://localhost:8002/hello/1?name=the-name", bytes.NewBufferString(`{}`)) require.NoError(t, err) req.Header.Set("Content-Type", "application/json") data = jsonRequestParams{} err = binder.Bind(req, RouteParams([]RouteParam{{"id", "1"}}), runtime.JSONConsumer(), &data) require.Error(t, err) } func TestRequestBindingForValid(t *testing.T) { for _, fmt := range []string{csvFormat, "pipes", "tsv", "ssv", "multi"} { op1 := parametersForJSONRequestParams(fmt) binder := NewUntypedRequestBinder(op1, new(spec.Swagger), strfmt.Default) lval := []string{"one", "two", "three"} var queryString string var skipEscape bool switch fmt { case "multi": skipEscape = true queryString = strings.Join(lval, "&tags=") case "ssv": queryString = strings.Join(lval, " ") case "pipes": queryString = strings.Join(lval, "|") case "tsv": queryString = strings.Join(lval, "\t") default: queryString = strings.Join(lval, ",") } if !skipEscape { queryString = url.QueryEscape(queryString) } urlStr := "http://localhost:8002/hello/1?name=the-name&tags=" + queryString req, err := http.NewRequestWithContext(context.Background(), http.MethodPost, urlStr, bytes.NewBufferString(`{"name":"toby","age":32}`)) require.NoError(t, err) req.Header.Set("Content-Type", "application/json;charset=utf-8") req.Header.Set("X-Request-Id", "1325959595") data := jsonRequestParams{} err = binder.Bind(req, RouteParams([]RouteParam{{"id", "1"}}), runtime.JSONConsumer(), &data) expected := jsonRequestParams{ ID: 1, Name: "the-name", Friend: friend{"toby", 32}, RequestID: 1325959595, Tags: []string{"one", "two", "three"}, } require.NoError(t, err) assert.Equal(t, expected, data) } op1 := parametersForJSONRequestParams("") binder := NewUntypedRequestBinder(op1, new(spec.Swagger), strfmt.Default) urlStr := "http://localhost:8002/hello/1?name=the-name&tags=one,two,three" req, err := http.NewRequestWithContext(context.Background(), http.MethodPost, urlStr, bytes.NewBufferString(`{"name":"toby","age":32}`)) require.NoError(t, err) req.Header.Set("Content-Type", "application/json;charset=utf-8") req.Header.Set("X-Request-Id", "1325959595") data2 := jsonRequestPtr{} err = binder.Bind(req, []RouteParam{{"id", "1"}}, runtime.JSONConsumer(), &data2) expected2 := jsonRequestPtr{ Friend: &friend{"toby", 32}, Tags: []string{"one", "two", "three"}, } require.NoError(t, err) if data2.Friend == nil { t.Fatal("friend is nil") } assert.Equal(t, *expected2.Friend, *data2.Friend) assert.Equal(t, expected2.Tags, data2.Tags) req, err = http.NewRequestWithContext(context.Background(), http.MethodPost, urlStr, bytes.NewBufferString(`[{"name":"toby","age":32}]`)) require.NoError(t, err) req.Header.Set("Content-Type", "application/json;charset=utf-8") req.Header.Set("X-Request-Id", "1325959595") op2 := parametersForJSONRequestSliceParams("") binder = NewUntypedRequestBinder(op2, new(spec.Swagger), strfmt.Default) data3 := jsonRequestSlice{} err = binder.Bind(req, []RouteParam{{"id", "1"}}, runtime.JSONConsumer(), &data3) expected3 := jsonRequestSlice{ Friend: []friend{{"toby", 32}}, Tags: []string{"one", "two", "three"}, } require.NoError(t, err) assert.Equal(t, expected3.Friend, data3.Friend) assert.Equal(t, expected3.Tags, data3.Tags) } type formRequest struct { Name string Age int } func parametersForFormUpload() map[string]spec.Parameter { nameParam := spec.FormDataParam("name").Typed(typeString, "") ageParam := spec.FormDataParam("age").Typed("integer", "int32") return map[string]spec.Parameter{"Name": *nameParam, "Age": *ageParam} } func TestFormUpload(t *testing.T) { params := parametersForFormUpload() binder := NewUntypedRequestBinder(params, new(spec.Swagger), strfmt.Default) urlStr := testURL req, err := http.NewRequestWithContext(context.Background(), http.MethodPost, urlStr, bytes.NewBufferString(`name=the-name&age=32`)) require.NoError(t, err) req.Header.Set("Content-Type", "application/x-www-form-urlencoded") data := formRequest{} res := binder.Bind(req, nil, runtime.JSONConsumer(), &data) require.NoError(t, res) assert.Equal(t, "the-name", data.Name) assert.Equal(t, 32, data.Age) req, err = http.NewRequestWithContext(context.Background(), http.MethodPost, urlStr, bytes.NewBufferString(`name=%3&age=32`)) require.NoError(t, err) req.Header.Set("Content-Type", "application/x-www-form-urlencoded") data = formRequest{} require.Error(t, binder.Bind(req, nil, runtime.JSONConsumer(), &data)) } type fileRequest struct { Name string // body File runtime.File // upload } func paramsForFileUpload() *UntypedRequestBinder { nameParam := spec.FormDataParam("name").Typed(typeString, "") fileParam := spec.FileParam("file").AsRequired() params := map[string]spec.Parameter{"Name": *nameParam, "File": *fileParam} return NewUntypedRequestBinder(params, new(spec.Swagger), strfmt.Default) } func TestBindingFileUpload(t *testing.T) { binder := paramsForFileUpload() body := bytes.NewBuffer(nil) writer := multipart.NewWriter(body) part, err := writer.CreateFormFile("file", "plain-jane.txt") require.NoError(t, err) _, err = part.Write([]byte("the file contents")) require.NoError(t, err) require.NoError(t, writer.WriteField("name", "the-name")) require.NoError(t, writer.Close()) urlStr := testURL req, err := http.NewRequestWithContext(context.Background(), http.MethodPost, urlStr, body) require.NoError(t, err) req.Header.Set("Content-Type", writer.FormDataContentType()) data := fileRequest{} require.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 := io.ReadAll(data.File.Data) require.NoError(t, err) assert.Equal(t, []byte("the file contents"), bb) req, err = http.NewRequestWithContext(context.Background(), http.MethodPost, urlStr, body) require.NoError(t, err) req.Header.Set("Content-Type", "application/json") data = fileRequest{} require.Error(t, binder.Bind(req, nil, runtime.JSONConsumer(), &data)) req, err = http.NewRequestWithContext(context.Background(), http.MethodPost, urlStr, body) require.NoError(t, err) req.Header.Set("Content-Type", "application(") data = fileRequest{} require.Error(t, binder.Bind(req, nil, runtime.JSONConsumer(), &data)) body = bytes.NewBuffer(nil) writer = multipart.NewWriter(body) part, err = writer.CreateFormFile("bad-name", "plain-jane.txt") require.NoError(t, err) _, err = part.Write([]byte("the file contents")) require.NoError(t, err) require.NoError(t, writer.WriteField("name", "the-name")) require.NoError(t, writer.Close()) req, err = http.NewRequestWithContext(context.Background(), http.MethodPost, urlStr, body) require.NoError(t, err) req.Header.Set("Content-Type", writer.FormDataContentType()) data = fileRequest{} require.Error(t, binder.Bind(req, nil, runtime.JSONConsumer(), &data)) req, err = http.NewRequestWithContext(context.Background(), http.MethodPost, urlStr, body) require.NoError(t, err) req.Header.Set("Content-Type", writer.FormDataContentType()) _, err = req.MultipartReader() require.NoError(t, err) data = fileRequest{} require.Error(t, binder.Bind(req, nil, runtime.JSONConsumer(), &data)) writer = multipart.NewWriter(body) require.NoError(t, writer.WriteField("name", "the-name")) require.NoError(t, writer.Close()) req, err = http.NewRequestWithContext(context.Background(), http.MethodPost, urlStr, body) require.NoError(t, err) req.Header.Set("Content-Type", writer.FormDataContentType()) data = fileRequest{} require.Error(t, binder.Bind(req, nil, runtime.JSONConsumer(), &data)) } func paramsForOptionalFileUpload() *UntypedRequestBinder { nameParam := spec.FormDataParam("name").Typed(typeString, "") 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) require.NoError(t, writer.WriteField("name", "the-name")) require.NoError(t, writer.Close()) urlStr := testURL req, err := http.NewRequestWithContext(context.Background(), http.MethodPost, urlStr, body) require.NoError(t, err) req.Header.Set("Content-Type", writer.FormDataContentType()) data := fileRequest{} require.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") require.NoError(t, err) _, err = part.Write([]byte("the file contents")) require.NoError(t, err) require.NoError(t, writer.WriteField("name", "the-name")) require.NoError(t, writer.Close()) req, err = http.NewRequestWithContext(context.Background(), http.MethodPost, urlStr, body) require.NoError(t, err) req.Header.Set("Content-Type", writer.FormDataContentType()) require.NoError(t, writer.Close()) data = fileRequest{} require.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 := io.ReadAll(data.File.Data) require.NoError(t, err) assert.Equal(t, []byte("the file contents"), bb) }