Skip to content

HTTP/2: Ensure newStream() is called only once per connection upgrade and the correct handler is used#9396

Merged
normanmaurer merged 1 commit into4.1from
upgrade_stream
Jul 23, 2019
Merged

HTTP/2: Ensure newStream() is called only once per connection upgrade and the correct handler is used#9396
normanmaurer merged 1 commit into4.1from
upgrade_stream

Conversation

@normanmaurer
Copy link
Copy Markdown
Member

@normanmaurer normanmaurer commented Jul 23, 2019

Motivation:

3062993 introduced some code change to move the responsibility of creating the stream for the upgrade to Http2FrameCodec. Unfortunaly this lead to the situation of having newStream().setStreamAndProperty(...) be called twice. Because of this we only ever saw the channelActive(...) on Http2StreamChannel but no other events as the mapping was replaced on the second newStream().setStreamAndProperty(...) call.

Beside this we also did not use the correct handler for the upgrade stream in some cases

Modifications:

  • Just remove the Http2FrameCodec.onHttpClientUpgrade() method and so let the base class handle all of it. The stream is created correctly as part of the ConnectionListener implementation of Http2FrameCodec already.
  • Consolidate logic of creating stream channels
  • Adjust unit test to capture the bug

Result:

Fixes #9395

@normanmaurer
Copy link
Copy Markdown
Member Author

@bryce-anderson I think this should fix your problem.. please verify.

@normanmaurer normanmaurer added this to the 4.1.38.Final milestone Jul 23, 2019
@normanmaurer
Copy link
Copy Markdown
Member Author

@netty-bot test this please

… and the correct handler is used

Motivation:

3062993 introduced some code change to move the responsibility of creating the stream for the upgrade to Http2FrameCodec. Unfortunaly this lead to the situation of having newStream().setStreamAndProperty(...) be called twice. Because of this we only ever saw the channelActive(...) on Http2StreamChannel but no other events as the mapping was replaced on the second newStream().setStreamAndProperty(...) call.

Beside this we also did not use the correct handler for the upgrade stream in some cases

Modifications:

- Just remove the Http2FrameCodec.onHttpClientUpgrade() method and so let the base class handle all of it. The stream is created correctly as part of the ConnectionListener implementation of Http2FrameCodec already.
- Consolidate logic of creating stream channels
- Adjust unit test to capture the bug

Result:

Fixes #9395
@normanmaurer
Copy link
Copy Markdown
Member Author

@bryce-anderson this took me a while to figure out completely... There were actually two problems. This PR fixes all of them and now finagle tests pass again here as well. Can you please verify ?

@normanmaurer normanmaurer changed the title HTTP/2: Ensure newStream() is called only once per connection upgrade HTTP/2: Ensure newStream() is called only once per connection upgrade and the correct handler is used Jul 23, 2019
@normanmaurer
Copy link
Copy Markdown
Member Author

@netty-bot test this please

@bryce-anderson
Copy link
Copy Markdown
Contributor

Looks like it works from my end!

@normanmaurer
Copy link
Copy Markdown
Member Author

@bryce-anderson cool... please approve

Copy link
Copy Markdown
Contributor

@bryce-anderson bryce-anderson left a comment

Choose a reason for hiding this comment

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

Looks a lot better.

}

private static boolean isServer(ChannelHandlerContext ctx) {
return ctx.channel().parent() instanceof ServerChannel;
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

This feels pretty brittle. Would this be better as a protected member of Http2ChannelDuplexHandler which has access to the connection() through the frameCodec field?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

we could do this but I wanted to keep the handlers as much as separated as possible ...

@Override
final void onHttp2StreamStateChanged(ChannelHandlerContext ctx, DefaultHttp2FrameStream stream) {

switch (stream.state()) {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

This looks identical to the Http2MultiplexHandler code other than the type of AbstractHttp2StreamChannel created (Http2MultiplexCodecStreamChannel vs Http2MultiplexHandlerStreamChannel). Could that be lifted into Http2ChannelDuplexHandler?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Maybe it's okay since the multiplex codec is deprecated and presumably will be removed at some point?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

yeah that was my thinking

@normanmaurer
Copy link
Copy Markdown
Member Author

@bryce-anderson so with this in does the whole finagle build pass ?

@bryce-anderson
Copy link
Copy Markdown
Contributor

@normanmaurer, yes, it looks like we're back in business. Thanks!

@normanmaurer
Copy link
Copy Markdown
Member Author

@bryce-anderson ok cool...let me merge this one.

@normanmaurer normanmaurer merged commit 513e9f2 into 4.1 Jul 23, 2019
@normanmaurer normanmaurer deleted the upgrade_stream branch July 23, 2019 19:05
normanmaurer added a commit that referenced this pull request Jul 23, 2019
… and the correct handler is used (#9396)

Motivation:

3062993 introduced some code change to move the responsibility of creating the stream for the upgrade to Http2FrameCodec. Unfortunaly this lead to the situation of having newStream().setStreamAndProperty(...) be called twice. Because of this we only ever saw the channelActive(...) on Http2StreamChannel but no other events as the mapping was replaced on the second newStream().setStreamAndProperty(...) call.

Beside this we also did not use the correct handler for the upgrade stream in some cases

Modifications:

- Just remove the Http2FrameCodec.onHttpClientUpgrade() method and so let the base class handle all of it. The stream is created correctly as part of the ConnectionListener implementation of Http2FrameCodec already.
- Consolidate logic of creating stream channels
- Adjust unit test to capture the bug

Result:

Fixes #9395
@bryce-anderson
Copy link
Copy Markdown
Contributor

@normanmaurer, do you have an idea of when 4.1.38 will be released?
And thanks again for the fix.

@normanmaurer
Copy link
Copy Markdown
Member Author

@bryce-anderson tomorrow or Thursday.

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.

Commit 306299323cd seems to have broken finagle tests

2 participants