joyent/node — pull request #5100 by vshlos (2013-03-21 04:03:51+00:00)
Title: fix error causing socket to not return to the http agent until timeout occurs.

# The Problem
I have found an issue where if there is an exception thrown in the handler of a http response, then this connection will not be returned to the pool until it times out a few minutes later. This causes the pool to backup and can lead to a denial of service attack or other issues in which node will not be able to talk to a host for a given amount of time.

Here is a simple proof of concept:
```javascript
var http = require("http")

function test() {
var options = {
host: "google.com",
port: 80,
path: "/"
}

console.log("started")
var req = http.request(options, function (res) {
console.log("response")

res.on("end", function () {
throw new Error("HELLO")

})
})
req.end()

}

process.on("uncaughtException", function () {
console.log("uncaught");
})

for (var i = 0; i < 10; i++)
test();
```

This code sample will display "started" 10 times and "response" 5 times (maxSockets is 5) then hang for a couple of minutes until those sockets timeout, then show "response" 5 more times.

This exception can be thrown on the response callback or in any of the emit events and will cause a similar issue.

This is especially noticeable when you are running a test framework like mocha and on the response you check the JSON object with an assert which throws an exception and causes the rest of the tests that talk to the same endpoint to fail or timeout.

For example if you have the following type of code
```javascript
test.makeRequest(function (result) {
assert(result.firstName != "")
})
```
After 5 of these tests fail, the rest will fail with a timeout even though the test might otherwise pass.

# The Fix
There is now a try-catch wrapper around the emit handling code in http.js which overrides the emit event and ensures that responseEnd is always called. If there is an exception on getting the response or in the "data" event, then it will kill the socket and return it to the pool.

There is now 1 added test to test this exact problem in pummel/test-http-agent-exception.js