Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Merge branch 'future'

  • Loading branch information...
commit 511bb04bbb3c11ec11c48917ebd191af0074f335 2 parents d710ba4 + 84d0a20
Ștefan Rusu authored
5 CHANGELOG.md
View
@@ -1,3 +1,8 @@
+## v0.4.1
+ * Passing null as the file argument to http.get turns off saving the response body.
+ * Fixes the HTTP Basic authentication support. [#9](https://github.com/SaltwaterC/http-get/issues/9)
+ * Attaches the HTTP(S) response body to the error argument, if possible, for 203 status codes.
+
## v0.4
* [BREAKS COMPAT] node.js v0.6.11+ support. Drops support for node.js v0.4. [#3](https://github.com/SaltwaterC/http-get/issues/3)
* New option: bufferType for specifying the fact that the library should return the buffers as [Buffer](http://nodejs.org/api/buffer.html) instance instead of String instance.
1  README.md
View
@@ -28,3 +28,4 @@ node.js v0.4 is **NOT** supported due to lack of zlib bindings. Only http-get v0
## Contributor
* [cmtt](https://github.com/cmtt) - options.timeout
+ * [elarcent](https://github.com/elarcent) - HTTP Basic auth fix
2  lib/Buffer.toByteArray.js
View
@@ -1,6 +1,6 @@
/**
* Buffer.toByteArray() - Returns an array of bytes from the Buffer argument
- * @param buffer
+ * @returns {Array}
*/
if ( ! Buffer.prototype.toByteArray) {
Buffer.prototype.toByteArray = function () {
6 lib/Object.watch.js
View
@@ -1,8 +1,8 @@
// Inspired by https://gist.github.com/175649
/**
* Object.watch() - Watches for a property to be assigned a value and runs a function when that occurs.
- * @param prop
- * @param handler
+ * @param {String} prop
+ * @param {Function} handler
*/
if ( ! Object.prototype.watch) {
Object.defineProperty(Object.prototype, 'watch', {
@@ -27,7 +27,7 @@ if ( ! Object.prototype.watch) {
/**
* Object.unwatch() - Removes a watchpoint set with the watch method.
- * @param prop
+ * @param {String} prop
*/
if ( ! Object.prototype.unwatch) {
Object.defineProperty(Object.prototype, 'unwatch', {
57 lib/http-get.js
View
@@ -17,9 +17,10 @@ var semver = require('semver');
/**
* Patches in the http.head() method
- * @param options
- * @param cb
- * @return req
+ *
+ * @param {Object} options
+ * @param {Function} cb
+ * @returns {Object}
*/
http.head = function (options, cb) {
options.method = 'HEAD';
@@ -30,9 +31,10 @@ http.head = function (options, cb) {
/**
* Patches in the https.head() method
- * @param options
- * @param cb
- * @return req
+ *
+ * @param {Object} options
+ * @param {Function} cb
+ * @returns {Object}
*/
https.head = function (options, cb) {
options.method = 'HEAD';
@@ -43,6 +45,7 @@ https.head = function (options, cb) {
/**
* Sets the http.Agent.defaultMaxSockets property
+ *
* @param value
*/
var setMaxSockets = function (value) {
@@ -56,15 +59,16 @@ exports.setMaxSockets = setMaxSockets;
/**
* The http.get() method
- * @param options
- * @param file
- * @param cb
- * @param reqId
+ *
+ * @param {Object} options
+ * @param {String} file
+ * @param {Function} cb
+ * @param {Number} reqId
*/
var get = function (options, file, cb, reqId) {
if (typeof file == 'function') {
cb = file;
- file = null;
+ file = false;
if (options.maxbody) {
options.maxbody = tools.absInt(options.maxbody);
if ( ! options.maxbody) {
@@ -73,8 +77,10 @@ var get = function (options, file, cb, reqId) {
}
}
} else {
- file = String(file).trim();
- file = p.resolve(file);
+ if (file !== null) {
+ file = String(file).trim();
+ file = p.resolve(file);
+ }
}
if ( ! options.url) {
@@ -200,7 +206,7 @@ var get = function (options, file, cb, reqId) {
ws.on('close', function () {
if ( ! aborted) {
var ret = {
- code: 200,
+ code: res.statusCode,
headers: res.headers,
file: file
};
@@ -227,7 +233,7 @@ var get = function (options, file, cb, reqId) {
stream.on('end', function () {
transfer.ended = true;
});
- } else { // buffered response
+ } else if (file === false) { // buffered response
var buf = [];
stream.on('data', function (data) {
@@ -240,7 +246,7 @@ var get = function (options, file, cb, reqId) {
aborted = true;
req.abort();
var err = tools.formattedError('Large body detected.');
- err.code = 200;
+ err.code = res.statusCode;
err.headers = res.headers;
cb(err);
}
@@ -251,7 +257,7 @@ var get = function (options, file, cb, reqId) {
stream.on('end', function () {
if ( ! aborted) {
var ret = {
- code: 200,
+ code: res.statusCode,
headers: res.headers,
buffer: new Buffer(buf)
};
@@ -267,6 +273,15 @@ var get = function (options, file, cb, reqId) {
cb(null, ret);
}
});
+ } else if (file === null) { // discard the response body, equivalent of sending the data to /dev/null
+ var ret = {
+ code: res.statusCode,
+ headers: res.headers
+ };
+ if (reqId > 0) {
+ ret.url = options.url;
+ }
+ cb(null, ret);
}
break;
@@ -309,6 +324,7 @@ var get = function (options, file, cb, reqId) {
cb(null, ret);
break;
+ case 203: // Non-Authoritative Information
case 400: // all the "user" errors
case 401:
case 403:
@@ -412,9 +428,10 @@ exports.get = get;
/**
* The http.head() method
- * @param options
- * @param cb
- * @param reqId
+ *
+ * @param {Object} options
+ * @param {Function} cb
+ * @param {Number} reqId
*/
var head = function (options, cb, reqId) {
if ( ! options.url) {
61 lib/tools.js
View
@@ -14,24 +14,26 @@ var pack = JSON.parse(fs.readFileSync(p.resolve(__dirname + '/../package.json'))
/**
* Makes all the HTTP request headers to be specified as lower case
- * @param hdr
- * @return hdr
+ *
+ * @param {Object} headers
+ * @returns {Object}
*/
-var normalizeHeaders = function (hdr) {
- for (var name in hdr) {
+var normalizeHeaders = function (headers) {
+ for (var name in headers) {
var lowName = name.toLowerCase();
- var val = hdr[name];
- delete(hdr[name]);
- hdr[lowName] = val;
+ var val = headers[name];
+ delete(headers[name]);
+ headers[lowName] = val;
}
- return hdr;
+ return headers;
};
exports.normalizeHeaders = normalizeHeaders;
/**
* Returns the absolute integer value of the input. Avoids the NaN crap.
+ *
* @param value
- * @return value
+ * @returns {Number} value
*/
var absInt = function (value) {
return Math.abs(parseInt(value) | 0);
@@ -40,9 +42,10 @@ var absInt = function (value) {
exports.absInt = absInt;
/**
* Processes the input parameters for get(), head()
- * @param options
- * @param reqId
- * @return object
+ *
+ * @param {Object} options
+ * @param {Number} reqId
+ * @returns {Object}
*/
var processInput = function (options, reqId) {
reqId = absInt(reqId);
@@ -117,9 +120,7 @@ var processInput = function (options, reqId) {
if (url.protocol == 'https:') {
client = https;
}
- if (url.auth) {
- opt.headers.authorization = new Buffer(url.auth).toString('base64');
- }
+ opt.auth = url.auth;
} else {
opt.host = options.proxy.host;
opt.port = options.proxy.port;
@@ -141,9 +142,10 @@ exports.processInput = processInput;
/**
* Prepares the redirect target
- * @param url
- * @param location
- * @return string
+ *
+ * @param {String} url
+ * @param {String} location
+ * @returns {String}
*/
var prepareRedirectUrl = function (url, location) {
var original = u.parse(url);
@@ -163,8 +165,9 @@ exports.prepareRedirectUrl = prepareRedirectUrl;
/**
* Wrapper for formatting the message of an Error object
- * @param message
- * @return object
+ *
+ * @param {String} message
+ * @returns {Object}
*/
var formattedError = function () {
return new Error(util.format.apply(this, arguments));
@@ -173,11 +176,12 @@ exports.formattedError = formattedError;
/**
* Download progress callback
- * @param progress
- * @param data
- * @param currLen
- * @param totalLen
- * @return number
+ *
+ * @param {Function} progress
+ * @param {Buffer} data
+ * @param {Number} currLen
+ * @param {Number} totalLen
+ * @returns {Number} currLen
*/
var doProgress = function (progress, data, currLen, totalLen) {
if (progress && data && data.length) {
@@ -191,9 +195,10 @@ exports.doProgress = doProgress;
/**
* Ends a file transfer
- * @param fd
- * @param lastModified
- * @param writeStream
+ *
+ * @param {Number} fd
+ * @param {String} lastModified
+ * @param {Object} writeStream
*/
var endFileTransfer = function (fd, lastModified, writeStream) {
var atime = new Date();
6 package.json
View
@@ -1,6 +1,6 @@
{
"name": "http-get",
- "version": "0.4.0",
+ "version": "0.4.1",
"main": "./lib/http-get.js",
"description": "Simple to use node.js HTTP / HTTPS client for downloading remote files. Supports transparent gzip / deflate decoding.",
"dependencies": {
@@ -18,6 +18,10 @@
{
"name": "cmtt",
"url": "https://github.com/cmtt"
+ },
+ {
+ "name": "elarcent",
+ "url": "https://github.com/elarcent"
}
],
"repository": {
54 tests/includes/common.js
View
@@ -27,6 +27,14 @@ options.url404 = u.format({
pathname: '/404'
});
+options.urlAuth = u.format({
+ protocol: 'http:',
+ hostname: options.host,
+ port: options.port,
+ pathname: '/auth',
+ auth: 'user:pass'
+});
+
options.urlNoPrefix = options.host + ':' + options.port + '/';
options.secureUrl = u.format({
@@ -42,9 +50,11 @@ var createFooServer = function (secure, cb) {
var srvCb = function (req, res) {
var gzip = false;
var deflate = false;
+
if (req.headers.foo) {
res.setHeader('foo', req.headers.foo);
}
+
if (req.headers['accept-encoding']) {
var accept = req.headers['accept-encoding'].split(',');
if (accept.indexOf('gzip') != -1) {
@@ -58,6 +68,7 @@ var createFooServer = function (secure, cb) {
switch (req.url) {
case '/404':
res.writeHead(404, {'content-type': 'text/plain'});
+
if ( ! gzip && ! deflate) {
res.write('Not Found');
res.end();
@@ -72,6 +83,7 @@ var createFooServer = function (secure, cb) {
res.end();
});
}
+
if (deflate) {
zlib.deflate('Not Found', function (err, compressed) {
if ( ! err) {
@@ -86,6 +98,48 @@ var createFooServer = function (secure, cb) {
return;
break;
+ case '/auth':
+ res.writeHead(200, {'content-type': 'application/json'});
+
+ // a pretti basic HTTP Basic Auth parser :)
+ var authorization = req.headers['authorization'] || '';
+ var token = authorization.split(/\s+/).pop() || '';
+ var auth = new Buffer(token, 'base64').toString();
+ auth = auth.split(/:/);
+
+ var response = JSON.stringify({
+ username: auth[0],
+ password: auth[1]
+ });
+
+ if ( ! gzip && ! deflate) {
+ res.write(response);
+ res.end();
+ } else {
+ if (gzip) {
+ zlib.gzip(response, function (err, compressed) {
+ if ( ! err) {
+ res.write(compressed);
+ } else {
+ res.writeHead(500, {'content-type': 'text/plain'});
+ }
+ res.end();
+ });
+ }
+
+ if (deflate) {
+ zlib.deflate(response, function (err, compressed) {
+ if ( ! err) {
+ res.write(compressed);
+ } else {
+ res.writeHead(500, {'content-type': 'text/plain'});
+ }
+ res.end();
+ });
+ }
+ }
+ break;
+
default:
res.writeHead(200, {'content-type': 'text/plain'});
break;
31 tests/request-auth.js
View
@@ -0,0 +1,31 @@
+var hg = require('../');
+
+var u = require('url');
+var http = require('http');
+var assert = require('assert');
+
+var common = require('./includes/common.js');
+
+var callback = false;
+
+var server = common.createFooServer(false, function () {
+ hg.get({url: common.options.urlAuth}, function (err, res) {
+ callback = true;
+
+ assert.ifError(err);
+ assert.deepEqual(200, res.code);
+ var auth = JSON.parse(res.buffer);
+
+ var url = u.parse(common.options.urlAuth);
+ var urlAuth = url.auth.split(/:/);
+
+ assert.deepEqual(auth.username, urlAuth[0]);
+ assert.deepEqual(auth.password, urlAuth[1])
+
+ server.close();
+ });
+});
+
+process.on('exit', function () {
+ assert.ok(callback);
+});
20 tests/response-file-null.js
View
@@ -0,0 +1,20 @@
+var http = require('../');
+
+var assert = require('assert');
+var common = require('./includes/common.js');
+
+var callback = false;
+
+var server = common.createFooServer(false, function () {
+ http.get({url: common.options.url}, null, function (err, res) {
+ callback = true;
+ assert.ifError(err);
+ assert.deepEqual(200, res.code);
+ assert.ok(res.headers);
+ server.close();
+ });
+});
+
+process.on('exit', function () {
+ assert.ok(callback);
+});
Please sign in to comment.
Something went wrong with that request. Please try again.