Skip to content

Commit e83ebc0

Browse files
authored
reproduce issue #436 (#439)
1 parent 4cb78ee commit e83ebc0

File tree

1 file changed

+135
-0
lines changed

1 file changed

+135
-0
lines changed

openapi3filter/issue436_test.go

Lines changed: 135 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,135 @@
1+
package openapi3filter_test
2+
3+
import (
4+
"bytes"
5+
"context"
6+
"io"
7+
"mime/multipart"
8+
"net/http"
9+
"net/textproto"
10+
"strings"
11+
12+
"github.com/getkin/kin-openapi/openapi3"
13+
"github.com/getkin/kin-openapi/openapi3filter"
14+
"github.com/getkin/kin-openapi/routers/gorillamux"
15+
)
16+
17+
func Example_validateMultipartFormData() {
18+
const spec = `
19+
openapi: 3.0.0
20+
info:
21+
title: 'Validator'
22+
version: 0.0.1
23+
paths:
24+
/test:
25+
post:
26+
requestBody:
27+
required: true
28+
content:
29+
multipart/form-data:
30+
schema:
31+
type: object
32+
required:
33+
- file
34+
properties:
35+
file:
36+
type: string
37+
format: binary
38+
categories:
39+
type: array
40+
items:
41+
$ref: "#/components/schemas/Category"
42+
responses:
43+
'200':
44+
description: Created
45+
46+
components:
47+
schemas:
48+
Category:
49+
type: object
50+
properties:
51+
name:
52+
type: string
53+
required:
54+
- name
55+
`
56+
57+
loader := openapi3.NewLoader()
58+
doc, err := loader.LoadFromData([]byte(spec))
59+
if err != nil {
60+
panic(err)
61+
}
62+
if err = doc.Validate(loader.Context); err != nil {
63+
panic(err)
64+
}
65+
66+
router, err := gorillamux.NewRouter(doc)
67+
if err != nil {
68+
panic(err)
69+
}
70+
71+
body := &bytes.Buffer{}
72+
writer := multipart.NewWriter(body)
73+
74+
{ // Add a single "categories" item as part data
75+
h := make(textproto.MIMEHeader)
76+
h.Set("Content-Disposition", `form-data; name="categories"`)
77+
h.Set("Content-Type", "application/json")
78+
fw, err := writer.CreatePart(h)
79+
if err != nil {
80+
panic(err)
81+
}
82+
if _, err = io.Copy(fw, strings.NewReader(`{"name": "foo"}`)); err != nil {
83+
panic(err)
84+
}
85+
}
86+
87+
{ // Add a single "categories" item as part data, again
88+
h := make(textproto.MIMEHeader)
89+
h.Set("Content-Disposition", `form-data; name="categories"`)
90+
h.Set("Content-Type", "application/json")
91+
fw, err := writer.CreatePart(h)
92+
if err != nil {
93+
panic(err)
94+
}
95+
if _, err = io.Copy(fw, strings.NewReader(`{"name": "bar"}`)); err != nil {
96+
panic(err)
97+
}
98+
}
99+
100+
{ // Add file data
101+
fw, err := writer.CreateFormFile("file", "hello.txt")
102+
if err != nil {
103+
panic(err)
104+
}
105+
if _, err = io.Copy(fw, strings.NewReader("hello")); err != nil {
106+
panic(err)
107+
}
108+
}
109+
110+
writer.Close()
111+
112+
req, err := http.NewRequest(http.MethodPost, "/test", bytes.NewReader(body.Bytes()))
113+
if err != nil {
114+
panic(err)
115+
}
116+
req.Header.Set("Content-Type", writer.FormDataContentType())
117+
118+
route, pathParams, err := router.FindRoute(req)
119+
if err != nil {
120+
panic(err)
121+
}
122+
123+
if err = openapi3filter.ValidateRequestBody(
124+
context.Background(),
125+
&openapi3filter.RequestValidationInput{
126+
Request: req,
127+
PathParams: pathParams,
128+
Route: route,
129+
},
130+
route.Operation.RequestBody.Value,
131+
); err != nil {
132+
panic(err)
133+
}
134+
// Output:
135+
}

0 commit comments

Comments
 (0)