summaryrefslogtreecommitdiffhomepage
path: root/src
diff options
context:
space:
mode:
authorAlexander Borisov <alexander.borisov@nginx.com>2018-12-19 15:55:58 +0300
committerAlexander Borisov <alexander.borisov@nginx.com>2018-12-19 15:55:58 +0300
commit13c9ebccca9c7bee80f4b9c1da4c128435d9dac1 (patch)
treee2a8784b187233f03e4c19bb1b61b1f1ee90cf37 /src
parentde3c062c6e3e869d726b93a1ffe617059df7611a (diff)
downloadunit-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-xsrc/nodejs/unit-http/http_server.js40
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);