Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix retrying requests with body contents by resetting the reader index of ByteBuf #1281

Merged
merged 3 commits into from
Aug 3, 2022

Conversation

gavinbunney
Copy link
Collaborator

@gavinbunney gavinbunney commented Aug 3, 2022

For TLS handled connections, once the request body has been written to the channel, the ByteBuf.readerIndex is mutated to point to the end of the buffer. This means when retrying requests, subsequent fetches of that buffer return no bytes (as they use the readerIndex). This only affects TLS connections as the SSL handler in netty mutates those indexes (doesn't appear to be the case with plaintext).

Original issue raised with netty from 2018 (netty/netty#7753) eluded to this fact before the changes to pre-buffer bodies was put into zuul (i.e. pre-buffering on 503s that was introduced hid this actual issue of the indexes needing to be reset).

This change resets the readerIndex before retrying a request, and removes the buffering of bodies in retry scenarios.

@@ -178,6 +178,13 @@ public Iterable<HttpContent> getBodyContents() {
return Collections.unmodifiableList(bodyChunks);
}

@Override
public void resetBodyReader() {
for (final HttpContent chunk : bodyChunks) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is it worth only resetting this when we know we have a body, i.e. effectively setBody has been called?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looking at the soft contract we don't set the hasBody boolean in the setBody method. So going to not check that here as the hasBody doesn't determine any logic within the message impl currently.

@gavinbunney gavinbunney marked this pull request as ready for review August 3, 2022 20:52
@artgon
Copy link
Contributor

artgon commented Aug 3, 2022

LGTM! This is a huge improvement over the hack we put in back in 2018.

@artgon artgon self-requested a review August 3, 2022 20:59
@@ -896,6 +846,10 @@ protected void handleOriginNonSuccessResponse(final HttpResponse originResponse,
startedSendingResponseToClient, zuulRequest.hasCompleteBody(), zuulRequest.getMethod());
//detach from current origin.
unlinkFromOrigin();

// ensure body reader indexes are reset so retry is able to access the body buffer
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Worth clarifying in this comment that we want Netty to have access to that ByteBuf, rather than Zuul itself.

@gavinbunney gavinbunney merged commit 4ee00db into master Aug 3, 2022
@gavinbunney gavinbunney deleted the gavin/body-readeridx branch August 3, 2022 23:53
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.

3 participants