I'm trying to test HTTP/2 push promise with Netty, but doesn't seem to work. Use case is as simple as:
index.js
file so I want to send a PUSH_PROMISE
for index.js
index
page.Here is what I did:
int nextStreamId = encoder.connection().local().incrementAndGetNextStreamId();
String authority = request.headers().get("host");
Http2Headers pushHeaders = new DefaultHttp2Headers()
.method("GET")
.path("/assets/index.js")
.authority(authority)
.scheme("https");
encoder.writePushPromise(ctx, Integer.parseInt(streamId), nextStreamId, pushHeaders, 0, ctx.newPromise());
It successfully send a PUSH_PROMISE
to the browser but then the /assets/index.js
file isn't loaded at all (browser waits indefinitely for a response)
This only happens when I send the PUSH_PROMISE
, if I remove those line everything works fine and both files (HTML+js) are served properly via H2.
A full demo is available here (it uses a self-signed certificate so you must accept the unsafe warning)
The source code for PUSH_PROMISE
is here.
Am I doing something wrong?
Thanks.
Your server is sending a PUSH_PROMISE but then it is never actually sending the data to complete the promised stream. The PUSH_PROMISE contract is the server saying to the client "I think you will make a request for this data in the future, so instead of you having to make a request I am already working on sending you this data". Notice the difference in the browser's behavior when you DO NOT sent the PUSH_PROMISE. In this case you get at least 2 requests:
Now contrast this behavior against when your server sends the PUSH_PROMISE:
Notice the browser doesn't even request "/assets/index.js" because you told the browser you already anticipated this request and are working on sending the result. So if you send the data for "/assets/index.js" after the PUSH_PROMSIE the browser will be happy.