Skip to content

Commit

Permalink
chore: experimenting with using a streaming technique rather than a b…
Browse files Browse the repository at this point in the history
…lock request
  • Loading branch information
ShocOne committed Jun 6, 2024
1 parent 16ef9f4 commit baf5db0
Showing 1 changed file with 39 additions and 2 deletions.
41 changes: 39 additions & 2 deletions httpclient/multipartrequest.go
Original file line number Diff line number Diff line change
Expand Up @@ -85,12 +85,18 @@ func (c *Client) DoMultiPartRequest(method, endpoint string, files map[string][]

log.Debug("Executing multipart request", zap.String("method", method), zap.String("endpoint", endpoint))

body, contentType, err := createMultipartRequestBody(files, formDataFields, fileContentTypes, formDataPartHeaders, log)
// body, contentType, err := createMultipartRequestBody(files, formDataFields, fileContentTypes, formDataPartHeaders, log)
// if err != nil {
// return nil, err
// }

// Call the helper function to create a streaming multipart request body
body, contentType, err := createStreamingMultipartRequestBody(files, formDataFields, fileContentTypes, formDataPartHeaders, log)
if err != nil {
return nil, err
}

logMultiPartRequestBody(body, log)
//logMultiPartRequestBody(body, log)

url := c.APIHandler.ConstructAPIResourceEndpoint(endpoint, log)

Expand Down Expand Up @@ -130,6 +136,37 @@ func (c *Client) DoMultiPartRequest(method, endpoint string, files map[string][]
return resp, response.HandleAPIErrorResponse(resp, log)
}

// createStreamingMultipartRequestBody creates a streaming multipart request body with the provided files and form fields.
// This function constructs the body of a multipart/form-data request using an io.Pipe, allowing the request to be sent in chunks.

func createStreamingMultipartRequestBody(files map[string][]string, formDataFields map[string]string, fileContentTypes map[string]string, formDataPartHeaders map[string]http.Header, log logger.Logger) (io.Reader, string, error) {
pr, pw := io.Pipe()
writer := multipart.NewWriter(pw)

go func() {
defer pw.Close()
defer writer.Close()

for fieldName, filePaths := range files {
for _, filePath := range filePaths {
if err := addFilePart(writer, fieldName, filePath, fileContentTypes, formDataPartHeaders, log); err != nil {
pw.CloseWithError(err)
return
}
}
}

for key, val := range formDataFields {
if err := addFormField(writer, key, val, log); err != nil {
pw.CloseWithError(err)
return
}
}
}()

return pr, writer.FormDataContentType(), nil
}

// createMultipartRequestBody creates a multipart request body with the provided files and form fields, supporting custom content types and headers.
// This function constructs the body of a multipart/form-data request by adding each file and form field to the multipart writer,
// setting custom content types and headers for each part as specified.
Expand Down

0 comments on commit baf5db0

Please sign in to comment.