pax_global_header00006660000000000000000000000064124351726260014522gustar00rootroot0000000000000052 comment=ac60cad509a124e36ea55f6a3c3720a17d82a7bc node-get-1.4.0/000077500000000000000000000000001243517262600132265ustar00rootroot00000000000000node-get-1.4.0/.npmignore000066400000000000000000000000371243517262600152250ustar00rootroot00000000000000test/ test_data/ node_modules/ node-get-1.4.0/.travis.yml000066400000000000000000000000601243517262600153330ustar00rootroot00000000000000language: node_js node_js: - "0.8" - "0.10" node-get-1.4.0/CHANGELOG.md000066400000000000000000000035721243517262600150460ustar00rootroot00000000000000## Changelog ### 1.4.0 * Enforce content-length header if set in response ### 1.3.0 * node v0.10 compatibility ### 1.2.0 * Make HTTP agent configurable. ### 1.1.10 * Re-tagging due to a problem with 1.1.9 being previously tagged ### 1.1.9 * More fixes to proxy support ### 1.1.8 * Fix proxy support when not using auth ### 1.1.7 * Automatic base64 encoding of proxy.auth into headers['proxy-authorization'] * Now properly sets headers on requests * Moved tests to mocha ### 1.1.6 * Now returns 504 errors * Only uses setTimeout if timeout value is > 0 ### 1.1.5 * Added max_length setting (assumes bytes) that cancels the download if the file is growing too big ### 1.1.4 * Retain node v0.4.x compatibility. ### 1.1.3 * Now using 10 second timeout - tests using mocha ### 1.1.2 * Better error handling around invalid URLs ### 1.1.1 * Node 0.6.3 compatibility without warnings ### 1.1.0 * Returns Get instance as last parameter of `toDisk`, which assists with filetype-guessing ### 1.0.0 * Switched from deprecated `createClient()` API to new `http.request` API from node. * Stronger support for HTTPS * No longer supports node versions below 0.3.6 ### 0.4.0 * Added `asBuffer()` method * Streamlined `asDisk` to use node's native `.pipe()` function * Added `encoding` option to constructor ### 0.4.0 * `.asBuffer()` added * `get()` can now be used without `new` ### 0.3.0 * `get` now supports HTTP SOCKS proxies by setting `HTTP_PROXY` in `ENV` ### 0.2.0 * `node-get` is now `get`. ### 0.1.1 * [laplatrem](https://github.com/leplatrem): Fixed HTTPS support ### 0.1.0 * `max_redirs`, `headers` options in node-get constructor * The API changes in 0.1.x - Get should never be expected to throw an exception. * Handling of invalid URLs on redirect. * Handling of file-level errors. ### 0.0.3 * Handling of DNS-level exceptions. ### 0.0.2 * Enhanced URL validation. node-get-1.4.0/LICENSE000066400000000000000000000027141243517262600142370ustar00rootroot00000000000000Copyright (c), Development Seed All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: - Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. - Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. - Neither the name "Development Seed" nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. node-get-1.4.0/Makefile000066400000000000000000000002661243517262600146720ustar00rootroot00000000000000# # Run all tests # test: @mocha -R spec lint: ./node_modules/.bin/jshint lib/node-get/*.js doc: ./node_modules/.bin/docco lib/node-get/*.js bin/node-get-file.js .PHONY: test node-get-1.4.0/README.md000066400000000000000000000045001243517262600145040ustar00rootroot00000000000000# get [![Build Status](https://secure.travis-ci.org/mapbox/node-get.png?branch=master)](http://travis-ci.org/mapbox/node-get) `get` is a slightly higher-level HTTP client for nodejs. ## Installation npm install get get has no dependencies. For testing, you'll need make and [mocha](https://github.com/visionmedia/mocha). For docs you'll need [docco](https://github.com/jashkenas/docco). ## Features * Redirect following. * Convenience functions for downloading and getting data as string. * Binary-extension and basic binary detection. * Configurable headers ## API Downloads are objects in `get`. ```javascript var dl = new get({ uri: 'http://google.com/' }); ``` However, the function is [a self-calling constructor](http://ejohn.org/blog/simple-class-instantiation/), and thus the `new` keyword is not necessary: ```javascript var dl = get({ uri: 'http://google.com/' }); ``` The get constructor can also take a plain string if you don't want to give options. ```javascript var dl = get('http://google.com/'); ``` It can also take other options. ```javascript var dl = get({ uri: 'http://google.com/', max_redirs: 20, }); ``` Then it exposes three main methods ```javascript dl.asString(function(err, str) { console.log(str); }); ``` and ```javascript dl.toDisk('myfile.txt', function(err, filename) { console.log(err); }); ``` and finally ```javascript dl.asBuffer(function(err, data) { console.log(data); }); ``` There's also a lower-level API. ```javascript dl.perform(function(err, response) { // response is just a response object, just like // HTTP request, except handling redirects }); ``` If you give node-get an object of settings instead of a string, it accepts * `uri` - the address of the resource * `headers` - to replace its default headers with custom ones * `max_redirs` - the number of redirects to follow before returning an error * `no_proxy` - don't use a HTTP proxy, even if one is in `ENV` * `encoding` - When calling `.guessEncoding()`, `get` will use this instead of the default value ## Example ``` var get = require('get'); get('http://google.com/').asString(function(err, data) { if (err) throw err; console.log(data); }); ``` ## TODO: * Guessing encoding wth headers * User-customizable encodings ## Authors * Tom MacWright (tmcw) * Konstantin Kaefer (kkaefer) node-get-1.4.0/bin/000077500000000000000000000000001243517262600137765ustar00rootroot00000000000000node-get-1.4.0/bin/node-get-file.js000077500000000000000000000025131243517262600167570ustar00rootroot00000000000000#!/usr/bin/env node var path = require('path'), url = require('url'), util = require('util'), get = require('../lib/node-get/index.js'); var usage = 'usage:\n' + '\ndownload to a file:' + '\n\tnode-get-file.js ' + '\n\nget contents of file:' + '\n\tnode-get-file.js -' // Guessing destination filenames wget-style has never been // very robust, so require users to specify them. var obj = process.argv[2]; var dest = process.argv[3]; if (!(obj && dest)) { console.log(usage); process.exit(1); } // Initialize the download. try { var download = new get({ uri: obj }); } catch(e) { util.debug(e); process.exit(1); } if (dest == '-') { // Download to disk. download.asString(function(err, str) { // Print both errors and debugging messages // to stderr so that eventual piping is succesfull if (err) { util.debug(err); } else { console.log(str); } }); } else { // Download to disk. download.toDisk(dest, function(err, filename) { // Print both errors and debugging messages // to stderr so that eventual piping is succesfull if (err) { util.debug(err); } else { util.debug('Downloaded to ' + filename); } }); } node-get-1.4.0/lib/000077500000000000000000000000001243517262600137745ustar00rootroot00000000000000node-get-1.4.0/lib/encodings.js000066400000000000000000000005651243517262600163110ustar00rootroot00000000000000// Preset encodings for file formats. module.exports = { 'ext': { '.tif': 'binary', '.tiff': 'binary', '.geotiff': 'binary', '.zip': 'binary', '.sqlite': 'binary', '.png': 'binary', '.gif': 'binary', '.jpg': 'binary', '.mp3': 'binary', '.ico': 'binary', '.jpeg': 'binary' } }; node-get-1.4.0/lib/index.js000066400000000000000000000275341243517262600154540ustar00rootroot00000000000000// node.js libraries var http = require('http'), https = require('https'), util = require('util'), fs = require('fs'), events = require('events'), Buffer = require('buffer').Buffer, url = require('url'), path = require('path'); // Local node-get libraries var encodings = require('./encodings'); var default_headers = { 'Accept-Encoding': 'none', 'Connection': 'close', 'User-Agent': 'curl' }; // Get a Get object. Takes an argument, that is either // a plain string representing the URI, or an object: // // { // uri: "string of uri", // required // headers: {} // optional, default in source // max_redirs: 5 // optional, default 10 // no_proxy: true // prevent automatic proxy usage when HTTP_PROXY is set. // } function Get(options) { // Allow calling without new keyword. if (!(this instanceof Get)) { return new Get(options); } if (typeof options == 'string') { this.uri = options; this.headers = default_headers; if (process.env.HTTP_PROXY) { this.proxy = url.parse(process.env.HTTP_PROXY); this.headers.Host = url.parse(this.uri).host; if (this.proxy.auth) { this.headers['proxy-authorization'] = 'Basic ' + new Buffer(this.proxy.auth).toString('base64'); } } else { this.proxy = {}; } } else { if (!options.uri) { throw Error('uri option required in get constructor'); } this.uri = options.uri; this.max_redirs = options.max_redirs || 10; this.max_length = options.max_length || 0; this.encoding = options.encoding; this.headers = options.headers || default_headers; this.timeout = 'timeout' in options ? options.timeout : 10000; if (!this.no_proxy && process.env.HTTP_PROXY) { this.proxy = url.parse(process.env.HTTP_PROXY); this.headers.Host = url.parse(this.uri).host; if (this.proxy.auth) { this.headers['proxy-authorization'] = 'Basic ' + new Buffer(this.proxy.auth).toString('base64'); } } else { this.proxy = {}; } this.agent = options.agent || undefined; } } util.inherits(Get, events.EventEmitter); // Create a HTTP request. Just sanity-checks URLs and // chooses an HTTP or HTTPS request. // // - @return {http.ClientRequest} Get.prototype.request = function(callback) { // TODO: handle non http/https protocols this.uri_o = url.parse(this.uri); // Validate the URI at this step so that invalid // redirects are also caught. if (!(this.uri_o.protocol && (this.uri_o.protocol == 'http:' || this.uri_o.protocol == 'https:') && this.uri_o.hostname)) { return callback.call(this, null, new Error('Invalid URL: ' + url.format(this.uri))); } // TODO: should pronode-getxies support HTTPS? if (this.uri_o.protocol == 'https:') { return https.request({ agent: this.agent, host: this.uri_o.hostname, port: 443, headers: this.headers, path: this.proxy.hostname ? this.uri : ((this.uri_o.pathname || '') + (this.uri_o.search || '') + (this.uri_o.hash || '')) || '/' }, callback); } else { return http.request({ agent: this.agent, port: this.proxy.port || this.uri_o.port || 80, host: this.proxy.hostname || this.uri_o.hostname, headers: this.headers, path: this.proxy.hostname ? this.uri : ((this.uri_o.pathname || '') + (this.uri_o.search || '') + (this.uri_o.hash || '')) || '/' }, callback); } }; // Innermost API function of Get // // - @param {Function} callback // - @param {Number} times number of times re-called. Get.prototype.perform = function(callback, times) { if (times > this.max_redirs) { return callback(new Error('Redirect limit of ' + this.max_redirs + ' reached')); } times = times || 1; var clientrequest = this.request(function handleClientRequest(response, err) { if (err) return callback.call(this, err, null); response.resume(); if (response.statusCode >= 300 && response.statusCode < 400 && response.headers.location) { // Redirection // ----------- // Servers can send a full redirect location // or a short form, like a hyperlink. Handle both. if (url.parse(response.headers.location).protocol) { this.uri = response.headers.location; } else { this.uri = url.resolve(this.uri, response.headers.location); } this.perform(callback, times + 1); return; } else if (response.statusCode >= 400) { // failure var err = new Error('Server returned HTTP ' + response.statusCode); err.status = response.statusCode; return callback.call(this, err, response); } else { // success return callback.call(this, null, response); } }.bind(this)); // The client can fail if the url is invalid if (clientrequest) { // Ensure the callback is only called once in error cases. // Timeouts can trigger both error and timeout callbacks. var error = 0; // Handle DNS-level errors, like ECONNREFUSED clientrequest.on('error', function(err) { if (++error > 1) return; return callback.call(this, err); }.bind(this)); // Enforce a timeout of 10 seconds. // Add a no-op version of setTimeout for node <= 0.4.x. if (this.timeout > 0) { clientrequest.setTimeout = clientrequest.setTimeout || function() {}; clientrequest.setTimeout(this.timeout, function() { clientrequest.connection.end(); if (++error > 1) return; var err = new Error('Timed out after ' + this.timeout + 'ms'); err.status = 504; // HTTP status code for "Gateway Timeout". return callback.call(this, err); }.bind(this)); } // TODO: fix when/if gzip is supported. // If a proxy is defined, ask for the full requested URL, // otherwise construct the URL without a hostname and protocol. clientrequest.end(); } }; Get.prototype.guessResponseExtension = function(response) { if (response.headers['content-disposition']) { var match = response.headers['content-disposition'].match(/filename=\"([^"]+)\"/); if (match) { var ext = path.extname(match[1]); if (ext) { return ext; } } } return false; }; // Stream a file to disk // --------------------- // - @param {String} filename. // - @param {Function} callback. Get.prototype.toDisk = function(filename, callback) { // TODO: catch all errors this.perform(function(err, response) { if (err) return callback(err); // Don't set an encoding. Using an encoding messes up binary files. // Pump contents from the response stream into a new writestream. var file = fs.createWriteStream(filename); file.on('error', callback); file.on('close', function() { return callback(null, filename, response, this); }.bind(this)); response.pipe(file); }); }; // Get the contents of a URL as a string // // - @param {Function} callback. Get.prototype.asString = function(callback) { var max_length = this.max_length; var payload = 0; function error(err) { if (!callback) return; callback(err); callback = null; } // TODO: catch all errors this.perform(function pipeResponseToString(err, response) { if (err) return callback(err); var mime = (response.headers['content-type'] || '').toLowerCase(); if (mime !== 'application/json') switch (mime.split('/')[0]) { case 'binary': case 'application': case 'image': case 'video': return callback(new Error("Can't download binary file as string")); default: // TODO: respect Content-Transfer-Encoding header response.setEncoding(this.guessEncoding(this.uri)); } function returnString() { if (!callback) return; var err = checkContentLength(response.headers, payload); if (err) return error(err); callback(null, out.join(''), response.headers); callback = null; } // Fill an array with chunks of data, // and then join it into a string before calling `callback` var out = []; response.on('data', function(chunk) { if (!callback) return; payload += chunk.length; var err = checkMaxLength(max_length, payload); if (err) { response.socket.end(); error(err); } else { out.push(chunk); } }); response.on('error', error); response.on('end', returnString); response.on('close', returnString); }); }; // Get the contents of a URL as a buffer // // - @param {Function} callback. Get.prototype.asBuffer = function(callback) { var max_length = this.max_length; var payload = 0; function error(err) { if (!callback) return; callback(err); callback = null; } this.perform(function(err, response) { if (err) return error(err); function returnBuffer() { if (!callback) return; var err = checkContentLength(response.headers, payload); if (err) return error(err); for (var length = 0, i = 0; i < out.length; i++) { length += out[i].length; } var result = new Buffer(length); for (var pos = 0, j = 0; j < out.length; j++) { out[j].copy(result, pos); pos += out[j].length; } callback(null, result, response.headers); callback = null; } // Fill an array with chunks of data, // and then join it into a buffer before calling `callback` var out = []; response.on('data', function(chunk) { if (!callback) return; payload += chunk.length; var err = checkMaxLength(max_length, payload); if (err) { response.socket.end(); error(err); } else { out.push(chunk); } }); response.on('error', error); response.on('end', returnBuffer); response.on('close', returnBuffer); }); }; Get.prototype.guessEncoding = function(location) { // The 'most reliable' measure is probably the end of files, so // start off with extname. if (this.encoding) return this.encoding; var ext = path.extname(location).toLowerCase(); if (encodings.ext[ext]) return encodings.ext[ext]; }; function checkMaxLength(max, length) { if (!max) return; if (length <= max) return; return new Error('File exceeds maximum allowed length of ' + max + ' bytes'); } function checkContentLength(headers, length) { if (!headers['content-length']) return; var contentLength = parseInt(headers['content-length'], 10); if (isNaN(contentLength)) return; if (length === contentLength) return; return new Error('Body ('+length+' bytes) does not match content-length (' + contentLength + ' bytes)'); } module.exports = Get; module.exports.checkMaxLength = checkMaxLength; module.exports.checkContentLength = checkContentLength; node-get-1.4.0/package.json000066400000000000000000000014141243517262600155140ustar00rootroot00000000000000{ "name": "get", "description": "A slightly higher-level HTTP client for node.", "version": "1.4.0", "main": "./lib/index.js", "keywords": ["http", "client", "request", "get"], "url": "https://github.com/mapbox/node-get", "repository": { "type": "git", "url": "git://github.com/mapbox/node-get.git" }, "author": "Tom MacWright ", "contributors": [ "Konstantin Käfer " ], "licenses": [{ "type": "BSD" }], "devDependencies": { "mocha": ">= 0.11", "jshint": "0.2.x", "underscore": "1.2.x", "docco": "0.3.x" }, "engines": { "node": ">= 0.3.6" }, "scripts": { "test": "mocha -R spec" } } node-get-1.4.0/test/000077500000000000000000000000001243517262600142055ustar00rootroot00000000000000node-get-1.4.0/test/basic.test.js000066400000000000000000000145651243517262600166150ustar00rootroot00000000000000var path = require('path'); var assert = require('assert'); var crypto = require('crypto'); var exec = require('child_process').exec; var fs = require('fs'); var get = require('..'); function md5(obj) { if (!Array.isArray(obj)) obj = [ obj ]; var hash = crypto.createHash('md5'); obj.forEach(hash.update.bind(hash)); return hash.digest('hex'); } var files = [ { url: 'https://docs.google.com/a/dbsgeo.com/spreadsheet/pub?hl=en_US&hl=en_US&key=0AqV4OJpywingdFNYLXpKMmxqMG1lWTJzNE45ZUVnNlE&single=true&gid=0&output=csv', bin: false, redirects: 1, md5: 'a4d019d2bfedc55e84447f833ed71dff' }, { url: 'http://tilemill-data.s3.amazonaws.com/images/paperfolds_256.png', bin: true, md5: 'a99502016d4e2124cf2dc4775aafc256' }, { url: 'http://tilemill-data.s3.amazonaws.com/test_data/ipsum.json', bin: true, md5: '651ea0ff31786e9be9012112b21573be' }, { url: 'http://tilemill-data.s3.amazonaws.com/test_data/README.txt', bin: false, md5: '46d883d71e795d7c8a65c9b1a6673dd2' }, { url: 'http://tilemill-data.s3.amazonaws.com/test_data/shape_demo.zip', bin: true, md5: 'b5ff3545922cc9e0c750fb7263a7a3d3' }, { url: 'http://tilemill-data.s3.amazonaws.com/nasa_raster/lasvegas_tm5_12jan09_crop_geo_merc_small.tif', bin: true, md5: '3b97134839042fcab0d0ee8ea76f73c4' }, { url: 'http://dcatlas.dcgis.dc.gov/catalog/download.asp?downloadID=2315&downloadTYPE=ESRI', bin: true, md5: 'eebdc65e86129f92ebbcb2c6845204ef' } ]; // Ensure that we start over with a clean test_data directory. before(function(done) { exec('rm -rf ./test_data && mkdir ./test_data', done); }); describe('get().perform', function() { files.forEach(function(reference) { it('should return request object for ' + reference.url, function(done) { this.timeout(0); new get({ uri: reference.url, headers: { 'User-Agent': 'tombot' } }).perform(function(err, result) { var body = []; if (reference.error) { assert.ok(err); assert.eql(err.message, reference.error); done(); } else if (err) { done(err); } else { result.on('error', done); result.on('data', function(chunk) { body.push(chunk); }); result.on('close', function(err) { assert.equal(md5(body), reference.md5); done(); }); result.on('end', function() { assert.equal(md5(body), reference.md5); done(); }); } }); }); }); }); describe('get().toDisk', function() { files.forEach(function(reference) { it('should save to disk for ' + reference.url, function(done) { this.timeout(0); new get({ uri: reference.url, headers: { 'User-Agent': 'tombot' } }).toDisk('test_data/file_' + reference.md5, function(err, result) { if (reference.error) { assert.ok(err); assert.equal(err.message, reference.error); done(); } else if (err) { done(err); } else { assert.equal(md5(fs.readFileSync(result)), reference.md5); done(); } }); }); }); }); describe('get().asString', function() { files.forEach(function(reference) { it('should return as string for ' + reference.url, function(done) { this.timeout(0); new get({ uri: reference.url, headers: { 'User-Agent': 'tombot' } }).asString(function(err, result) { if (reference.bin && err) { assert.equal(err.message, "Can't download binary file as string"); done(); } else if (reference.bin) { done(new Error('Should not return binary files as string')); } else if (reference.error) { assert.equal(err.message, reference.error); done(); } else if (err) { done(err); } else { assert.equal(md5(result), reference.md5); done(); } }); }); }); }); describe('get().asBuffer', function() { files.forEach(function(reference) { it('should return as buffer for ' + reference.url, function(done) { this.timeout(0); new get({ uri: reference.url, headers: { 'User-Agent': 'tombot' } }).asBuffer(function(err, result) { if (reference.error) { assert.equal(err.message, reference.error); done(); } else if (err) { done(err); } else { assert.equal(md5(result), reference.md5); done(); } }); }); }); }); describe('max_length', function() { it('should abort .asBuffer() if the max_length is exceeded', function(done) { this.timeout(0); new get({ uri: 'http://tilemill-data.s3.amazonaws.com/images/paperfolds_256.png', headers: { 'User-Agent': 'tombot' }, max_length: 10000 }).asBuffer(function(err) { assert.ok(err); assert.equal(err.message, 'File exceeds maximum allowed length of 10000 bytes'); done(); }); }); it('should abort .asString() if the max_length is exceeded', function(done) { this.timeout(0); new get({ uri: 'http://tilemill-data.s3.amazonaws.com/test_data/README.txt', headers: { 'User-Agent': 'tombot' }, max_length: 10 }).asString(function(err) { assert.ok(err); assert.equal(err.message, 'File exceeds maximum allowed length of 10 bytes'); done(); }); }); }); node-get-1.4.0/test/error.test.js000066400000000000000000000046351243517262600166620ustar00rootroot00000000000000var assert = require('assert'); var http = require('http'); var get = require('..'); var serverTimeout; var serverBadLength; var portBadLength = 50000 + (Math.random() * 10000 | 0); var portTimeout = 50000 + (Math.random() * 10000 | 0); before(function(done) { serverTimeout = http.createServer(function(req, res) { // Do not respond to requests. }); serverTimeout.listen(portTimeout, done); }); before(function(done) { var connections = []; serverBadLength = http.createServer(function(req, res) { res.writeHead(200, {'content-length':'20'}); res.write(new Buffer(10)); connections.forEach(function(c) { c.destroy(); }); }); serverBadLength.on('connection', function(c) { connections.push(c); }); serverBadLength.listen(portBadLength, done); }); describe('error handling', function() { it('should return an error for an invalid URL', function(done) { new get({ uri: 'http://\\/', headers: { 'User-Agent': 'tombot' } }).toDisk('test_data/file_tmp', function(err, result) { assert.ok(/Invalid URL: http/.test(err.message)); done(); }); }); var methods = ['asString', 'asBuffer']; methods.forEach(function(method) { it(method + ': should error on bad content length', function(done) { new get({ uri: 'http://localhost:' + portBadLength, headers: { 'User-Agent': 'tombot' } })[method](function(err, result) { assert.equal(err.toString(), 'Error: Body (10 bytes) does not match content-length (20 bytes)'); done(); }); }); // Request timeout feature only exists on node v0.6.x. // Test that this can pass before running the test. if (!http.ClientRequest.prototype.setTimeout) return; it(method + ': should report a timeout error', function(done) { new get({ uri: 'http://localhost:' + portTimeout, headers: { 'User-Agent': 'tombot' }, timeout: 500 })[method](function(err, result) { assert.ok(err); assert.equal(err.status, 504); assert.equal(err.message, 'Timed out after 500ms'); done(); }); }); }); }); after(function() { serverTimeout.close(); serverBadLength.close(); }); node-get-1.4.0/test/headers.test.js000066400000000000000000000035201243517262600171340ustar00rootroot00000000000000var assert = require('assert'); var http = require('http'); var get = require('..'); var server; var port = 50000 + (Math.random() * 10000 | 0); before(function(done) { server = http.createServer(function(req, res) { res.writeHead(200, {'Content-Type': 'text/plain'}); res.end(JSON.stringify(req.headers)); }); server.listen(port, done); }); describe('headers', function() { it('should use default headers', function(done) { new get({ uri: 'http://localhost:' + port }).asString(function(err, result) { assert.ifError(err); var headers = JSON.parse(result); [ ['accept-encoding', 'none'], ['connection', 'close'], ['user-agent', 'curl'] ].forEach(function(v) { assert.equal(headers[v[0]], v[1]); }); done(); }); }); it('should override "connection: keep-alive"', function(done) { new get({ uri: 'http://localhost:' + port, headers: { 'Connection': 'keep-alive' } }).asString(function(err, result) { assert.ifError(err); var headers = JSON.parse(result); assert.equal(headers.connection, 'keep-alive'); done(); }); }); it('should set correct headers for proxied requests', function(done) { var HTTP_PROXY = process.env.HTTP_PROXY; process.env.HTTP_PROXY = 'http://user:pass@example.com:88'; var headers = new get({ uri: 'http://localhost:' + port }).headers; assert.equal(headers.Host, 'localhost:' + port); assert.equal(headers['proxy-authorization'], 'Basic dXNlcjpwYXNz'); process.env.HTTP_PROXY = HTTP_PROXY; done(); }); }); after(function() { server.close(); }); node-get-1.4.0/test/unit.test.js000066400000000000000000000017271243517262600165070ustar00rootroot00000000000000var assert = require('assert'); var Get = require('../lib/index.js'); it('checkMaxLength', function() { assert.equal(Get.checkMaxLength(null, 10), undefined); assert.equal(Get.checkMaxLength(1000, 10), undefined); assert.equal(Get.checkMaxLength(10, 10), undefined); assert.deepEqual(Get.checkMaxLength(10, 11).toString(), 'Error: File exceeds maximum allowed length of 10 bytes'); }); it('checkContentLength', function() { assert.equal(Get.checkContentLength({}, 10), undefined); assert.equal(Get.checkContentLength({'content-length':'foo'}, 10), undefined); assert.equal(Get.checkContentLength({'content-length':10}, 10), undefined); assert.equal(Get.checkContentLength({'content-length':'10'}, 10), undefined); assert.equal(Get.checkContentLength({'content-length':'10.0'}, 10), undefined); assert.equal(Get.checkContentLength({'content-length':'10'}, 9).toString(), 'Error: Body (9 bytes) does not match content-length (10 bytes)'); });