2

I'm trying to test HTTP/2 push promise with Netty, but doesn't seem to work. Use case is as simple as:

  1. Request home/index page
  2. Index page depends on a index.js file so I want to send a PUSH_PROMISE for index.js
  3. Write and flush content for 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.

Edgar Espina
  • 507
  • 4
  • 10

1 Answers1

2

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:

  1. /
  2. /assets/index.js
  3. [Your browser may also request /favicon.ico]

Now contrast this behavior against when your server sends the PUSH_PROMISE:

  1. /
  2. [Your browser may also request /favicon.ico]

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.

Scott Mitchell
  • 716
  • 4
  • 7
  • Thanks! Got PUSH_PROMISE wrong! Thought the browser was supposed to make a new request when it get the PUSH_PROMISE. – Edgar Espina Aug 11 '16 at 12:19
  • Hi Scott, how do I send ask netty to process a `new request` (the one I want to push)? or how do I put a request for `assets/index.js` and make sure the correct handlers or pipeline is executed? For example undertow or jetty does this automatically, just need to use their PUSH API. – Edgar Espina Aug 21 '16 at 16:54