Skip to content

Conversation

@jamietanna
Copy link
Contributor

@jamietanna jamietanna commented Apr 7, 2025

As noted in #743, some users of the openapi3filter, largely via
oapi-codegen and openapi.tanna.dev/go/validator0 are seeing that
when using an AuthenticationFunc, this can lead to errors such as:

request body has an error: value is required but missing

Or:

request body has an error: reading failed: http: invalid Read on closed Body

This turns out to be down to the fact that a call to the
AuthenticationFunc may read the request body, but due to the way that
Go's io.Readers can only be read once, this then means the body cannot
be read by anyone else further in the request chain.

To resolve this, we can make sure that each iteration of the
AuthenticationFunc gets a fresh copy of the request body (in its own
io.Reader).

This follows logic that exists within the ValidateRequestBody method,
with an additional layer of caching the raw bytes from the body.

We also add tests to validate:

  • calling the ValidateRequest body function with an
    AuthenticationFunc that reads the request body
  • using an integration test with a test HTTP server also works,
    indicating that the HTTP handler can then read the request body itself

Closes #743.

@jamietanna jamietanna changed the title rew! openapi3filter: don't consume request body in AuthenticatorFunc openapi3filter: don't consume request body in AuthenticatorFunc Apr 7, 2025
@jamietanna jamietanna force-pushed the defect/body branch 3 times, most recently from d8931da to 40c18e4 Compare April 7, 2025 13:53
As noted in getkin#743, some users of the `openapi3filter`, largely via
`oapi-codegen` and `openapi.tanna.dev/go/validator`[0] are seeing that
when using an `AuthenticationFunc`, this can lead to errors such as:

    request body has an error: value is required but missing

Or:

    request body has an error: reading failed: http: invalid Read on closed Body

This turns out to be down to the fact that a call to the
`AuthenticationFunc` may read the request body, but due to the way that
Go's `io.Reader`s can only be read once, this then means the body cannot
be read by anyone else further in the request chain.

To resolve this, we can make sure that each iteration of the
`AuthenticationFunc` gets a fresh copy of the request body (in its own
`io.Reader`).

This follows logic that exists within the `ValidateRequestBody` method,
with an additional layer of caching the raw bytes from the body.

We also add tests to validate:

- calling the `ValidateRequest` body function with an
  `AuthenticationFunc` that reads the request body
- using an integration test with a test HTTP server also works,
  indicating that the HTTP handler can then read the request body itself

Closes getkin#743.

[0]: https://gitlab.com/jamietanna/httptest-openapi/-/issues/5
@jamietanna jamietanna marked this pull request as ready for review April 7, 2025 13:59
@fenollp fenollp merged commit 75e2cc5 into getkin:master Apr 7, 2025
5 checks passed
@fenollp
Copy link
Collaborator

fenollp commented Apr 7, 2025

Thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

http: invalid Read on closed Body error comes in AuthenticationFunc with request body validation

2 participants