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 Chunked APIs sending incorrect responses to HEAD requests #92042

Merged
merged 3 commits into from Dec 1, 2022

Conversation

original-brownbear
Copy link
Member

Response bodies must always be empty for HEAD requests. Since the request encoder does not know that its dealing with a response to a HEAD request we have to indicate this fact to it. Also, needed to adjust the test http client to use the http-codec so it is able to correlate what responses are meant for HEAD requests and will correctly read responses for HEAD requests.
Without this change the added test reproduces the extra bytes and fails with an assert about more than one response received.

closes #92032

Response bodies must always be empty for HEAD requests.
Since the request encoder does not know that its dealing with a response
to a HEAD request we have to indicate this fact to it.
Also, needed to adjust the test http client to use the http-codec so it is able
to correlate what responses are meant for HEAD requests and will correctly read
responses for HEAD requests.
Without this change the added test reproduces the extra bytes and fails with an assert
about more than one response received.

closes elastic#92032
@original-brownbear original-brownbear added >bug :Distributed/Network Http and internode communication implementations v8.7.0 labels Dec 1, 2022
@elasticsearchmachine elasticsearchmachine added the Team:Distributed Meta label for distributed team label Dec 1, 2022
@elasticsearchmachine
Copy link
Collaborator

Pinging @elastic/es-distributed (Team:Distributed)

@elasticsearchmachine
Copy link
Collaborator

Hi @original-brownbear, I've created a changelog YAML for you.

.addLast("encoder", new HttpResponseEncoder())
.addLast("encoder", new HttpResponseEncoder() {
@Override
protected boolean isContentAlwaysEmpty(HttpResponse msg) {
Copy link
Member Author

Choose a reason for hiding this comment

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

Same fix of sorts is used by vert.x, see discussion in netty/netty#6761

protected boolean isContentAlwaysEmpty(HttpResponse msg) {
// non-chunked responses (Netty4HttpResponse extends Netty's DefaultFullHttpResponse) with chunked transfer
// encoding are only sent by us in response to HEAD requests an must always have an empty body
return msg instanceof Netty4HttpResponse && HttpUtil.isTransferEncodingChunked(msg)
Copy link
Member Author

Choose a reason for hiding this comment

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

It's a little dirty to guess things like this, but it seemed nicer than unnecessarily adding another field to the netty response implementation.

Copy link
Contributor

Choose a reason for hiding this comment

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

Seems ok but would it also work to just check if there's anything in the body (i.e. ((Netty4HttpResponse)msg).content().isReadable())? At least IMO we should assert there's no body here.

Copy link
Member Author

Choose a reason for hiding this comment

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

++ added the assertion

Copy link
Contributor

@DaveCTurner DaveCTurner left a comment

Choose a reason for hiding this comment

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

Looks good, one question.

protected boolean isContentAlwaysEmpty(HttpResponse msg) {
// non-chunked responses (Netty4HttpResponse extends Netty's DefaultFullHttpResponse) with chunked transfer
// encoding are only sent by us in response to HEAD requests an must always have an empty body
return msg instanceof Netty4HttpResponse && HttpUtil.isTransferEncodingChunked(msg)
Copy link
Contributor

Choose a reason for hiding this comment

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

Seems ok but would it also work to just check if there's anything in the body (i.e. ((Netty4HttpResponse)msg).content().isReadable())? At least IMO we should assert there's no body here.

Copy link
Contributor

@DaveCTurner DaveCTurner left a comment

Choose a reason for hiding this comment

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

LGTM

@DaveCTurner
Copy link
Contributor

DaveCTurner commented Dec 1, 2022

Are we going to backport this to 8.6 (and maybe even 8.5?). Seems safe enough, although it might not be a very impactful bug it'd be embarrassing for someone to hit it in the months before 8.7 comes out.

@original-brownbear original-brownbear added auto-backport-and-merge Automatically create backport pull requests and merge when ready v8.6.0 labels Dec 1, 2022
@original-brownbear
Copy link
Member Author

Sure lets do 8.6 I'd say. It's almost impossible to hit this as you point out, maybe not worth adding the noise to 8.5 but 8.6 seems fine.
Thanks David!

@original-brownbear original-brownbear merged commit d5ee6ab into elastic:main Dec 1, 2022
original-brownbear added a commit to original-brownbear/elasticsearch that referenced this pull request Dec 1, 2022
…c#92042)

Response bodies must always be empty for HEAD requests.
Since the request encoder does not know that its dealing with a response
to a HEAD request we have to indicate this fact to it.
Also, needed to adjust the test http client to use the http-codec so it is able
to correlate what responses are meant for HEAD requests and will correctly read
responses for HEAD requests.
Without this change the added test reproduces the extra bytes and fails with an assert
about more than one response received.

closes elastic#92032
elasticsearchmachine pushed a commit that referenced this pull request Jan 3, 2023
…92042) (#92049)

* Fix Chunked APIs sending incorrect responses to HEAD requests (#92042)

Response bodies must always be empty for HEAD requests.
Since the request encoder does not know that its dealing with a response
to a HEAD request we have to indicate this fact to it.
Also, needed to adjust the test http client to use the http-codec so it is able
to correlate what responses are meant for HEAD requests and will correctly read
responses for HEAD requests.
Without this change the added test reproduces the extra bytes and fails with an assert
about more than one response received.

closes #92032

* fix compile
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
auto-backport-and-merge Automatically create backport pull requests and merge when ready >bug :Distributed/Network Http and internode communication implementations Team:Distributed Meta label for distributed team v8.6.0 v8.7.0
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Chunked HTTP APIs send (final/empty) chunk in response to HEAD requests
3 participants