You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
164 lines
3.6 KiB
164 lines
3.6 KiB
/**
|
|
* @fileoverview Http request in node.js
|
|
* @author douzi <liaowei08@gmail.com>
|
|
*/
|
|
var http = require('http');
|
|
var util = require('utils-extend');
|
|
var url = require('url');
|
|
var path = require('path');
|
|
var querystring = require('querystring');
|
|
var file = require('file-system');
|
|
|
|
/**
|
|
* @description
|
|
* http request
|
|
* @param {object|string} [options]
|
|
* @param {function} [callback]
|
|
* @example
|
|
* request('url', function(err, res, body) { });
|
|
* request({url: '', headers: {}, method: 'POST'}, function(err, res, body) { });
|
|
*/
|
|
function request(options, callback) {
|
|
var opts = {
|
|
headers: {
|
|
'Content-Type': 'application/json'
|
|
},
|
|
method: 'GET',
|
|
encoding: 'utf8',
|
|
// If the callback body is buffer, it can hanlder document pipe simply
|
|
isBuffer: false,
|
|
json: false
|
|
};
|
|
|
|
if (util.isString(options)) {
|
|
opts.url = options;
|
|
} else {
|
|
util.extend(opts, options);
|
|
}
|
|
|
|
// Append request data
|
|
if (opts.data) {
|
|
if (opts.method === 'GET') {
|
|
opts.url += '?' + querystring.stringify(opts.data);
|
|
} else {
|
|
opts.data = JSON.stringify(opts.data);
|
|
opts.headers['Content-Length'] = new Buffer(opts.data).length;
|
|
}
|
|
}
|
|
|
|
// Extend request url object
|
|
util.extend(opts, util.pick(url.parse(opts.url), 'hostname', 'port', 'path', 'auth'));
|
|
delete opts.url;
|
|
|
|
var req = http.request(opts, function(res) {
|
|
var body = [];
|
|
var size = 0;
|
|
|
|
res.on('data', function(chunk) {
|
|
body.push(chunk);
|
|
size += chunk.length;
|
|
});
|
|
|
|
res.on('end', function() {
|
|
var result = '';
|
|
|
|
// Buffer
|
|
if (opts.isBuffer) {
|
|
result = Buffer.concat(body, size);
|
|
} else {
|
|
var buffer = new Buffer(size);
|
|
for (var i = 0, pos = 0, l = body.length; i < l; i++) {
|
|
var chunk = body[i];
|
|
chunk.copy(buffer, pos);
|
|
pos += chunk.length;
|
|
}
|
|
result = buffer.toString(opts.encoding);
|
|
|
|
if (opts.json) {
|
|
result = JSON.parse(result);
|
|
}
|
|
}
|
|
|
|
callback(null, res, result);
|
|
});
|
|
});
|
|
|
|
req.on('error', callback);
|
|
|
|
if (opts.method !== 'GET' && opts.data) {
|
|
req.write(opts.data);
|
|
}
|
|
|
|
req.end();
|
|
}
|
|
|
|
/**
|
|
* @description
|
|
* @example
|
|
* request.post('url', function() {});
|
|
* request.post({ url: 'url', data: { q1: 'v1' }}, function() {});
|
|
*/
|
|
request.post = function(options, callback) {
|
|
if (util.isString(options)) {
|
|
options = {
|
|
url: options
|
|
};
|
|
}
|
|
|
|
options.method = 'POST';
|
|
request(options, callback);
|
|
};
|
|
|
|
/**
|
|
* @description
|
|
* Download remote resurce to local file
|
|
* @example
|
|
* request.download({ url: 'path.png' }, function(err, res, body, filepath) {})
|
|
* request.download({
|
|
url: 'path.png',
|
|
rootPath: 'dest/path'
|
|
}, function(err, res, body, filepath) {
|
|
|
|
});
|
|
*/
|
|
request.download = function(options, callback) {
|
|
var opts = util.extend({
|
|
rootPath: '',
|
|
ignore: false
|
|
}, options);
|
|
|
|
request({
|
|
url: opts.url,
|
|
isBuffer: true
|
|
}, function(err, res, body) {
|
|
if (err) return callback(err);
|
|
if (res.statusCode !== 200) return callback(err, res, body);
|
|
var destPath;
|
|
var pathname = url.parse(options.url).pathname.replace(/^\//, '');
|
|
|
|
if (opts.destPath) {
|
|
if (util.isFunction(opts.destPath)) {
|
|
destPath = opts.destPath(path.basename(pathname));
|
|
} else {
|
|
destPath = opts.destPath;
|
|
}
|
|
} else {
|
|
destPath = path.join(
|
|
options.rootPath,
|
|
pathname
|
|
);
|
|
}
|
|
|
|
if (opts.ignore) {
|
|
destPath = destPath.toLowerCase();
|
|
}
|
|
|
|
file.writeFile(destPath, body, function(err) {
|
|
if (err) return callback(err);
|
|
|
|
callback(null, res, body, destPath);
|
|
});
|
|
});
|
|
};
|
|
|
|
module.exports = request;
|
|
|