fizz icon indicating copy to clipboard operation
fizz copied to clipboard

[binding error] Parsing audio file sent in the request body together with query params

Open norbertstrzelecki opened this issue 11 months ago • 1 comments

While sending an audio file within the request body, I'm receiving the following error:

{
    "error": "binding error: error parsing request body: invalid character 'R' looking for beginning of value"
}

As I understand, the audio file is parsed as a string and not the binary file -- the "R" is from string "RIFF" file header. The question is whether I could bind it as an audio/wav type as described below?

The request looks like this:

curl --location 'http://0.0.0.0:8080/test?userId=some-id' \
--header 'accept: application/json' \
--header 'Content-Type: audio/wav' \
--data '@/audio_file.wav'

So I send userId as a param and binary audio file in the body as audio/wav content type.

Code-wise, the handler functions look like this:

// Bind returns router parameters
func (h *Handler) Bind(router *fizz.Fizz) {
	router.POST("/test", []fizz.OperationOption{
		fizz.ID("test"),
	}, tonic.Handler(h.handle, http.StatusOK))
}

func (h *Handler) handle(c *gin.Context, _ *Evaluation) (*Response, error) {
	var request Request
	err := c.ShouldBindQuery(&request)
        /.../
	audio, err := io.ReadAll(c.Request.Body)
       /.../

	input := Evaluation{
		UserID:          request.UserID,
		Audio:            audio,
	}
	eval := h.Evaluate(c, input)
        /.../

	return &Response{Eval: eval}, nil

and the structs:

type Evaluation struct {
	UserID    string `query:"userId" validate:"required" description:"Id of user"`
	Audio     []byte `format:"binary"`
}

type Request struct {
	UserID    string    `query:"userId" validate:"required" description:"Id of user"`
}

type Response struct {
	Eval    string    `json:"eval"`
}

BTW While generating OpenAPI YAML, the part I'm interested in looks like this:

      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/TestInput'

components:
  schemas:
    TestInput:
      type: object
      properties:
        Audio:
          type: string
          format: binary

and I need this:

      requestBody:
        content:
          audio/wav:
            schema:
              type: string
              format: binary

norbertstrzelecki avatar Mar 06 '24 11:03 norbertstrzelecki