Skip to content

Commit a8b80bf

Browse files
authored
Merge pull request #205 from deploymenttheory/dev
Added support for multi file uploads following OAS3 spec
2 parents ec4a9dd + 6ee80ae commit a8b80bf

File tree

1 file changed

+11
-18
lines changed

1 file changed

+11
-18
lines changed

httpclient/multipartrequest.go

Lines changed: 11 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ import (
2323
)
2424

2525
// DoMultiPartRequest creates and executes a multipart/form-data HTTP request for file uploads and form fields.
26-
func (c *Client) DoMultiPartRequest(method, endpoint string, files map[string]string, params map[string]string, contentTypes map[string]string, headersMap map[string]http.Header, out interface{}) (*http.Response, error) {
26+
func (c *Client) DoMultiPartRequest(method, endpoint string, files map[string][]string, params map[string]string, contentTypes map[string]string, headersMap map[string]http.Header, out interface{}) (*http.Response, error) {
2727
log := c.Logger
2828
ctx, cancel := context.WithCancel(context.Background())
2929
defer cancel() // Ensure the context is canceled when the function returns
@@ -107,13 +107,15 @@ func (c *Client) DoMultiPartRequest(method, endpoint string, files map[string]st
107107
}
108108

109109
// createMultipartRequestBody creates a multipart request body with the provided files and form fields, supporting custom content types and headers.
110-
func createMultipartRequestBody(files map[string]string, params map[string]string, contentTypes map[string]string, headersMap map[string]http.Header, log logger.Logger) (*bytes.Buffer, string, error) {
110+
func createMultipartRequestBody(files map[string][]string, params map[string]string, contentTypes map[string]string, headersMap map[string]http.Header, log logger.Logger) (*bytes.Buffer, string, error) {
111111
body := &bytes.Buffer{}
112112
writer := multipart.NewWriter(body)
113113

114-
for fieldName, filePath := range files {
115-
if err := addFilePart(writer, fieldName, filePath, contentTypes, headersMap, log); err != nil {
116-
return nil, "", err
114+
for fieldName, filePaths := range files {
115+
for _, filePath := range filePaths {
116+
if err := addFilePart(writer, fieldName, filePath, contentTypes, headersMap, log); err != nil {
117+
return nil, "", err
118+
}
117119
}
118120
}
119121

@@ -145,14 +147,13 @@ func addFilePart(writer *multipart.Writer, fieldName, filePath string, contentTy
145147
contentType = ct
146148
}
147149

148-
var partHeaders textproto.MIMEHeader
150+
var part io.Writer
149151
if h, ok := headersMap[fieldName]; ok {
150-
partHeaders = CustomFormDataHeader(fieldName, filepath.Base(filePath), contentType, h)
152+
part, err = writer.CreatePart(CustomFormDataHeader(fieldName, filepath.Base(filePath), contentType, h))
151153
} else {
152-
partHeaders = FormDataHeader(fieldName, contentType)
154+
part, err = writer.CreateFormFile(fieldName, filepath.Base(filePath))
153155
}
154156

155-
part, err := writer.CreatePart(partHeaders)
156157
if err != nil {
157158
log.Error("Failed to create form file part", zap.String("fieldName", fieldName), zap.Error(err))
158159
return err
@@ -175,7 +176,7 @@ func addFilePart(writer *multipart.Writer, fieldName, filePath string, contentTy
175176

176177
// addFormField adds a form field to the multipart writer with the provided key and value.
177178
func addFormField(writer *multipart.Writer, key, val string, log logger.Logger) error {
178-
fieldWriter, err := writer.CreatePart(FormDataHeader(key, "text/plain"))
179+
fieldWriter, err := writer.CreateFormField(key)
179180
if err != nil {
180181
log.Error("Failed to create form field", zap.String("key", key), zap.Error(err))
181182
return err
@@ -187,14 +188,6 @@ func addFormField(writer *multipart.Writer, key, val string, log logger.Logger)
187188
return nil
188189
}
189190

190-
// FormDataHeader creates a textproto.MIMEHeader for a form data field with the provided field name and content type.
191-
func FormDataHeader(fieldname, contentType string) textproto.MIMEHeader {
192-
header := textproto.MIMEHeader{}
193-
header.Set("Content-Disposition", fmt.Sprintf(`form-data; name="%s"`, fieldname))
194-
header.Set("Content-Type", contentType)
195-
return header
196-
}
197-
198191
// CustomFormDataHeader creates a textproto.MIMEHeader for a form data field with the provided field name, file name, content type, and custom headers.
199192
func CustomFormDataHeader(fieldname, filename, contentType string, customHeaders http.Header) textproto.MIMEHeader {
200193
header := textproto.MIMEHeader{}

0 commit comments

Comments
 (0)