Skip to content

Commit

Permalink
Merge pull request #1143 from tdakkota/fix/multipart-content-type
Browse files Browse the repository at this point in the history
fix(gen): set Content-Type for JSON-encoded form parameters
  • Loading branch information
ernado authored Dec 18, 2023
2 parents 850508d + 097db69 commit 67c195f
Show file tree
Hide file tree
Showing 8 changed files with 72 additions and 26 deletions.
3 changes: 2 additions & 1 deletion .golangci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,8 @@ issues:
text: G114

# We are using quoting algorithm from mime/multipart package. False-positive.
- path: http[/\\]multipart_file\.go
- path: (http|uri)
source: form-data; name="%s"
linters: [gocritic]
text: sprintfQuotedString

Expand Down
6 changes: 3 additions & 3 deletions examples/ex_2ch/oas_request_encoders_gen.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

10 changes: 5 additions & 5 deletions examples/ex_openai/oas_request_encoders_gen.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 5 additions & 1 deletion gen/_template/request_encode.tmpl
Original file line number Diff line number Diff line change
Expand Up @@ -139,7 +139,11 @@ func encode{{ $op.Name }}Request(
{{- else }}
{{- errorf "unexpected type: %s" $unaliased }}
{{- end }}
q := uri.NewQueryEncoder()
q := uri.NewFormEncoder(map[string]string{
{{- range $param := $type.FormParameters }}{{- if $param.Spec.Content }}
{{ quote $param.Spec.Name }}: "application/json; charset=utf-8",
{{- end }}{{- end }}
})
{{- range $param := $type.FormParameters }}
{
// Encode {{ quote $param.Spec.Name }} form field.
Expand Down
8 changes: 6 additions & 2 deletions internal/integration/test_allof/oas_request_encoders_gen.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

20 changes: 11 additions & 9 deletions internal/integration/test_form/oas_request_encoders_gen.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

37 changes: 36 additions & 1 deletion uri/query_encoder.go
Original file line number Diff line number Diff line change
@@ -1,14 +1,20 @@
package uri

import (
"fmt"
"io"
"mime/multipart"
"net/textproto"
"net/url"
"strings"

"github.com/go-faster/errors"
)

type QueryEncoder struct {
values url.Values

ct map[string]string
}

func NewQueryEncoder() *QueryEncoder {
Expand All @@ -17,6 +23,13 @@ func NewQueryEncoder() *QueryEncoder {
}
}

func NewFormEncoder(ct map[string]string) *QueryEncoder {
return &QueryEncoder{
values: make(url.Values),
ct: ct,
}
}

type QueryParameterEncodingConfig struct {
Name string
Style QueryStyle
Expand Down Expand Up @@ -48,10 +61,32 @@ func (e *QueryEncoder) Values() url.Values {
func (e *QueryEncoder) WriteMultipart(w *multipart.Writer) error {
for k, values := range e.values {
for i, value := range values {
if err := w.WriteField(k, value); err != nil {
if err := e.writeMultipartField(w, k, value); err != nil {
return errors.Wrapf(err, "write %q: [%d]", k, i)
}
}
}
return nil
}

func (e *QueryEncoder) writeMultipartField(w *multipart.Writer, key, value string) error {
h := make(textproto.MIMEHeader)
h.Set("Content-Disposition",
fmt.Sprintf(`form-data; name="%s"`, escapeQuotes(key)))
if contentType, ok := e.ct[key]; ok {
h.Set("Content-Type", contentType)
}

field, err := w.CreatePart(h)
if err != nil {
return err
}
_, err = io.WriteString(field, value)
return err
}

var quoteEscaper = strings.NewReplacer("\\", "\\\\", `"`, "\\\"")

func escapeQuotes(s string) string {
return quoteEscaper.Replace(s)
}

0 comments on commit 67c195f

Please sign in to comment.