Skip to content

Commit 2eb96aa

Browse files
authored
Merge pull request #290 from minrk/writable-ended
2 parents 6792ceb + 2706a23 commit 2eb96aa

File tree

1 file changed

+21
-11
lines changed

1 file changed

+21
-11
lines changed

lib/configproxy.js

+21-11
Original file line numberDiff line numberDiff line change
@@ -36,13 +36,15 @@ function argumentsArray(args) {
3636
function fail(req, res, code, msg) {
3737
// log a failure, and finish the HTTP request with an error code
3838
msg = msg || "";
39+
res._logMsg = msg;
40+
41+
if (res.writableEnded) return; // response already done
3942
if (res.writeHead) res.writeHead(code);
4043
if (res.write) {
4144
if (!msg) {
4245
msg = http.STATUS_CODES[code];
4346
}
4447
res.write(msg);
45-
res._logMsg = msg;
4648
}
4749
if (res.end) res.end();
4850
}
@@ -410,6 +412,7 @@ class ConfigurableProxy extends EventEmitter {
410412
_handleProxyErrorDefault(code, kind, req, res) {
411413
// called when no custom error handler is registered,
412414
// or is registered and doesn't work
415+
if (res.writableEnded) return; // response already done
413416
if (!res.headersSent && res.writeHead) res.writeHead(code);
414417
if (res.write) res.write(http.STATUS_CODES[code]);
415418
if (res.end) res.end();
@@ -425,15 +428,20 @@ class ConfigurableProxy extends EventEmitter {
425428
this.statsd.increment("requests." + code, 1);
426429
if (e) {
427430
// avoid stack traces on known not-our-problem errors:
428-
// ECONNREFUSED (backend isn't there)
429-
// ECONNRESET (backend is there, but didn't respond)
430-
if (e.code === "ECONNRESET" || e.code === "ECONNREFUSED") {
431-
errMsg = e.message;
432-
} else {
433-
// logging the error object shows a stack trace.
434-
// Anything that gets here is an unknown error,
435-
// so log more info.
436-
errMsg = e;
431+
// ECONNREFUSED, EHOSTUNREACH (backend isn't there)
432+
// ECONNRESET, ETIMEDOUT (backend is there, but didn't respond)
433+
switch (e.code) {
434+
case "ECONNREFUSED":
435+
case "ECONNRESET":
436+
case "EHOSTUNREACH":
437+
case "ETIMEDOUT":
438+
errMsg = e.message;
439+
break;
440+
default:
441+
// logging the error object shows a stack trace.
442+
// Anything that gets here is an unknown error,
443+
// so log more info.
444+
errMsg = e;
437445
}
438446
}
439447
this.log.error("%s %s %s %s", code, req.method, req.url, errMsg);
@@ -463,13 +471,14 @@ class ConfigurableProxy extends EventEmitter {
463471
}
464472

465473
var errorRequest = (secure ? https : http).request(target, function (upstream) {
474+
if (res.writableEnded) return; // response already done
466475
["content-type", "content-encoding"].map(function (key) {
467476
if (!upstream.headers[key]) return;
468477
if (res.setHeader) res.setHeader(key, upstream.headers[key]);
469478
});
470479
if (res.writeHead) res.writeHead(code);
471480
upstream.on("data", (data) => {
472-
if (res.write) res.write(data);
481+
if (res.write && !res.writableEnded) res.write(data);
473482
});
474483
upstream.on("end", () => {
475484
if (res.end) res.end();
@@ -498,6 +507,7 @@ class ConfigurableProxy extends EventEmitter {
498507
this._handleProxyErrorDefault(code, kind, req, res);
499508
return;
500509
}
510+
if (res.writableEnded) return; // response already done
501511
if (res.writeHead) res.writeHead(code, { "Content-Type": "text/html" });
502512
if (res.write) res.write(data);
503513
if (res.end) res.end();

0 commit comments

Comments
 (0)