Skip to content

Instantly share code, notes, and snippets.

@ishiduca
Created October 3, 2011 10:05
Show Gist options
  • Save ishiduca/1258811 to your computer and use it in GitHub Desktop.
Save ishiduca/1258811 to your computer and use it in GitHub Desktop.
チェーンメソッドを使う HTTPClient #Node.js
var http = require('http'),
url = require('url');
var _version = '0.001'; // 2011.10.03
function HTTPClient (config) {
config = config || {};
var storage = {};
this['redirect'] = config['redirect'] || false; // redirect: not ok
this['cookie'] = config['cookie'] || undefined;
this['referer'] = config['referer'] || undefined;
this['queue'] = [];
this.set = function (key, value) {
storage[key] = value;
return this;
};
this.get = function (key) {
return storage[key];
};
}
(function () {
var $client = HTTPClient.prototype;
$client['VERSION'] = _version;
$client['guard'] = undefined;
function _start () {
if (this.queue && this.queue.length > 0) {
var aRequest = this.queue.shift(),
method, uriStr, callback, headers, body,
options, uri, path,
req,
that
;
if (typeof aRequest[0] === 'function') aRequest = (aRequest[0])();
method = aRequest.shift();
uriStr = aRequest.shift();
callback = aRequest.pop();
headers = aRequest.shift() || {};
body = aRequest.shift() || null;
// resolve URI
method = method.toUpperCase();
uri = url.parse(uriStr);
path = (! uri['pathname']) ? '/' :
( uri['pathname'].slice(0, 1) === '/') ? uri['pathname'] :
[ "/", uri['pathname'] ].join('');
if (uri['search']) path += uri['search'];
if (method === 'POST') {
headers['content-length'] = (body) ? body.length : 0;
headers['content-type'] = headers['content-type'] || 'application/x-www-form-urlencoded';
}
if (! headers['referer'] && this['referer']) headers['referer'] = this['referer'];
if (! headers['cookie'] && this['cookie']) headers['cookie'] = this['cookie'];
options = {
"method" : method,
"host" : uri['hostname'],
"port" : (uri['port']) ? uri['port'] :
(uri['protocol'] === 'https') ? '443' : '80',
"path" : path,
"headers" : headers
};
// serv request
req = http.request(options);
if (body) req.write(body);
req.end();
// recieve response
that = this;
req.on('error', function (e) { throw e; });
req.on('response', function (res) {
var statusCode = res.statusCode,
resHeaders = res.headers;
if (resHeaders['set-cookie']) that['cookie'] = resHeaders['set-cookie'][0];
that['referer'] = uriStr;
if (that['redirect'] && statusCode >= 300 && statusCode < 400 && resHeaders['location']) {
that.queue.unshift([
'GET',
resHeaders['location'],
{ referer : that['referer'], cookie : that['cookie'] },
function (_res, _req) { that.release(); }
]);
}
callback(res, [ uriStr, headers, body ]);
});
} else {
if (typeof this['guard'] === 'function') this['guard']();
}
}
$client .request = function () {
var args = Array.prototype.slice.apply(arguments);
this.queue.push(args); // args = [ method, uriStr, headers, body, callback ] || [ Function ];
return this;
};
$client .end = function (callback) {
if (callback) this['guard'] = callback;
_start.apply(this);
};
$client .release = function (callback) {
if (callback && typeof callback === 'function') callback();
_start.apply(this);
};
$client .clear = $client.release;
}) ();
exports.HTTPClient = HTTPClient;
1;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment