Skip to content

Instantly share code, notes, and snippets.

@nanha
Forked from ishiduca/gist:2280639
Created July 17, 2012 11:54
Show Gist options
  • Save nanha/3129007 to your computer and use it in GitHub Desktop.
Save nanha/3129007 to your computer and use it in GitHub Desktop.
node.js http.agent の agent.maxSockets の上限を避ける その2
var events,http, url, path;
events = require('events');
http = require('http');
url = require('url');
path = require('path');
var agents = {};
agent.onSocketsLengthChange;
if (http.getAgent) {
agents.onSocketsLengthChange = function (agent) {
var helper;
while (agent.sockets.length < agent.maxSockets && agent.waitRequests.length > 0) {
helper = agent.waitRequests.shift();
helper();
}
agent.sockets.forEach(function (socket, i) {
if (! socket.hasOnCloseListener) {
socket.hasOnCloseListener = 1;
socket.once('close', function (had_error) {
if (had_error) {
console.log('sockets[' + i + '/' + agent.sockets.length + '] is closing by error');
}
agents.onSocketsLengthChange(agent);
});
console.log('set agent.sockets[' + i + '] "hasOnCloseListener"');
}
});
};
}
function httpRequest (/* getURL, method, options, onResponse */) {
var that, agentid, helper,
args, getURL, uri, uriPath, method, options, headers, body, requestOptions;
that = this;
args = Array.prototype.slice.apply(arguments);
getURL = args.shift();
onResponse = args.pop();
method = args.shift() || 'GET';
method = method.toUpperCase();
options = args.shift() || {};
if (options.body) {
body = options.body || null;
delete options.body;
}
headers = options;
uri = url.parse(getURL());
uriPath = (! uri.pathname) ? '/'
: (uri.pathname.slice(0, 1) === '/') ? uri.pathname
: '/' + uri.pathname;
if (uri.search) uriPath += uri.search;
if (method === 'POST') {
headers['content-type'] = headers['content-type'] || 'application/x-www-form-urlencoded';
headers['content-length'] = (body) ? Buffer.byteLength(body) : 0;
}
if (! headers.referer && this.referer) headers.referer = this.referer;
if (! headers.cookie && this.cookie) headers.cookie = this.cookie;
requestOptions = {
method : method,
host : uri.host,
port : (uri.port) ? uri.port : (uri.protocol === 'https') ? '443' : '80',
path : uriPath,
headers : headers
};
helper = function () {
var req;
req = http.request(requestOptions);
req.on('error', function (error) {
console.log(error);
process.exit(1);
});
req.on('response', function (response) {
var statusCode, responseHeaders, _onResponse;
statusCode = response.statusCode;
responseHeaders = response.headers;
if (responseHeaders['set-cookie']) that.cookie = responseHeaders['set-cookie'][0];
that.referer = uri.href;
if (that.redirect && statusCode >= 300 && statusCode < 400 && responseHeaders.location) {
_onResponse = onResponse;
httpRequest(
function () { return responseHeaders.location; }, 'GET',
{ referer : that.referer, cookie : that.cookie },
function (response, request) {
_onResponse(response, request);
}
)
return;
}
onResponse(response, [ uri.href, headers, body ]);
});
if (body) req.write(body);
req.end();
};
if (agents.onSocketsLengthChange) {
agentid = [ requestOptions.host, requestOptions.port ].join(':');
if (! agents[agentid]) {
agents[agentid] = http.getAgent(requestOptions.host, requestOptions.port);
agents[agentid].waitRequests = [];
agents[agentid].maxSockets = 2;
}
agents[agentid].waitRequests.push(helper);
agents.onSocketsLengthChange(agents[agentid]);
return;
}
helper();
}
exports.httpRequest = httpRequest;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment