Jon Chambers
Jon Chambers

Reputation: 664

Sending an HTTP/2 client preface with Netty

I'm trying to get started with HTTP/2 in Netty. I've tried the "hello world" example, and it works as expected. In the example, the pipelines look something like this:

Server:

Client:

I'm trying—mostly for educational purposes—to build a client that doesn't do HTTP-to-HTTP/2 conversion (i.e. I'm trying to write something "closer to the metal"). My server looks almost exactly like the example server, but my client pipeline looks almost exactly like the server pipeline:

The trouble I'm running into is that the client preface doesn't seem to be sent as expected:

Dec 02, 2015 9:37:19 PM io.netty.handler.codec.http2.Http2ConnectionHandler processGoAwayWriteResult SEVERE: Sending GOAWAY failed: lastStreamId '0', errorCode '1', debugData 'HTTP/2 client preface string missing or corrupt. Hex dump for received bytes: 000000040000000000'. Forcing shutdown of the connection. javax.net.ssl.SSLException: SSLEngine closed already

One other thing to mention here is that I'm going straight for HTTP/2 via TLS, and am not trying to do a cleartext upgrade.

I've read through all of the "hello world" example code and through all of the base classes, but I'm not seeing where the client sends its preface in the example. I suspect this has something to do with the self-destructing settings handler in the example, but can't see what that does other than control the timing of non-preface traffic later.

I've also tried playing with the server(boolean) method in the Http2ConnectionHandler Builder, but without much success. Am I missing something obvious? How should I set up my client pipeline (or what steps should I take AFTER setting up my pipeline) to manage the preface exchange?

Alternatively, this could be happening because the client is trying to send a GOAWAY before the preface exchange happens (since all I'm trying to do is connect). If that's the case, though, what's the "right" way to open a connection and hold it open (if only long enough to let the preface exchange happen)? Is the self-destructing handler the "expected" approach?

EDIT: To clarify, I'm not sending a GOAWAY on purpose. If this is what's happening, it's a mystery in its own right.

Thanks kindly!

Upvotes: 3

Views: 5659

Answers (1)

Jon Chambers
Jon Chambers

Reputation: 664

I am on crazy pills. Building the client connection handler with .server(false) made everything work as expected; I must have just been running old code when I tried it before. Apologies for the noise!

EDIT: More specifically, the problem appears to be that I was trying to do .server(false) inside the build0 method of my connection handler builder. It appears this isn't allowed (or, at least, doesn't work), but I'm not yet sure why. Calling .server(false) from the thing actually using the builder has the desired results.

Upvotes: 2

Related Questions