-
Notifications
You must be signed in to change notification settings - Fork 186
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
Doesn't work with Express.js #100
Comments
I'm getting the same error. |
Thanks for reporting. This would indeed be nice. I expect to have some time to look into this in about a week. Feel free to send pull requests if you happen to find the root if the issue. |
Now I found it not easy to fix... Express replaces the request's So, your IncomingMessage inherits PassThrough at first but soon loses |
Thanks for digging deeper! I don't have an idea for a fix yet, but will be thinking about possible solutions... |
Please feel free to open a new bug report in Express.js as well, if there is something we can fix or change to make it work better with |
In node-http2, all of the features can be implemented without relying on inheritance, even without performance loss. Both the IncomingMessage class and inheriting from PassThrough is just convenience, they are not necessary. In contrast, in express, implementing the object augmentation without mangling the proto would result in performance loss. But it needs some work, and the code will be somewhat uglier... I'm still thinking about a prettier solution. |
So, although IncomingMessage and PassThrough are avoidable, both IncomingRequest and IncomingResponse are necessary (or avoidable only with performance penalty). And the protos belonging to these classes would be replaced by express on instances... Maybe express could check if the proto that it wants to replace is really the built-in IncomingMessage, and if not, it would just copy the augmentation methods to the instance itself instead of the proto replacement. It would be a performance penalty, but only when used with node-http2 (or other alternative HTTP API implementation). @dougwilson what do you think? |
So if the only reason why http2 doesn't work with Express is because of this prototype stuff, then it should be fixed in 5.0 this summer. If we are brainstorming on a method to get it into 4.x and also keep backwards compatibility, then we can and a PR would be welcome :) Some things to think of is that with sub apps, we don't know the prototype we want to replace, so you would need to walk down the entire chain searching for IncomingRequest. We also need to think about how to handle things like non-configurable properties, where today there is no issue and Express will overwrite them, but changing to a non-proto-replacement may cause different behavior or errors for people. In Express 5 we are moving to prototype injection over replacement, though it's not backwards compatible. |
Also we need to consider that if we put things on the instance itself, it'll change behavior of people doing Object.keys() or hasOwnProperty and the like, so we have to take that into consideration as well, if this change when using http2 will cause issues in various existing middleware modules. |
I would be happy with 5.0 as a solution without support for 4.x. But, what do you mean by prototype injection? If it is |
It would not be that code, since that code would not allow for the co-existence of http2 and node.js core requests on the same express app, which is something we want. |
Yeah, it's pretty tricky to implement this thing properly. If express is going to do something like this, then I think both http2 and http1 would work: maintain a map of observed protos (in this case, the built-in IncomingMessage, and node-http2 IncomingRequest), and make a separate injectable proto object for each of them, and always inject the appropriate one. It's up to you of course, just thinking about the proper way of implementing this... |
One problem with the mapped idea is that we would have to take a dependency on http2 and then, for equality to work, people would have to only use the same version of http2 on which express is getting the http2 prototype reference from. |
Yes if the map is static. But it could start as empty (or preloaded with But anyway, this is probably not the right place to talk about it. Should I
|
There is already an open issue in Express that is linked to this issue. |
@dougwilson would be helpful if you have posted the link here |
Related Express issue: |
@crepererum for some reason that issue was locked and discussion is restricted to collaborators 👎 |
@olalonde Well let's hope that means something is being done about it. This pretty much breaks HTTP/2's implementation into ExpressJS, further holding back nodeJS applications to HTTP/1.1 I'm actually surprised that it's taking this long to get a reliable implementation of HTTP/2 going. |
@stanier me too. Surprised core node doesn't support HTTP2 already. |
@ralph3991 imho, Joyent's node has been slower on releases. I'm more surprised that io.js hasn't made a decision on it. They seem rather in limbo on how to deal with it. |
@stanier wow, I didn't even know that existed. Thank you. I checked it out and it looks much better than node for the cutting edge. Yeah id have to agree again, they support ECMAScript 6 but not HTTP2? Hmm. I'm just happy rfc7540 is finally finished and developers can start making final releases. I checked out https://github.com/molnarg/node-http2 but they are still on Draft 16 :( |
@ralph3991 not true, as of v3.2.0, node-http2 advertises h2, not draft 16 (any documents that say otherwise are just out of date - pull requests welcome to fix it!) Also, this conversation is quite the derail from the actual purpose of this issue. If it continues, I may have to lock the issue. |
👍 |
any updates on this? last comment on the express thread is to raise the issue here, does not sound like they are going to fix. in the meantime we're using connect directly |
This is because people are linking to the wrong thread in the Express repo; the correct thread is listed right at the top of this issue: There is no backwards-compatible way to fix this in Express, so without anything happening here, it won't be until Express 5.0 that this module (and any other server that does not inherit from Node.js core http prototype) will work with Express. |
@molnarg, is a solution being worked on in this repo, or are we to wait for Express v5 and hope it resolves any issues? |
@CodeTheInternet, assume that responsibility for the issue is being thrown on @strongloop |
+1 |
Please ignore my last comment - apologies. |
I would like to create an example with this dependency. |
Using: "express": "^5.0.0-alpha.2",
"http2": "^3.3.4", const http2 = require('http2');
const express = require('express');
const yargs = require('yargs');
const path = require('path');
const fs = require('fs');
const argv = yargs
.help()
.strict()
.options({
port: {
default: 8000,
demand: true,
type: 'number'
}
})
.argv;
process.on('unhandledRejection', (reason, promise) => {
/* eslint-disable no-console */
console.log('Unhandled RejectionPromise');
console.log('promise', promise);
console.log('reason', reason);
console.log('reason.stack', reason.stack);
/* eslint-enable */
});
const app = express();
app.get('/', (req, res) => {
res.json({foo: 'test'});
});
/* eslint-disable no-console, no-unused-vars */
app.use((err, req, res, next) => {
console.error(err.stack);
/* eslint-enable */
res
.status(500)
.send('Internal Server Error');
});
http2
.createServer({
log: require('bunyan').createLogger({name: 'myapp'}),
key: fs.readFileSync(path.resolve(__dirname, './localhost.key')),
cert: fs.readFileSync(path.resolve(__dirname, './localhost.crt'))
}, app)
.listen(argv.port, (err) => {
if (err) {
throw new Error(err);
}
/* eslint-disable no-console */
console.log('Listening on port: ' + argv.port + '.');
/* eslint-enable no-console */
}); Does not work. The complete log output: https://gist.github.com/gajus/843fd2d682f946680af161b7054b01f2 |
whats up with babel.js in there? |
@MrOutput No relevance. Add syntax support for object destructuring. |
@gajus could you put that big log code block into a gist at all? It is making the page very large. |
@gajus please hide you code For now (while we are waiting for Express v5) you can use spdy with express const port = 3000
const spdy = require('spdy')
const express = require('express')
const path = require('path')
const fs = require('fs')
const app = express()
app.get('*', (req, res) => {
res.json({foo: 'test'})
})
let options = {
key: fs.readFileSync(__dirname + '/server.key'),
cert: fs.readFileSync(__dirname + '/server.crt')
};
console.log(options);
spdy
.createServer(options, app)
.listen(port, (err) => {
if (err) {
process.exit(1)
}
console.log('Listening on port: ' + port + '.')
}) |
@azat-co SPDY is dead |
@konradjurk what exactly do you mean by dead? spdy repo is alive. even if there's not much active development, you can use it right now see the official h2 spec where under Node it says http2 and spdy: https://github.com/http2/http2-spec/wiki/Implementations |
@azat-co Google Chrome doesn't support SPDY anymore: http://blog.chromium.org/2016/02/transitioning-from-spdy-to-http2.html So when even its inventor won't support it you know it is dead |
@konradjurk Google SPDY become HTTP/2, if my understanding correct. That's the standards. Now the libraries: |
@konradjurk so basically spdy become http/2 standard and whatever spdy lib had is a viable choice for H2 features... spdy lib is not dead in any case AFAIK 😄 |
OK, this is getting out of hand... too much discussion not related to fixing this bug spamming my inbox. I'll be locking this conversation. However, just to note, spdy is dead. Chrome no longer supports it. I disabled support for it in Firefox 50 (scheduled to release in 12 weeks or so), and removed it entirely in Firefox 51 (6 weeks or so after 50). It is not compatible with h2, even if it was the basis for the spec work, so no, spdy is not a good option for anyone. If I ever get more than a few hours to work on this repo, I might actually try to make this work with Express since it's obviously a pain point for a lot of people, but I don't see any time soon when that would happen. Until that, patches are more than welcome to fix the issue. |
I wrote simple Express app and got an error.
Is that a node-http2's matter or Node's one?
It is hard to debug for me...
Node: v0.12.0
node-http2: v3.2.0
express: v4.11.2
The text was updated successfully, but these errors were encountered: