-
Notifications
You must be signed in to change notification settings - Fork 59
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
Add support for Node 10.12.x. #58
Conversation
- following https://github.com/nodejs/node/blob/master/src/node_http_parser.cc, the core HTTP parser now validates the arguments given to the constructor. This used to by a string but is now a number (0,1, 2)
Update version number, as the Node.js compatibility has been updated.
Add nodejs 8 and 10 to Travis.
Added Node.js 8 and 10 to Travis, but found Node.js 10 to contain failing unit tests. |
I'm confused by this change. Those values have been numbers in previous Node versions too (they are back to at least v6 I checked randomly), but they should be opaque to the Node Javascript code, they're only ever passed to "new HTTPParser()", which is our code. Am I missing something? |
- Two failures remain that might be due to incompatible nodejs changes
@Jimbly that took me some thing to figure out as well. |
It looks to me like it's calling parser.reinitialize(HTTPParser.RESPONSE, which isn't a number, that's the string we were previously exporting? Where's the call with a number? |
Sorry for the messy explanation, you're right. The unit test changes now fail 6 and 8, so more work there i guess. |
Our .REQUEST and .RESPONSE values should never get passed to node_http_parser.cc, that's the module we're replacing. If so, something else is going wrong (maybe related to process binding stuff?). |
I did notice when I ran the tests on v10 myself that a few of the tests were getting into the native Node parser, which probably shouldn't be happening (otherwise the test is testing the wrong parser, although maybe those particular tests always were), but I didn't investigate what was causing that. |
Process.binding is deprecated in node.js 10, so the implementation might have changed a bit? Hmm, they now use internalBinding to retrieve the http_parser, which used to be different with process.binding? See https://github.com/nodejs/node/blob/eb9748d222061381236f19cbe162cf9eb2e034ad/lib/_http_client.js#L27. |
It looks like process.binding still works, and "http_parser" is "whitelisted for access via process.binding()", so I don't think that's an immediate problem, but probably will be in the future. It's possible some node bootstrapping order has changed so we're not getting our monkey patch in before _http_common.js pulls out HTTPParser, or something like that though, if some internal module is requiring _http_common before user code starts running... but in general it seems like our monkey patch is working, just not on a couple tests. |
Ok i think i understand. I'll close this pr and when i think i have the solution to the issue, open a new PR. |
Okay, cool, thanks for diving into this! |
I dug a little deeper today, and i think i at least found in what situations the monkey patch isn't applied correctly. The test "test-http-server-stale-close.js" ends up throwing native code error in "Reinitialize":
This only seems to happen when
Now the million dollar question; what changed in At BlueConic, we are using http-parser-js in child processes (started with I will try to dig a little deeper into the difference in |
What stands out is that Node.js child_process in Not sure yet why spawn mitigates the issue. |
I should have some time today to poke into this, I'll see if I can find a cause. Nothing is obvious from skimming the code, but it shouldn't be too hard to add some logging to the Node internals and see what's happening. I'm a little worried that: if the first line of user code in our module is overriding the process binding, and that's not good enough, there might be nothing that can be done, short of requesting some upstream changes to Node.js - and supporting modules that override Node.js internals is very much something they don't want to be concerned with, but if it's a generalized fix, not just exposing something for us, then maybe they'd take it ^_^. |
Well, I'm not sure I'm closer to a solution or not, but I've tracked down a lot of details. The specific minor version where this started to fail was between v10.0.0 and v10.1.0, and, as you suspected, that's where the additional require() from internal/child_process of http_parser and _http_common happen (most importantly the latter, since then _http_common caches a HTTPParser constructor pre-monkeypatch). I've been doing my testing on the v10.1.0 code, as it just gives a JS-level error instead of a process crash, which makes things much easier to debug. The actual include path/stack for how _http_common is getting loaded at startup is:
The reason this only happened for you with fork() and not spawn() is that Object.setupChannel() is only called if the child process has an IPC with the parent. Calling spawn() with The problem that causes crashes is that then, later, _http_client/server get loaded, after our monkey-patching, so they're using our HTTParser.* values and passing them on into a non-monkey-patched native parser object. I can't think of any obvious solution to this, either in our code or a general-purpose patch to Node. We might need to do the monkey-patching differently, assuming callers already have an instance of the native HTTPParser constructor, but I do not know of any way to change a function/ctor's code retroactively (seems that it might not be possible), however we can modify it's prototype, so we could maybe allow the default/native constructor to be called and just override all of the functions with some lazy construction... but that's bound to be messy and we never get access to the original parameters to the constructor, so I'm not particularly hopeful that would work... I'm out of time for the day, just wanted to share what I've found so far. Also, maybe we should "re-open" this, not to necessarily merge the code, but to keep our conversation in an open issue. |
Thanks for your investigation. I'll think about some more as well. |
I've done some more thinking and posted an issue in the Node.js repo, will hopefully get some direction or advice from them. I think it might not be too bad to fix Node to allow this to work for now, but probably nothing guaranteed future-safe... but this module breaks on roughly every-other major Node version, so that's nothing new ;) |
This issue will be fixed with a new Node.js release: nodejs/node#24006. |
This reverts commit 9707b7c.
Now Node.js 10.15.1 is released (in which #24006 is fixed), i'll work to make this branch run on Node.js 10 again. |
This reverts commit a3a1cfddb7a181203b24c5129ad04f4781726948.
This reverts commit d15a5c961dd50754efe6d8d1343dd898320d5190. # Conflicts: # tests/parallel/test-http-request-end-twice.js # tests/parallel/test-http-unix-socket.js
* Updated pom and CHANGELOG.md
@Jimbly I've reverted all of the changes in http-parser.js, but still some unit tests failed.
It looks like Node.js 10 still does some things different. |
Update tests to work on Node v10.x. Resolves #58
Following https://github.com/nodejs/node/blob/master/src/node_http_parser.cc, the core HTTP parser now validates the arguments given to the constructor. This used to by a string but is now a number (0,1, 2).
This is a short term solution that adds support for Node.js 10.x, but in the long term the following might prove problematic: