Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Missing "as" attribute in documentation on server push #1303

Closed
utrenkner opened this issue May 17, 2017 · 11 comments
Closed

Missing "as" attribute in documentation on server push #1303

utrenkner opened this issue May 17, 2017 · 11 comments

Comments

@utrenkner
Copy link
Contributor

Due to my problems with pushing assets to Chrome, I learned that the "as" attribute of the preload link is not optional but required, e.g. <link rel=preload as=script href=...>.

In the h2o documentation, this is not mentioned, see several code examples on the HTTP/2 Directives.

And the example for "Pushing asset files" given on Using Mruby must actually be written with two separate mruby-handlers - one for the CSS file with "as=style" and one for the JS file with "as=script"

paths:
  "/":
    mruby.handler: |
      Proc.new do |env|
        push_paths = []
        # push css and js when request is to dir root or HTML
        if /(\/|\.html)\z/.match(env["PATH_INFO"])
          push_paths << "/css/style.css"
        end
        [399, push_paths.empty? ? {} : {"link" => push_paths.map{|p| "<#{p}>; rel=preload; as=style"}.join("\n")}, []]
      end
    mruby.handler: |
      Proc.new do |env|
        push_paths = []
        # push css and js when request is to dir root or HTML
        if /(\/|\.html)\z/.match(env["PATH_INFO"])
          push_paths << "/js/app.js"
        end
        [399, push_paths.empty? ? {} : {"link" => push_paths.map{|p| "<#{p}>; rel=preload; as=script"}.join("\n")}, []]
      end
    fastcgi.connect: ...

The relative attribute for each content type can be found in the draft standard.

@worenga
Copy link

worenga commented May 17, 2017

The problem is that we are using link headers to control the server's push behavior. However the link headers are also dasy-chained to the browser which in the case of a client that does not support H2 Push or H1 will lead to an invalid link header.

If you are interested only in controlling H2 Server Push then you might add the x-http2-push-only attribute to the link header. Newer h2o versions will then remove the pushed path from the link header.

For backwards compatibility with H1 and H2 NoPush i think that should be mentioned in the docs.

@utrenkner
Copy link
Contributor Author

Interesting - I had seen that change, but at the time I did not understand what it should be used for.

However, I am not quite sure how to implement this. Do I just include in the above example a x-http2-push-only=true, e.g.

..
        [399, push_paths.empty? ? {} : {"link" => push_paths.map{|p| "<#{p}>; rel=preload; as=script x-http2-push-only=true"}.join("\n")}, []]
...

@deweerdt
Copy link
Member

deweerdt commented May 17, 2017

@utrenkner the link header should look like this:

Link: </assets/style.css>; as=style; rel=preload; x-http2-push-only

@deweerdt
Copy link
Member

Note that the spec says that the element is optional.

The as attribute's value must be a valid request destination. If the provided value is omitted, the value is initialized to the empty string.

It also says that it is appropriate to preload when:

When the as attribute of the link element of a preload link that is already in a Document is set or changed to a value that does not or no longer matches the request destination of the previous obtained external resource, if any.

which is what I assume makes Chrome re-fetch the resource. I think the spec is missing a piece indicating how pushes are supposed to set their request destination.

@utrenkner
Copy link
Contributor Author

Thank you for the clarification. As for the specs, I must admit that you are right.

I had read this recent article on Smashing Magazine, which received clarification on exactly this issue by Yoav Weiss. The article says:The as=style portion of the header is not optional. It informs the browser of the pushed asset’s content type. In this case, we use a value of style to indicate that the pushed asset is a style sheet. You can specify other content types. It’s important to note that omitting the as value can result in the browser downloading the pushed resource twice. So don’t forget it!

So technically, one can omit the 'as' argument - but then one cannot expect that the browser does what one wants: To download the resource early and only once.

@worenga
Copy link

worenga commented May 19, 2017

I just tested x-http2-push-only via mruby and it does not seem to remove the link header or the path as expected.

@utrenkner
Copy link
Contributor Author

@worenga I can confirm this. I just tried it on a test domain - here the result of WPT with IE10.

@utrenkner
Copy link
Contributor Author

Looking at this discussion on the W3-Preload standard, I would like to emphasize my original proposal, that we should really include the "as" attribute in the documentation. In the discussion the editors of the draft standard explain that it is de-facto required, even though it is not universally implemented this way in client software.

That said, I was wondering, if we could add a feature to h2o, which would automatically map mime-types to request destinations. As @igrigorik explains, this is not in the specs. But I think it could be included in h2o, at least as a default which can be overriden. Then we would not have to include separate mruby handlers for each request destination, when we add resources to push-paths. For our site in question, we now have 4 such mruby-handlers (for style, script, image and font).

@jbergstroem
Copy link

@utrenkner said:
That said, I was wondering, if we could add a feature to h2o, which would automatically map mime-types to request destinations. As @igrigorik explains, this is not in the specs. But I think it could be included in h2o, at least as a default which can be overriden.

I like this idea.

@deweerdt
Copy link
Member

that we should really include the "as" attribute in the documentation.

#1307

@utrenkner
Copy link
Contributor Author

Thanks to @deweerdt for the patch to the docs.

And it contains a much simpler way to add several different resources types within the same mruby-handler.

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

No branches or pull requests

4 participants