kin-openapi
kin-openapi copied to clipboard
http: invalid Read on closed Body error comes in AuthenticationFunc with request body validation
I have a POST request with the request body parameter. I am using OapiRequestValidatorWithOptions to validate and authenticate each and every request. However, it gave http: invalid Read on closed Body error and fails to bind the JSON to the request object.
I was able to avoid the error by setting ExcludeRequestBody so ValidateRequest skips request body validation as shown in the example below.
validator := middleware.OapiRequestValidatorWithOptions(swagger,
&middleware.Options{
Options: openapi3filter.Options{
ExcludeRequestBody: true,
AuthenticationFunc: NewAuthenticator(middleware.AuthConfig{}),
},
})
However, I would like to continue to use ValidateRequest. Is there any solution to this?
I faced the same issue today. I'm using an authenticator function with Echo. In the authenticator, I updated the request object using Echo context by setting a new context with a JWT token. EDIT: It seems it caused the request duplication and led to the fact that now I had two request objects.
Before:
c.SetRequest(c.Request().WithContext(xauth.WithToken(c.Request().Context(), parsed)))
Now:
req := input.RequestValidationInput.Request.WithContext(xauth.WithToken(input.RequestValidationInput.Request.Context(), parsed))
input.RequestValidationInput.Request = req
c.SetRequest(req)
this is because the body is closed in the ValidateRequestBody method
if req.Body != http.NoBody && req.Body != nil {
--> defer req.Body.Close() <--
var err error
if data, err = ioutil.ReadAll(req.Body); err != nil {
return &RequestError{
input: input,
RequestBody: requestBody
Reason: "reading failed",
err: err,
}
}
@nazirok did you end up fixing it? How did you handle it? It only happens when using AuthenticationFunc and changing the request context. Without it there's no issue
Also seeing this issue with v0.120.0 - go1.21.1 darwin/arm64 used with github.com/deepmap/oapi-codegen/pkg/chi-middleware
Setting ExcludeRequestBody: true is a temporary, but unacceptable workaround.
Options: openapi3filter.Options{
ExcludeRequestBody: true,
},
I've also encountered this with v0.126.0.
This change in nethttp-middleware fixed it for me: copying the request body before validation, and then resetting it afterwards with the copy.
Although it's not clear why this happens, as openapi3filter.ValidateRequest() correctly resets the request body too.