Skip to content

Commit

Permalink
http: overridable clientError
Browse files Browse the repository at this point in the history
Make default `clientError` behavior (close socket immediately)
overridable. With this APIs it is possible to write a custom error
handler, and to send, for example, a 400 HTTP response.

    http.createServer(...).on('clientError', function(err, socket) {
      socket.end('HTTP/1.1 400 Bad Request\r\n\r\n');
      socket.destroy();
    });

Fix: nodejs#4543
  • Loading branch information
indutny committed Jan 6, 2016
1 parent 0f65247 commit 9fc35f4
Show file tree
Hide file tree
Showing 5 changed files with 10 additions and 13 deletions.
4 changes: 4 additions & 0 deletions doc/api/http.markdown
Original file line number Diff line number Diff line change
Expand Up @@ -421,6 +421,10 @@ not be emitted.
`function (exception, socket) { }`

If a client connection emits an `'error'` event, it will be forwarded here.
Listener of this event is responsible for destroying socket, and, for example,
can do it it gracefully by sending 400 HTTP response.

Default behavior is destroy socket immediately.

`socket` is the [`net.Socket`][] object that the error originated from.

Expand Down
7 changes: 2 additions & 5 deletions lib/_http_server.js
Original file line number Diff line number Diff line change
Expand Up @@ -237,10 +237,6 @@ function Server(requestListener) {

this.addListener('connection', connectionListener);

this.addListener('clientError', function(err, conn) {
conn.destroy(err);
});

this.timeout = 2 * 60 * 1000;

this._pendingResponseData = 0;
Expand Down Expand Up @@ -353,7 +349,8 @@ function connectionListener(socket) {

// TODO(isaacs): Move all these functions out of here
function socketOnError(e) {
self.emit('clientError', e, this);
if (!self.emit('clientError', e, this))
this.destroy(e);
}

function socketOnData(d) {
Expand Down
5 changes: 3 additions & 2 deletions lib/https.js
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,9 @@ function Server(opts, requestListener) {
this.addListener('request', requestListener);
}

this.addListener('clientError', function(err, conn) {
conn.destroy();
this.addListener('tlsClientError', function(err, conn) {
if (!this.emit('clientError', err, conn))
conn.destroy();
});

this.timeout = 2 * 60 * 1000;
Expand Down
6 changes: 0 additions & 6 deletions test/parallel/test-http-client-abort.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,12 +21,6 @@ var server = http.Server(function(req, res) {
server.close();
}
});

// since there is already clientError, maybe that would be appropriate,
// since "error" is magical
req.on('clientError', function() {
console.log('Got clientError');
});
});

var responses = 0;
Expand Down
1 change: 1 addition & 0 deletions test/parallel/test-https-timeout-server.js
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ server.on('clientError', function(err, conn) {
assert.equal(conn._secureEstablished, false);
server.close();
clientErrors++;
conn.destroy();
});

server.listen(common.PORT, function() {
Expand Down

0 comments on commit 9fc35f4

Please sign in to comment.