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

Are nested or recursive HTTP/2 push streams possible? #1135

Closed
robbie-mac opened this issue Mar 1, 2018 · 2 comments
Closed

Are nested or recursive HTTP/2 push streams possible? #1135

robbie-mac opened this issue Mar 1, 2018 · 2 comments

Comments

@robbie-mac
Copy link

robbie-mac commented Mar 1, 2018

  • Node.js Version: 9.7.0
  • OS: Windows
  • Scope (install, code, runtime, meta, other?): code
  • Module (and version) (if relevant): HTTP/2

@jasnell or anybody else that would care to comment. I'm wondering a couple of things regarding HTTP/2 push streams:
If I understand things correctly, push streams are intended to proactively serve resources that are needed to get a page on screen as quickly as possible. Basically compressing the fetch-parse-fetch-parse loop.

So with that in mind, I though of this: index.htm needs a few resources, css and js. The js file needs a few resources, say some json data.

I want to push resources to a document served by a push stream.

So here is what I tried:

//server = http2.createSecureServer(); init code removed for brevity
server.addListener('stream', function (stream, headers) {
let resourcePath = path.join(serverRootPath, headers[HTTP2_HEADER_PATH]);
stream.respondWithFile(resourcePath, {
            'content-type': mimeTypes.get(resourcePath.match(mimeRegExp)[0]),
        });
}); 

Yay I have a static file server, except no push. So I modify to this:

//server = http2.createSecureServer(); init code removed for brevity
server.addListener('stream', function (stream, headers) {
let resourcePath = path.join(serverRootPath, headers[HTTP2_HEADER_PATH]);
stream.respondWithFile(resourcePath, {
            'content-type': mimeTypes.get(resourcePath.match(mimeRegExp)[0]),
        });
stream.pushStream({ ':path': pushResourcePath }, { 'parent': stream.id }, (err, stream, headers) => {
            stream.respondWithFile(path.join(serverRoot, pushResourcePath), {
                'content-type': mimeTypes.get(path.join(serverRoot,pushResourcePath).match(mimeRegExp)[0]),
            });
        });
}); 

Yay, I have a working push stream. Then I add a push stream inside of the push stream callback

//server = http2.createSecureServer(); init code removed for brevity
server.addListener('stream', function (stream, headers) {
    let resourcePath = path.join(serverRootPath, headers[HTTP2_HEADER_PATH]);
    stream.respondWithFile(resourcePath, {
        'content-type': mimeTypes.get(resourcePath.match(mimeRegExp)[0]),
    });
    stream.pushStream({ ':path': pushResourcePath }, { 'parent': stream.id }, (err, stream, headers) => {
        stream.respondWithFile(path.join(serverRoot, pushResourcePath), {
            'content-type': mimeTypes.get(path.join(serverRoot, pushResourcePath).match(mimeRegExp)[0]),
        });
        stream.pushStream({ ':path': subPushResourcePath }, { 'parent': stream.id }, (err, stream, headers) => {
            stream.respondWithFile(path.join(serverRoot, subPushResourcePath), {
                'content-type': mimeTypes.get(path.join(serverRoot, subPushResourcePath).match(mimeRegExp)[0]),
            });
        });
    });
}); 

The train derails here. I get an error stating an invalid argument for the nested push stream, and the json file is served through another get request.

What am I missing? The nested pushstream callback gets an error instead of a stream, but I don't understand why.

On a more design level curiosity, why was the stream.pushStream() function designed with a callback, and not as a promise? Given that pushStream generates a request Promise... or am I conflating two different uses of Promise?

@robbie-mac robbie-mac changed the title Are nested or recursive HTTP/2 push streams posible? Are nested or recursive HTTP/2 push streams possible? Mar 1, 2018
@robbie-mac
Copy link
Author

I realized it would make sense to provide the error:

{ Error [ERR_HTTP2_ERROR]: Invalid argument
at ServerHttp2Stream.pushStream (internal/http2/core.js:2095:17)
at file:///D:/http2_experimental_server/src/server.mjs:106:24
at process._tickCallback (internal/process/next_tick.js:114:19)
code: 'ERR_HTTP2_ERROR',
name: 'Error [ERR_HTTP2_ERROR]',
errno: -501 }

@robbie-mac
Copy link
Author

The more I try to figure this out, the more I feel this might be a bug. Closing an moving to nodejs/node#19095

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

1 participant