Uploaded image for project: 'Undertow'
  1. Undertow
  2. UNDERTOW-1877

HTTP2 implementation returns PUSH PROMISES for frames that are already a promise (even id)

XMLWordPrintable

    • Hide
      • Package and deploy the attached project.
        unzip push-promises.zip
        cd push-promises
        mvn clean package
        
      • Deploy the application in wildfly.
      • Start chrome/chromium in incognito (it should be the first time! It you don't see it, close and start in incognito the whole browser again).
      • Access the index page: https://localhost:8443/push-promises/index.html
      • ERR_HTTP2_PROTOCOL_ERROR is shown by the browser (see attached screenshot). Tested in chromium 88 (fedora box) and google chrome 89.
      Show
      Package and deploy the attached project. unzip push-promises.zip cd push-promises mvn clean package Deploy the application in wildfly. Start chrome/chromium in incognito (it should be the first time! It you don't see it, close and start in incognito the whole browser again). Access the index page: https://localhost:8443/push-promises/index.html ERR_HTTP2_PROTOCOL_ERROR is shown by the browser (see attached screenshot). Tested in chromium 88 (fedora box) and google chrome 89.
    • Hide

      Disable push promises at undertow level:

      /subsystem=undertow/server=default-server/https-listener=https:write-attribute(name=http2-enable-push, value=false)
      
      Show
      Disable push promises at undertow level: /subsystem=undertow/server= default -server/https-listener=https:write-attribute(name=http2-enable-push, value= false )
    • Undefined

      The http2 implementation in undertow returns promises even when the request being processed is a push promise. This is forbidden by spec:

      PUSH_PROMISE frames MUST only be sent on a peer-initiated stream that is in either the "open" or "half-closed (remote)" state.

      The error can be reproduced using a servlet that serves several resources and uses promises in some of them. For example:

      if (request.getServletPath().endsWith(".html") || request.getPathInfo().endsWith(".html")) {
                  PushBuilder pushBuilder = request.newPushBuilder();
                  if (pushBuilder != null) {
                      // pushing css and js in advance
                      pushBuilder.path("resources/one.css").push();
                      pushBuilder.path("resources/one.js").push();
                  }
                  // slow the index to let chrome to receive the invalid push promise
                  try {Thread.sleep(1000L);} catch (InterruptedException e) {}
                  getServletContext()
                          .getRequestDispatcher("/WEB-INF/index.html")
                          .forward(request, response);
              } else if (request.getPathInfo().endsWith(".css")) {
                  PushBuilder pushBuilder = request.newPushBuilder();
                  if (pushBuilder != null) {
                      // pushing images in advance
                      pushBuilder.path("resources/one.png").push();
                  }
                  getServletContext()
                          .getRequestDispatcher("/WEB-INF/sample.css")
                          .forward(request, response);
              } else if (request.getPathInfo().endsWith(".js")) {
                  getServletContext()
                          .getRequestDispatcher("/WEB-INF/sample.js")
                          .forward(request, response);
              } else if (request.getPathInfo().endsWith(".png")) {
                  getServletContext()
                          .getRequestDispatcher("/WEB-INF/sample.png")
                          .forward(request, response);
              } else {
                  throw new ServletException("Invalid request");
              }
      

      The index.html generates two promises (one.css and one.js) and in turn one.css generates another promise for one.png. This is not very common but it should be OK for the server. Right now the browser receives a promise from for the png file initiated by the css promise, which is incorrect by spec because the css file was not requested by the client.

            rhn-support-rmartinc Ricardo Martin Camarero
            rhn-support-rmartinc Ricardo Martin Camarero
            Votes:
            0 Vote for this issue
            Watchers:
            3 Start watching this issue

              Created:
              Updated:
              Resolved: