diff options
author | Alexander Borisov <alexander.borisov@nginx.com> | 2018-12-19 15:55:58 +0300 |
---|---|---|
committer | Alexander Borisov <alexander.borisov@nginx.com> | 2018-12-19 15:55:58 +0300 |
commit | 13c9ebccca9c7bee80f4b9c1da4c128435d9dac1 (patch) | |
tree | e2a8784b187233f03e4c19bb1b61b1f1ee90cf37 /src | |
parent | de3c062c6e3e869d726b93a1ffe617059df7611a (diff) | |
download | unit-13c9ebccca9c7bee80f4b9c1da4c128435d9dac1.tar.gz unit-13c9ebccca9c7bee80f4b9c1da4c128435d9dac1.tar.bz2 |
Node.js: changed the 'data' event calling sequence for the request.
The problem is caused by Promises' inconsistency.
The 'date' event could have been triggered before the user has started
listening for it. To resolve the issue, we override the 'on' method of
the request's emitter.
Diffstat (limited to '')
-rwxr-xr-x | src/nodejs/unit-http/http_server.js | 40 |
1 files changed, 30 insertions, 10 deletions
diff --git a/src/nodejs/unit-http/http_server.js b/src/nodejs/unit-http/http_server.js index 47851c98..9b7b8403 100755 --- a/src/nodejs/unit-http/http_server.js +++ b/src/nodejs/unit-http/http_server.js @@ -288,6 +288,28 @@ ServerRequest.prototype.resume = function resume() { return []; }; +/* + * The "on" method is overridden to defer reading data until user code is + * ready, that is (ev === "data"). This can occur after req.emit("end") is + * executed, since the user code can be scheduled asynchronously by Promises + * and so on. Passing the data is postponed by process.nextTick() until + * the "on" method caller completes. + */ +ServerRequest.prototype.on = function on(ev, fn) { + Server.prototype.on.call(this, ev, fn); + + if (ev === "data") { + process.nextTick(function () { + if (this.server.buffer.length !== 0) { + this.emit("data", this.server.buffer); + } + + }.bind(this)); + } +}; + +ServerRequest.prototype.addListener = ServerRequest.prototype.on; + function Server(requestListener) { EventEmitter.call(this); @@ -321,22 +343,20 @@ Server.prototype.listen = function () { }; Server.prototype.run_events = function (server, req, res) { + req.server = server; + res.server = server; + req.res = res; + res.req = req; + + server.buffer = server.unit._read(req.socket.req_pointer); + /* Important!!! setImmediate starts the next iteration in Node.js loop. */ setImmediate(function () { server.emit("request", req, res); Promise.resolve().then(() => { - let buf = server.unit._read(req.socket.req_pointer); - - if (buf.length != 0) { - req.emit("data", buf); - } - - req.emit("end"); - }); - - Promise.resolve().then(() => { req.emit("finish"); + req.emit("end"); if (res.finished) { unit_lib.unit_response_end(res); |