Created
August 8, 2016 20:52
-
-
Save dsklopp/cfd9d69ecd0c255e736c23151d186de9 to your computer and use it in GitHub Desktop.
New Relic POC Browserify Doesn't Work
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
(function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(require,module,exports){ | |
/** | |
* Feel free to explore, or check out the full documentation | |
* https://docs.newrelic.com/docs/synthetics/new-relic-synthetics/scripting-monitors/writing-api-tests | |
* for details. | |
*/ | |
var dns = require("native-dns"); | |
var util = require("util"); | |
function resultant(response) { | |
console.log(response.answer + " : " + response.time); | |
} | |
function dns_query(name, server, callback) { | |
transport = 'udp'; | |
timeout = 1000; | |
var question = dns.Question({ | |
name: name, | |
type: 'A' | |
}); | |
var req = dns.Request({ | |
question: question, | |
server: { address: server, port: 53, type: transport }, | |
timeout: timeout | |
}); | |
var start; | |
req.on('message', function (err, answer) { | |
answer.answer.forEach(function (a) { | |
var response = { | |
time: Date.now() - start, | |
answer: a.address | |
}; | |
callback(response); | |
}); | |
}); | |
start = Date.now(); | |
req.send(); | |
} | |
dns_query('www.google.com', '8.8.8.8', resultant); | |
},{"native-dns":16,"util":15}],2:[function(require,module,exports){ | |
},{}],3:[function(require,module,exports){ | |
// http://wiki.commonjs.org/wiki/Unit_Testing/1.0 | |
// | |
// THIS IS NOT TESTED NOR LIKELY TO WORK OUTSIDE V8! | |
// | |
// Originally from narwhal.js (http://narwhaljs.org) | |
// Copyright (c) 2009 Thomas Robinson <280north.com> | |
// | |
// Permission is hereby granted, free of charge, to any person obtaining a copy | |
// of this software and associated documentation files (the 'Software'), to | |
// deal in the Software without restriction, including without limitation the | |
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or | |
// sell copies of the Software, and to permit persons to whom the Software is | |
// furnished to do so, subject to the following conditions: | |
// | |
// The above copyright notice and this permission notice shall be included in | |
// all copies or substantial portions of the Software. | |
// | |
// THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | |
// AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN | |
// ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION | |
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | |
// when used in node, this will actually load the util module we depend on | |
// versus loading the builtin util module as happens otherwise | |
// this is a bug in node module loading as far as I am concerned | |
var util = require('util/'); | |
var pSlice = Array.prototype.slice; | |
var hasOwn = Object.prototype.hasOwnProperty; | |
// 1. The assert module provides functions that throw | |
// AssertionError's when particular conditions are not met. The | |
// assert module must conform to the following interface. | |
var assert = module.exports = ok; | |
// 2. The AssertionError is defined in assert. | |
// new assert.AssertionError({ message: message, | |
// actual: actual, | |
// expected: expected }) | |
assert.AssertionError = function AssertionError(options) { | |
this.name = 'AssertionError'; | |
this.actual = options.actual; | |
this.expected = options.expected; | |
this.operator = options.operator; | |
if (options.message) { | |
this.message = options.message; | |
this.generatedMessage = false; | |
} else { | |
this.message = getMessage(this); | |
this.generatedMessage = true; | |
} | |
var stackStartFunction = options.stackStartFunction || fail; | |
if (Error.captureStackTrace) { | |
Error.captureStackTrace(this, stackStartFunction); | |
} | |
else { | |
// non v8 browsers so we can have a stacktrace | |
var err = new Error(); | |
if (err.stack) { | |
var out = err.stack; | |
// try to strip useless frames | |
var fn_name = stackStartFunction.name; | |
var idx = out.indexOf('\n' + fn_name); | |
if (idx >= 0) { | |
// once we have located the function frame | |
// we need to strip out everything before it (and its line) | |
var next_line = out.indexOf('\n', idx + 1); | |
out = out.substring(next_line + 1); | |
} | |
this.stack = out; | |
} | |
} | |
}; | |
// assert.AssertionError instanceof Error | |
util.inherits(assert.AssertionError, Error); | |
function replacer(key, value) { | |
if (util.isUndefined(value)) { | |
return '' + value; | |
} | |
if (util.isNumber(value) && !isFinite(value)) { | |
return value.toString(); | |
} | |
if (util.isFunction(value) || util.isRegExp(value)) { | |
return value.toString(); | |
} | |
return value; | |
} | |
function truncate(s, n) { | |
if (util.isString(s)) { | |
return s.length < n ? s : s.slice(0, n); | |
} else { | |
return s; | |
} | |
} | |
function getMessage(self) { | |
return truncate(JSON.stringify(self.actual, replacer), 128) + ' ' + | |
self.operator + ' ' + | |
truncate(JSON.stringify(self.expected, replacer), 128); | |
} | |
// At present only the three keys mentioned above are used and | |
// understood by the spec. Implementations or sub modules can pass | |
// other keys to the AssertionError's constructor - they will be | |
// ignored. | |
// 3. All of the following functions must throw an AssertionError | |
// when a corresponding condition is not met, with a message that | |
// may be undefined if not provided. All assertion methods provide | |
// both the actual and expected values to the assertion error for | |
// display purposes. | |
function fail(actual, expected, message, operator, stackStartFunction) { | |
throw new assert.AssertionError({ | |
message: message, | |
actual: actual, | |
expected: expected, | |
operator: operator, | |
stackStartFunction: stackStartFunction | |
}); | |
} | |
// EXTENSION! allows for well behaved errors defined elsewhere. | |
assert.fail = fail; | |
// 4. Pure assertion tests whether a value is truthy, as determined | |
// by !!guard. | |
// assert.ok(guard, message_opt); | |
// This statement is equivalent to assert.equal(true, !!guard, | |
// message_opt);. To test strictly for the value true, use | |
// assert.strictEqual(true, guard, message_opt);. | |
function ok(value, message) { | |
if (!value) fail(value, true, message, '==', assert.ok); | |
} | |
assert.ok = ok; | |
// 5. The equality assertion tests shallow, coercive equality with | |
// ==. | |
// assert.equal(actual, expected, message_opt); | |
assert.equal = function equal(actual, expected, message) { | |
if (actual != expected) fail(actual, expected, message, '==', assert.equal); | |
}; | |
// 6. The non-equality assertion tests for whether two objects are not equal | |
// with != assert.notEqual(actual, expected, message_opt); | |
assert.notEqual = function notEqual(actual, expected, message) { | |
if (actual == expected) { | |
fail(actual, expected, message, '!=', assert.notEqual); | |
} | |
}; | |
// 7. The equivalence assertion tests a deep equality relation. | |
// assert.deepEqual(actual, expected, message_opt); | |
assert.deepEqual = function deepEqual(actual, expected, message) { | |
if (!_deepEqual(actual, expected)) { | |
fail(actual, expected, message, 'deepEqual', assert.deepEqual); | |
} | |
}; | |
function _deepEqual(actual, expected) { | |
// 7.1. All identical values are equivalent, as determined by ===. | |
if (actual === expected) { | |
return true; | |
} else if (util.isBuffer(actual) && util.isBuffer(expected)) { | |
if (actual.length != expected.length) return false; | |
for (var i = 0; i < actual.length; i++) { | |
if (actual[i] !== expected[i]) return false; | |
} | |
return true; | |
// 7.2. If the expected value is a Date object, the actual value is | |
// equivalent if it is also a Date object that refers to the same time. | |
} else if (util.isDate(actual) && util.isDate(expected)) { | |
return actual.getTime() === expected.getTime(); | |
// 7.3 If the expected value is a RegExp object, the actual value is | |
// equivalent if it is also a RegExp object with the same source and | |
// properties (`global`, `multiline`, `lastIndex`, `ignoreCase`). | |
} else if (util.isRegExp(actual) && util.isRegExp(expected)) { | |
return actual.source === expected.source && | |
actual.global === expected.global && | |
actual.multiline === expected.multiline && | |
actual.lastIndex === expected.lastIndex && | |
actual.ignoreCase === expected.ignoreCase; | |
// 7.4. Other pairs that do not both pass typeof value == 'object', | |
// equivalence is determined by ==. | |
} else if (!util.isObject(actual) && !util.isObject(expected)) { | |
return actual == expected; | |
// 7.5 For all other Object pairs, including Array objects, equivalence is | |
// determined by having the same number of owned properties (as verified | |
// with Object.prototype.hasOwnProperty.call), the same set of keys | |
// (although not necessarily the same order), equivalent values for every | |
// corresponding key, and an identical 'prototype' property. Note: this | |
// accounts for both named and indexed properties on Arrays. | |
} else { | |
return objEquiv(actual, expected); | |
} | |
} | |
function isArguments(object) { | |
return Object.prototype.toString.call(object) == '[object Arguments]'; | |
} | |
function objEquiv(a, b) { | |
if (util.isNullOrUndefined(a) || util.isNullOrUndefined(b)) | |
return false; | |
// an identical 'prototype' property. | |
if (a.prototype !== b.prototype) return false; | |
// if one is a primitive, the other must be same | |
if (util.isPrimitive(a) || util.isPrimitive(b)) { | |
return a === b; | |
} | |
var aIsArgs = isArguments(a), | |
bIsArgs = isArguments(b); | |
if ((aIsArgs && !bIsArgs) || (!aIsArgs && bIsArgs)) | |
return false; | |
if (aIsArgs) { | |
a = pSlice.call(a); | |
b = pSlice.call(b); | |
return _deepEqual(a, b); | |
} | |
var ka = objectKeys(a), | |
kb = objectKeys(b), | |
key, i; | |
// having the same number of owned properties (keys incorporates | |
// hasOwnProperty) | |
if (ka.length != kb.length) | |
return false; | |
//the same set of keys (although not necessarily the same order), | |
ka.sort(); | |
kb.sort(); | |
//~~~cheap key test | |
for (i = ka.length - 1; i >= 0; i--) { | |
if (ka[i] != kb[i]) | |
return false; | |
} | |
//equivalent values for every corresponding key, and | |
//~~~possibly expensive deep test | |
for (i = ka.length - 1; i >= 0; i--) { | |
key = ka[i]; | |
if (!_deepEqual(a[key], b[key])) return false; | |
} | |
return true; | |
} | |
// 8. The non-equivalence assertion tests for any deep inequality. | |
// assert.notDeepEqual(actual, expected, message_opt); | |
assert.notDeepEqual = function notDeepEqual(actual, expected, message) { | |
if (_deepEqual(actual, expected)) { | |
fail(actual, expected, message, 'notDeepEqual', assert.notDeepEqual); | |
} | |
}; | |
// 9. The strict equality assertion tests strict equality, as determined by ===. | |
// assert.strictEqual(actual, expected, message_opt); | |
assert.strictEqual = function strictEqual(actual, expected, message) { | |
if (actual !== expected) { | |
fail(actual, expected, message, '===', assert.strictEqual); | |
} | |
}; | |
// 10. The strict non-equality assertion tests for strict inequality, as | |
// determined by !==. assert.notStrictEqual(actual, expected, message_opt); | |
assert.notStrictEqual = function notStrictEqual(actual, expected, message) { | |
if (actual === expected) { | |
fail(actual, expected, message, '!==', assert.notStrictEqual); | |
} | |
}; | |
function expectedException(actual, expected) { | |
if (!actual || !expected) { | |
return false; | |
} | |
if (Object.prototype.toString.call(expected) == '[object RegExp]') { | |
return expected.test(actual); | |
} else if (actual instanceof expected) { | |
return true; | |
} else if (expected.call({}, actual) === true) { | |
return true; | |
} | |
return false; | |
} | |
function _throws(shouldThrow, block, expected, message) { | |
var actual; | |
if (util.isString(expected)) { | |
message = expected; | |
expected = null; | |
} | |
try { | |
block(); | |
} catch (e) { | |
actual = e; | |
} | |
message = (expected && expected.name ? ' (' + expected.name + ').' : '.') + | |
(message ? ' ' + message : '.'); | |
if (shouldThrow && !actual) { | |
fail(actual, expected, 'Missing expected exception' + message); | |
} | |
if (!shouldThrow && expectedException(actual, expected)) { | |
fail(actual, expected, 'Got unwanted exception' + message); | |
} | |
if ((shouldThrow && actual && expected && | |
!expectedException(actual, expected)) || (!shouldThrow && actual)) { | |
throw actual; | |
} | |
} | |
// 11. Expected to throw an error: | |
// assert.throws(block, Error_opt, message_opt); | |
assert.throws = function(block, /*optional*/error, /*optional*/message) { | |
_throws.apply(this, [true].concat(pSlice.call(arguments))); | |
}; | |
// EXTENSION! This is annoying to write outside this module. | |
assert.doesNotThrow = function(block, /*optional*/message) { | |
_throws.apply(this, [false].concat(pSlice.call(arguments))); | |
}; | |
assert.ifError = function(err) { if (err) {throw err;}}; | |
var objectKeys = Object.keys || function (obj) { | |
var keys = []; | |
for (var key in obj) { | |
if (hasOwn.call(obj, key)) keys.push(key); | |
} | |
return keys; | |
}; | |
},{"util/":15}],4:[function(require,module,exports){ | |
(function (global){ | |
/*! | |
* The buffer module from node.js, for the browser. | |
* | |
* @author Feross Aboukhadijeh <feross@feross.org> <http://feross.org> | |
* @license MIT | |
*/ | |
/* eslint-disable no-proto */ | |
'use strict' | |
var base64 = require('base64-js') | |
var ieee754 = require('ieee754') | |
var isArray = require('isarray') | |
exports.Buffer = Buffer | |
exports.SlowBuffer = SlowBuffer | |
exports.INSPECT_MAX_BYTES = 50 | |
/** | |
* If `Buffer.TYPED_ARRAY_SUPPORT`: | |
* === true Use Uint8Array implementation (fastest) | |
* === false Use Object implementation (most compatible, even IE6) | |
* | |
* Browsers that support typed arrays are IE 10+, Firefox 4+, Chrome 7+, Safari 5.1+, | |
* Opera 11.6+, iOS 4.2+. | |
* | |
* Due to various browser bugs, sometimes the Object implementation will be used even | |
* when the browser supports typed arrays. | |
* | |
* Note: | |
* | |
* - Firefox 4-29 lacks support for adding new properties to `Uint8Array` instances, | |
* See: https://bugzilla.mozilla.org/show_bug.cgi?id=695438. | |
* | |
* - Chrome 9-10 is missing the `TypedArray.prototype.subarray` function. | |
* | |
* - IE10 has a broken `TypedArray.prototype.subarray` function which returns arrays of | |
* incorrect length in some situations. | |
* We detect these buggy browsers and set `Buffer.TYPED_ARRAY_SUPPORT` to `false` so they | |
* get the Object implementation, which is slower but behaves correctly. | |
*/ | |
Buffer.TYPED_ARRAY_SUPPORT = global.TYPED_ARRAY_SUPPORT !== undefined | |
? global.TYPED_ARRAY_SUPPORT | |
: typedArraySupport() | |
/* | |
* Export kMaxLength after typed array support is determined. | |
*/ | |
exports.kMaxLength = kMaxLength() | |
function typedArraySupport () { | |
try { | |
var arr = new Uint8Array(1) | |
arr.__proto__ = {__proto__: Uint8Array.prototype, foo: function () { return 42 }} | |
return arr.foo() === 42 && // typed array instances can be augmented | |
typeof arr.subarray === 'function' && // chrome 9-10 lack `subarray` | |
arr.subarray(1, 1).byteLength === 0 // ie10 has broken `subarray` | |
} catch (e) { | |
return false | |
} | |
} | |
function kMaxLength () { | |
return Buffer.TYPED_ARRAY_SUPPORT | |
? 0x7fffffff | |
: 0x3fffffff | |
} | |
function createBuffer (that, length) { | |
if (kMaxLength() < length) { | |
throw new RangeError('Invalid typed array length') | |
} | |
if (Buffer.TYPED_ARRAY_SUPPORT) { | |
// Return an augmented `Uint8Array` instance, for best performance | |
that = new Uint8Array(length) | |
that.__proto__ = Buffer.prototype | |
} else { | |
// Fallback: Return an object instance of the Buffer class | |
if (that === null) { | |
that = new Buffer(length) | |
} | |
that.length = length | |
} | |
return that | |
} | |
/** | |
* The Buffer constructor returns instances of `Uint8Array` that have their | |
* prototype changed to `Buffer.prototype`. Furthermore, `Buffer` is a subclass of | |
* `Uint8Array`, so the returned instances will have all the node `Buffer` methods | |
* and the `Uint8Array` methods. Square bracket notation works as expected -- it | |
* returns a single octet. | |
* | |
* The `Uint8Array` prototype remains unmodified. | |
*/ | |
function Buffer (arg, encodingOrOffset, length) { | |
if (!Buffer.TYPED_ARRAY_SUPPORT && !(this instanceof Buffer)) { | |
return new Buffer(arg, encodingOrOffset, length) | |
} | |
// Common case. | |
if (typeof arg === 'number') { | |
if (typeof encodingOrOffset === 'string') { | |
throw new Error( | |
'If encoding is specified then the first argument must be a string' | |
) | |
} | |
return allocUnsafe(this, arg) | |
} | |
return from(this, arg, encodingOrOffset, length) | |
} | |
Buffer.poolSize = 8192 // not used by this implementation | |
// TODO: Legacy, not needed anymore. Remove in next major version. | |
Buffer._augment = function (arr) { | |
arr.__proto__ = Buffer.prototype | |
return arr | |
} | |
function from (that, value, encodingOrOffset, length) { | |
if (typeof value === 'number') { | |
throw new TypeError('"value" argument must not be a number') | |
} | |
if (typeof ArrayBuffer !== 'undefined' && value instanceof ArrayBuffer) { | |
return fromArrayBuffer(that, value, encodingOrOffset, length) | |
} | |
if (typeof value === 'string') { | |
return fromString(that, value, encodingOrOffset) | |
} | |
return fromObject(that, value) | |
} | |
/** | |
* Functionally equivalent to Buffer(arg, encoding) but throws a TypeError | |
* if value is a number. | |
* Buffer.from(str[, encoding]) | |
* Buffer.from(array) | |
* Buffer.from(buffer) | |
* Buffer.from(arrayBuffer[, byteOffset[, length]]) | |
**/ | |
Buffer.from = function (value, encodingOrOffset, length) { | |
return from(null, value, encodingOrOffset, length) | |
} | |
if (Buffer.TYPED_ARRAY_SUPPORT) { | |
Buffer.prototype.__proto__ = Uint8Array.prototype | |
Buffer.__proto__ = Uint8Array | |
if (typeof Symbol !== 'undefined' && Symbol.species && | |
Buffer[Symbol.species] === Buffer) { | |
// Fix subarray() in ES2016. See: https://github.com/feross/buffer/pull/97 | |
Object.defineProperty(Buffer, Symbol.species, { | |
value: null, | |
configurable: true | |
}) | |
} | |
} | |
function assertSize (size) { | |
if (typeof size !== 'number') { | |
throw new TypeError('"size" argument must be a number') | |
} | |
} | |
function alloc (that, size, fill, encoding) { | |
assertSize(size) | |
if (size <= 0) { | |
return createBuffer(that, size) | |
} | |
if (fill !== undefined) { | |
// Only pay attention to encoding if it's a string. This | |
// prevents accidentally sending in a number that would | |
// be interpretted as a start offset. | |
return typeof encoding === 'string' | |
? createBuffer(that, size).fill(fill, encoding) | |
: createBuffer(that, size).fill(fill) | |
} | |
return createBuffer(that, size) | |
} | |
/** | |
* Creates a new filled Buffer instance. | |
* alloc(size[, fill[, encoding]]) | |
**/ | |
Buffer.alloc = function (size, fill, encoding) { | |
return alloc(null, size, fill, encoding) | |
} | |
function allocUnsafe (that, size) { | |
assertSize(size) | |
that = createBuffer(that, size < 0 ? 0 : checked(size) | 0) | |
if (!Buffer.TYPED_ARRAY_SUPPORT) { | |
for (var i = 0; i < size; ++i) { | |
that[i] = 0 | |
} | |
} | |
return that | |
} | |
/** | |
* Equivalent to Buffer(num), by default creates a non-zero-filled Buffer instance. | |
* */ | |
Buffer.allocUnsafe = function (size) { | |
return allocUnsafe(null, size) | |
} | |
/** | |
* Equivalent to SlowBuffer(num), by default creates a non-zero-filled Buffer instance. | |
*/ | |
Buffer.allocUnsafeSlow = function (size) { | |
return allocUnsafe(null, size) | |
} | |
function fromString (that, string, encoding) { | |
if (typeof encoding !== 'string' || encoding === '') { | |
encoding = 'utf8' | |
} | |
if (!Buffer.isEncoding(encoding)) { | |
throw new TypeError('"encoding" must be a valid string encoding') | |
} | |
var length = byteLength(string, encoding) | 0 | |
that = createBuffer(that, length) | |
that.write(string, encoding) | |
return that | |
} | |
function fromArrayLike (that, array) { | |
var length = checked(array.length) | 0 | |
that = createBuffer(that, length) | |
for (var i = 0; i < length; i += 1) { | |
that[i] = array[i] & 255 | |
} | |
return that | |
} | |
function fromArrayBuffer (that, array, byteOffset, length) { | |
array.byteLength // this throws if `array` is not a valid ArrayBuffer | |
if (byteOffset < 0 || array.byteLength < byteOffset) { | |
throw new RangeError('\'offset\' is out of bounds') | |
} | |
if (array.byteLength < byteOffset + (length || 0)) { | |
throw new RangeError('\'length\' is out of bounds') | |
} | |
if (byteOffset === undefined && length === undefined) { | |
array = new Uint8Array(array) | |
} else if (length === undefined) { | |
array = new Uint8Array(array, byteOffset) | |
} else { | |
array = new Uint8Array(array, byteOffset, length) | |
} | |
if (Buffer.TYPED_ARRAY_SUPPORT) { | |
// Return an augmented `Uint8Array` instance, for best performance | |
that = array | |
that.__proto__ = Buffer.prototype | |
} else { | |
// Fallback: Return an object instance of the Buffer class | |
that = fromArrayLike(that, array) | |
} | |
return that | |
} | |
function fromObject (that, obj) { | |
if (Buffer.isBuffer(obj)) { | |
var len = checked(obj.length) | 0 | |
that = createBuffer(that, len) | |
if (that.length === 0) { | |
return that | |
} | |
obj.copy(that, 0, 0, len) | |
return that | |
} | |
if (obj) { | |
if ((typeof ArrayBuffer !== 'undefined' && | |
obj.buffer instanceof ArrayBuffer) || 'length' in obj) { | |
if (typeof obj.length !== 'number' || isnan(obj.length)) { | |
return createBuffer(that, 0) | |
} | |
return fromArrayLike(that, obj) | |
} | |
if (obj.type === 'Buffer' && isArray(obj.data)) { | |
return fromArrayLike(that, obj.data) | |
} | |
} | |
throw new TypeError('First argument must be a string, Buffer, ArrayBuffer, Array, or array-like object.') | |
} | |
function checked (length) { | |
// Note: cannot use `length < kMaxLength` here because that fails when | |
// length is NaN (which is otherwise coerced to zero.) | |
if (length >= kMaxLength()) { | |
throw new RangeError('Attempt to allocate Buffer larger than maximum ' + | |
'size: 0x' + kMaxLength().toString(16) + ' bytes') | |
} | |
return length | 0 | |
} | |
function SlowBuffer (length) { | |
if (+length != length) { // eslint-disable-line eqeqeq | |
length = 0 | |
} | |
return Buffer.alloc(+length) | |
} | |
Buffer.isBuffer = function isBuffer (b) { | |
return !!(b != null && b._isBuffer) | |
} | |
Buffer.compare = function compare (a, b) { | |
if (!Buffer.isBuffer(a) || !Buffer.isBuffer(b)) { | |
throw new TypeError('Arguments must be Buffers') | |
} | |
if (a === b) return 0 | |
var x = a.length | |
var y = b.length | |
for (var i = 0, len = Math.min(x, y); i < len; ++i) { | |
if (a[i] !== b[i]) { | |
x = a[i] | |
y = b[i] | |
break | |
} | |
} | |
if (x < y) return -1 | |
if (y < x) return 1 | |
return 0 | |
} | |
Buffer.isEncoding = function isEncoding (encoding) { | |
switch (String(encoding).toLowerCase()) { | |
case 'hex': | |
case 'utf8': | |
case 'utf-8': | |
case 'ascii': | |
case 'binary': | |
case 'base64': | |
case 'raw': | |
case 'ucs2': | |
case 'ucs-2': | |
case 'utf16le': | |
case 'utf-16le': | |
return true | |
default: | |
return false | |
} | |
} | |
Buffer.concat = function concat (list, length) { | |
if (!isArray(list)) { | |
throw new TypeError('"list" argument must be an Array of Buffers') | |
} | |
if (list.length === 0) { | |
return Buffer.alloc(0) | |
} | |
var i | |
if (length === undefined) { | |
length = 0 | |
for (i = 0; i < list.length; ++i) { | |
length += list[i].length | |
} | |
} | |
var buffer = Buffer.allocUnsafe(length) | |
var pos = 0 | |
for (i = 0; i < list.length; ++i) { | |
var buf = list[i] | |
if (!Buffer.isBuffer(buf)) { | |
throw new TypeError('"list" argument must be an Array of Buffers') | |
} | |
buf.copy(buffer, pos) | |
pos += buf.length | |
} | |
return buffer | |
} | |
function byteLength (string, encoding) { | |
if (Buffer.isBuffer(string)) { | |
return string.length | |
} | |
if (typeof ArrayBuffer !== 'undefined' && typeof ArrayBuffer.isView === 'function' && | |
(ArrayBuffer.isView(string) || string instanceof ArrayBuffer)) { | |
return string.byteLength | |
} | |
if (typeof string !== 'string') { | |
string = '' + string | |
} | |
var len = string.length | |
if (len === 0) return 0 | |
// Use a for loop to avoid recursion | |
var loweredCase = false | |
for (;;) { | |
switch (encoding) { | |
case 'ascii': | |
case 'binary': | |
case 'raw': | |
case 'raws': | |
return len | |
case 'utf8': | |
case 'utf-8': | |
case undefined: | |
return utf8ToBytes(string).length | |
case 'ucs2': | |
case 'ucs-2': | |
case 'utf16le': | |
case 'utf-16le': | |
return len * 2 | |
case 'hex': | |
return len >>> 1 | |
case 'base64': | |
return base64ToBytes(string).length | |
default: | |
if (loweredCase) return utf8ToBytes(string).length // assume utf8 | |
encoding = ('' + encoding).toLowerCase() | |
loweredCase = true | |
} | |
} | |
} | |
Buffer.byteLength = byteLength | |
function slowToString (encoding, start, end) { | |
var loweredCase = false | |
// No need to verify that "this.length <= MAX_UINT32" since it's a read-only | |
// property of a typed array. | |
// This behaves neither like String nor Uint8Array in that we set start/end | |
// to their upper/lower bounds if the value passed is out of range. | |
// undefined is handled specially as per ECMA-262 6th Edition, | |
// Section 13.3.3.7 Runtime Semantics: KeyedBindingInitialization. | |
if (start === undefined || start < 0) { | |
start = 0 | |
} | |
// Return early if start > this.length. Done here to prevent potential uint32 | |
// coercion fail below. | |
if (start > this.length) { | |
return '' | |
} | |
if (end === undefined || end > this.length) { | |
end = this.length | |
} | |
if (end <= 0) { | |
return '' | |
} | |
// Force coersion to uint32. This will also coerce falsey/NaN values to 0. | |
end >>>= 0 | |
start >>>= 0 | |
if (end <= start) { | |
return '' | |
} | |
if (!encoding) encoding = 'utf8' | |
while (true) { | |
switch (encoding) { | |
case 'hex': | |
return hexSlice(this, start, end) | |
case 'utf8': | |
case 'utf-8': | |
return utf8Slice(this, start, end) | |
case 'ascii': | |
return asciiSlice(this, start, end) | |
case 'binary': | |
return binarySlice(this, start, end) | |
case 'base64': | |
return base64Slice(this, start, end) | |
case 'ucs2': | |
case 'ucs-2': | |
case 'utf16le': | |
case 'utf-16le': | |
return utf16leSlice(this, start, end) | |
default: | |
if (loweredCase) throw new TypeError('Unknown encoding: ' + encoding) | |
encoding = (encoding + '').toLowerCase() | |
loweredCase = true | |
} | |
} | |
} | |
// The property is used by `Buffer.isBuffer` and `is-buffer` (in Safari 5-7) to detect | |
// Buffer instances. | |
Buffer.prototype._isBuffer = true | |
function swap (b, n, m) { | |
var i = b[n] | |
b[n] = b[m] | |
b[m] = i | |
} | |
Buffer.prototype.swap16 = function swap16 () { | |
var len = this.length | |
if (len % 2 !== 0) { | |
throw new RangeError('Buffer size must be a multiple of 16-bits') | |
} | |
for (var i = 0; i < len; i += 2) { | |
swap(this, i, i + 1) | |
} | |
return this | |
} | |
Buffer.prototype.swap32 = function swap32 () { | |
var len = this.length | |
if (len % 4 !== 0) { | |
throw new RangeError('Buffer size must be a multiple of 32-bits') | |
} | |
for (var i = 0; i < len; i += 4) { | |
swap(this, i, i + 3) | |
swap(this, i + 1, i + 2) | |
} | |
return this | |
} | |
Buffer.prototype.toString = function toString () { | |
var length = this.length | 0 | |
if (length === 0) return '' | |
if (arguments.length === 0) return utf8Slice(this, 0, length) | |
return slowToString.apply(this, arguments) | |
} | |
Buffer.prototype.equals = function equals (b) { | |
if (!Buffer.isBuffer(b)) throw new TypeError('Argument must be a Buffer') | |
if (this === b) return true | |
return Buffer.compare(this, b) === 0 | |
} | |
Buffer.prototype.inspect = function inspect () { | |
var str = '' | |
var max = exports.INSPECT_MAX_BYTES | |
if (this.length > 0) { | |
str = this.toString('hex', 0, max).match(/.{2}/g).join(' ') | |
if (this.length > max) str += ' ... ' | |
} | |
return '<Buffer ' + str + '>' | |
} | |
Buffer.prototype.compare = function compare (target, start, end, thisStart, thisEnd) { | |
if (!Buffer.isBuffer(target)) { | |
throw new TypeError('Argument must be a Buffer') | |
} | |
if (start === undefined) { | |
start = 0 | |
} | |
if (end === undefined) { | |
end = target ? target.length : 0 | |
} | |
if (thisStart === undefined) { | |
thisStart = 0 | |
} | |
if (thisEnd === undefined) { | |
thisEnd = this.length | |
} | |
if (start < 0 || end > target.length || thisStart < 0 || thisEnd > this.length) { | |
throw new RangeError('out of range index') | |
} | |
if (thisStart >= thisEnd && start >= end) { | |
return 0 | |
} | |
if (thisStart >= thisEnd) { | |
return -1 | |
} | |
if (start >= end) { | |
return 1 | |
} | |
start >>>= 0 | |
end >>>= 0 | |
thisStart >>>= 0 | |
thisEnd >>>= 0 | |
if (this === target) return 0 | |
var x = thisEnd - thisStart | |
var y = end - start | |
var len = Math.min(x, y) | |
var thisCopy = this.slice(thisStart, thisEnd) | |
var targetCopy = target.slice(start, end) | |
for (var i = 0; i < len; ++i) { | |
if (thisCopy[i] !== targetCopy[i]) { | |
x = thisCopy[i] | |
y = targetCopy[i] | |
break | |
} | |
} | |
if (x < y) return -1 | |
if (y < x) return 1 | |
return 0 | |
} | |
function arrayIndexOf (arr, val, byteOffset, encoding) { | |
var indexSize = 1 | |
var arrLength = arr.length | |
var valLength = val.length | |
if (encoding !== undefined) { | |
encoding = String(encoding).toLowerCase() | |
if (encoding === 'ucs2' || encoding === 'ucs-2' || | |
encoding === 'utf16le' || encoding === 'utf-16le') { | |
if (arr.length < 2 || val.length < 2) { | |
return -1 | |
} | |
indexSize = 2 | |
arrLength /= 2 | |
valLength /= 2 | |
byteOffset /= 2 | |
} | |
} | |
function read (buf, i) { | |
if (indexSize === 1) { | |
return buf[i] | |
} else { | |
return buf.readUInt16BE(i * indexSize) | |
} | |
} | |
var foundIndex = -1 | |
for (var i = byteOffset; i < arrLength; ++i) { | |
if (read(arr, i) === read(val, foundIndex === -1 ? 0 : i - foundIndex)) { | |
if (foundIndex === -1) foundIndex = i | |
if (i - foundIndex + 1 === valLength) return foundIndex * indexSize | |
} else { | |
if (foundIndex !== -1) i -= i - foundIndex | |
foundIndex = -1 | |
} | |
} | |
return -1 | |
} | |
Buffer.prototype.indexOf = function indexOf (val, byteOffset, encoding) { | |
if (typeof byteOffset === 'string') { | |
encoding = byteOffset | |
byteOffset = 0 | |
} else if (byteOffset > 0x7fffffff) { | |
byteOffset = 0x7fffffff | |
} else if (byteOffset < -0x80000000) { | |
byteOffset = -0x80000000 | |
} | |
byteOffset >>= 0 | |
if (this.length === 0) return -1 | |
if (byteOffset >= this.length) return -1 | |
// Negative offsets start from the end of the buffer | |
if (byteOffset < 0) byteOffset = Math.max(this.length + byteOffset, 0) | |
if (typeof val === 'string') { | |
val = Buffer.from(val, encoding) | |
} | |
if (Buffer.isBuffer(val)) { | |
// special case: looking for empty string/buffer always fails | |
if (val.length === 0) { | |
return -1 | |
} | |
return arrayIndexOf(this, val, byteOffset, encoding) | |
} | |
if (typeof val === 'number') { | |
if (Buffer.TYPED_ARRAY_SUPPORT && Uint8Array.prototype.indexOf === 'function') { | |
return Uint8Array.prototype.indexOf.call(this, val, byteOffset) | |
} | |
return arrayIndexOf(this, [ val ], byteOffset, encoding) | |
} | |
throw new TypeError('val must be string, number or Buffer') | |
} | |
Buffer.prototype.includes = function includes (val, byteOffset, encoding) { | |
return this.indexOf(val, byteOffset, encoding) !== -1 | |
} | |
function hexWrite (buf, string, offset, length) { | |
offset = Number(offset) || 0 | |
var remaining = buf.length - offset | |
if (!length) { | |
length = remaining | |
} else { | |
length = Number(length) | |
if (length > remaining) { | |
length = remaining | |
} | |
} | |
// must be an even number of digits | |
var strLen = string.length | |
if (strLen % 2 !== 0) throw new Error('Invalid hex string') | |
if (length > strLen / 2) { | |
length = strLen / 2 | |
} | |
for (var i = 0; i < length; ++i) { | |
var parsed = parseInt(string.substr(i * 2, 2), 16) | |
if (isNaN(parsed)) return i | |
buf[offset + i] = parsed | |
} | |
return i | |
} | |
function utf8Write (buf, string, offset, length) { | |
return blitBuffer(utf8ToBytes(string, buf.length - offset), buf, offset, length) | |
} | |
function asciiWrite (buf, string, offset, length) { | |
return blitBuffer(asciiToBytes(string), buf, offset, length) | |
} | |
function binaryWrite (buf, string, offset, length) { | |
return asciiWrite(buf, string, offset, length) | |
} | |
function base64Write (buf, string, offset, length) { | |
return blitBuffer(base64ToBytes(string), buf, offset, length) | |
} | |
function ucs2Write (buf, string, offset, length) { | |
return blitBuffer(utf16leToBytes(string, buf.length - offset), buf, offset, length) | |
} | |
Buffer.prototype.write = function write (string, offset, length, encoding) { | |
// Buffer#write(string) | |
if (offset === undefined) { | |
encoding = 'utf8' | |
length = this.length | |
offset = 0 | |
// Buffer#write(string, encoding) | |
} else if (length === undefined && typeof offset === 'string') { | |
encoding = offset | |
length = this.length | |
offset = 0 | |
// Buffer#write(string, offset[, length][, encoding]) | |
} else if (isFinite(offset)) { | |
offset = offset | 0 | |
if (isFinite(length)) { | |
length = length | 0 | |
if (encoding === undefined) encoding = 'utf8' | |
} else { | |
encoding = length | |
length = undefined | |
} | |
// legacy write(string, encoding, offset, length) - remove in v0.13 | |
} else { | |
throw new Error( | |
'Buffer.write(string, encoding, offset[, length]) is no longer supported' | |
) | |
} | |
var remaining = this.length - offset | |
if (length === undefined || length > remaining) length = remaining | |
if ((string.length > 0 && (length < 0 || offset < 0)) || offset > this.length) { | |
throw new RangeError('Attempt to write outside buffer bounds') | |
} | |
if (!encoding) encoding = 'utf8' | |
var loweredCase = false | |
for (;;) { | |
switch (encoding) { | |
case 'hex': | |
return hexWrite(this, string, offset, length) | |
case 'utf8': | |
case 'utf-8': | |
return utf8Write(this, string, offset, length) | |
case 'ascii': | |
return asciiWrite(this, string, offset, length) | |
case 'binary': | |
return binaryWrite(this, string, offset, length) | |
case 'base64': | |
// Warning: maxLength not taken into account in base64Write | |
return base64Write(this, string, offset, length) | |
case 'ucs2': | |
case 'ucs-2': | |
case 'utf16le': | |
case 'utf-16le': | |
return ucs2Write(this, string, offset, length) | |
default: | |
if (loweredCase) throw new TypeError('Unknown encoding: ' + encoding) | |
encoding = ('' + encoding).toLowerCase() | |
loweredCase = true | |
} | |
} | |
} | |
Buffer.prototype.toJSON = function toJSON () { | |
return { | |
type: 'Buffer', | |
data: Array.prototype.slice.call(this._arr || this, 0) | |
} | |
} | |
function base64Slice (buf, start, end) { | |
if (start === 0 && end === buf.length) { | |
return base64.fromByteArray(buf) | |
} else { | |
return base64.fromByteArray(buf.slice(start, end)) | |
} | |
} | |
function utf8Slice (buf, start, end) { | |
end = Math.min(buf.length, end) | |
var res = [] | |
var i = start | |
while (i < end) { | |
var firstByte = buf[i] | |
var codePoint = null | |
var bytesPerSequence = (firstByte > 0xEF) ? 4 | |
: (firstByte > 0xDF) ? 3 | |
: (firstByte > 0xBF) ? 2 | |
: 1 | |
if (i + bytesPerSequence <= end) { | |
var secondByte, thirdByte, fourthByte, tempCodePoint | |
switch (bytesPerSequence) { | |
case 1: | |
if (firstByte < 0x80) { | |
codePoint = firstByte | |
} | |
break | |
case 2: | |
secondByte = buf[i + 1] | |
if ((secondByte & 0xC0) === 0x80) { | |
tempCodePoint = (firstByte & 0x1F) << 0x6 | (secondByte & 0x3F) | |
if (tempCodePoint > 0x7F) { | |
codePoint = tempCodePoint | |
} | |
} | |
break | |
case 3: | |
secondByte = buf[i + 1] | |
thirdByte = buf[i + 2] | |
if ((secondByte & 0xC0) === 0x80 && (thirdByte & 0xC0) === 0x80) { | |
tempCodePoint = (firstByte & 0xF) << 0xC | (secondByte & 0x3F) << 0x6 | (thirdByte & 0x3F) | |
if (tempCodePoint > 0x7FF && (tempCodePoint < 0xD800 || tempCodePoint > 0xDFFF)) { | |
codePoint = tempCodePoint | |
} | |
} | |
break | |
case 4: | |
secondByte = buf[i + 1] | |
thirdByte = buf[i + 2] | |
fourthByte = buf[i + 3] | |
if ((secondByte & 0xC0) === 0x80 && (thirdByte & 0xC0) === 0x80 && (fourthByte & 0xC0) === 0x80) { | |
tempCodePoint = (firstByte & 0xF) << 0x12 | (secondByte & 0x3F) << 0xC | (thirdByte & 0x3F) << 0x6 | (fourthByte & 0x3F) | |
if (tempCodePoint > 0xFFFF && tempCodePoint < 0x110000) { | |
codePoint = tempCodePoint | |
} | |
} | |
} | |
} | |
if (codePoint === null) { | |
// we did not generate a valid codePoint so insert a | |
// replacement char (U+FFFD) and advance only 1 byte | |
codePoint = 0xFFFD | |
bytesPerSequence = 1 | |
} else if (codePoint > 0xFFFF) { | |
// encode to utf16 (surrogate pair dance) | |
codePoint -= 0x10000 | |
res.push(codePoint >>> 10 & 0x3FF | 0xD800) | |
codePoint = 0xDC00 | codePoint & 0x3FF | |
} | |
res.push(codePoint) | |
i += bytesPerSequence | |
} | |
return decodeCodePointsArray(res) | |
} | |
// Based on http://stackoverflow.com/a/22747272/680742, the browser with | |
// the lowest limit is Chrome, with 0x10000 args. | |
// We go 1 magnitude less, for safety | |
var MAX_ARGUMENTS_LENGTH = 0x1000 | |
function decodeCodePointsArray (codePoints) { | |
var len = codePoints.length | |
if (len <= MAX_ARGUMENTS_LENGTH) { | |
return String.fromCharCode.apply(String, codePoints) // avoid extra slice() | |
} | |
// Decode in chunks to avoid "call stack size exceeded". | |
var res = '' | |
var i = 0 | |
while (i < len) { | |
res += String.fromCharCode.apply( | |
String, | |
codePoints.slice(i, i += MAX_ARGUMENTS_LENGTH) | |
) | |
} | |
return res | |
} | |
function asciiSlice (buf, start, end) { | |
var ret = '' | |
end = Math.min(buf.length, end) | |
for (var i = start; i < end; ++i) { | |
ret += String.fromCharCode(buf[i] & 0x7F) | |
} | |
return ret | |
} | |
function binarySlice (buf, start, end) { | |
var ret = '' | |
end = Math.min(buf.length, end) | |
for (var i = start; i < end; ++i) { | |
ret += String.fromCharCode(buf[i]) | |
} | |
return ret | |
} | |
function hexSlice (buf, start, end) { | |
var len = buf.length | |
if (!start || start < 0) start = 0 | |
if (!end || end < 0 || end > len) end = len | |
var out = '' | |
for (var i = start; i < end; ++i) { | |
out += toHex(buf[i]) | |
} | |
return out | |
} | |
function utf16leSlice (buf, start, end) { | |
var bytes = buf.slice(start, end) | |
var res = '' | |
for (var i = 0; i < bytes.length; i += 2) { | |
res += String.fromCharCode(bytes[i] + bytes[i + 1] * 256) | |
} | |
return res | |
} | |
Buffer.prototype.slice = function slice (start, end) { | |
var len = this.length | |
start = ~~start | |
end = end === undefined ? len : ~~end | |
if (start < 0) { | |
start += len | |
if (start < 0) start = 0 | |
} else if (start > len) { | |
start = len | |
} | |
if (end < 0) { | |
end += len | |
if (end < 0) end = 0 | |
} else if (end > len) { | |
end = len | |
} | |
if (end < start) end = start | |
var newBuf | |
if (Buffer.TYPED_ARRAY_SUPPORT) { | |
newBuf = this.subarray(start, end) | |
newBuf.__proto__ = Buffer.prototype | |
} else { | |
var sliceLen = end - start | |
newBuf = new Buffer(sliceLen, undefined) | |
for (var i = 0; i < sliceLen; ++i) { | |
newBuf[i] = this[i + start] | |
} | |
} | |
return newBuf | |
} | |
/* | |
* Need to make sure that buffer isn't trying to write out of bounds. | |
*/ | |
function checkOffset (offset, ext, length) { | |
if ((offset % 1) !== 0 || offset < 0) throw new RangeError('offset is not uint') | |
if (offset + ext > length) throw new RangeError('Trying to access beyond buffer length') | |
} | |
Buffer.prototype.readUIntLE = function readUIntLE (offset, byteLength, noAssert) { | |
offset = offset | 0 | |
byteLength = byteLength | 0 | |
if (!noAssert) checkOffset(offset, byteLength, this.length) | |
var val = this[offset] | |
var mul = 1 | |
var i = 0 | |
while (++i < byteLength && (mul *= 0x100)) { | |
val += this[offset + i] * mul | |
} | |
return val | |
} | |
Buffer.prototype.readUIntBE = function readUIntBE (offset, byteLength, noAssert) { | |
offset = offset | 0 | |
byteLength = byteLength | 0 | |
if (!noAssert) { | |
checkOffset(offset, byteLength, this.length) | |
} | |
var val = this[offset + --byteLength] | |
var mul = 1 | |
while (byteLength > 0 && (mul *= 0x100)) { | |
val += this[offset + --byteLength] * mul | |
} | |
return val | |
} | |
Buffer.prototype.readUInt8 = function readUInt8 (offset, noAssert) { | |
if (!noAssert) checkOffset(offset, 1, this.length) | |
return this[offset] | |
} | |
Buffer.prototype.readUInt16LE = function readUInt16LE (offset, noAssert) { | |
if (!noAssert) checkOffset(offset, 2, this.length) | |
return this[offset] | (this[offset + 1] << 8) | |
} | |
Buffer.prototype.readUInt16BE = function readUInt16BE (offset, noAssert) { | |
if (!noAssert) checkOffset(offset, 2, this.length) | |
return (this[offset] << 8) | this[offset + 1] | |
} | |
Buffer.prototype.readUInt32LE = function readUInt32LE (offset, noAssert) { | |
if (!noAssert) checkOffset(offset, 4, this.length) | |
return ((this[offset]) | | |
(this[offset + 1] << 8) | | |
(this[offset + 2] << 16)) + | |
(this[offset + 3] * 0x1000000) | |
} | |
Buffer.prototype.readUInt32BE = function readUInt32BE (offset, noAssert) { | |
if (!noAssert) checkOffset(offset, 4, this.length) | |
return (this[offset] * 0x1000000) + | |
((this[offset + 1] << 16) | | |
(this[offset + 2] << 8) | | |
this[offset + 3]) | |
} | |
Buffer.prototype.readIntLE = function readIntLE (offset, byteLength, noAssert) { | |
offset = offset | 0 | |
byteLength = byteLength | 0 | |
if (!noAssert) checkOffset(offset, byteLength, this.length) | |
var val = this[offset] | |
var mul = 1 | |
var i = 0 | |
while (++i < byteLength && (mul *= 0x100)) { | |
val += this[offset + i] * mul | |
} | |
mul *= 0x80 | |
if (val >= mul) val -= Math.pow(2, 8 * byteLength) | |
return val | |
} | |
Buffer.prototype.readIntBE = function readIntBE (offset, byteLength, noAssert) { | |
offset = offset | 0 | |
byteLength = byteLength | 0 | |
if (!noAssert) checkOffset(offset, byteLength, this.length) | |
var i = byteLength | |
var mul = 1 | |
var val = this[offset + --i] | |
while (i > 0 && (mul *= 0x100)) { | |
val += this[offset + --i] * mul | |
} | |
mul *= 0x80 | |
if (val >= mul) val -= Math.pow(2, 8 * byteLength) | |
return val | |
} | |
Buffer.prototype.readInt8 = function readInt8 (offset, noAssert) { | |
if (!noAssert) checkOffset(offset, 1, this.length) | |
if (!(this[offset] & 0x80)) return (this[offset]) | |
return ((0xff - this[offset] + 1) * -1) | |
} | |
Buffer.prototype.readInt16LE = function readInt16LE (offset, noAssert) { | |
if (!noAssert) checkOffset(offset, 2, this.length) | |
var val = this[offset] | (this[offset + 1] << 8) | |
return (val & 0x8000) ? val | 0xFFFF0000 : val | |
} | |
Buffer.prototype.readInt16BE = function readInt16BE (offset, noAssert) { | |
if (!noAssert) checkOffset(offset, 2, this.length) | |
var val = this[offset + 1] | (this[offset] << 8) | |
return (val & 0x8000) ? val | 0xFFFF0000 : val | |
} | |
Buffer.prototype.readInt32LE = function readInt32LE (offset, noAssert) { | |
if (!noAssert) checkOffset(offset, 4, this.length) | |
return (this[offset]) | | |
(this[offset + 1] << 8) | | |
(this[offset + 2] << 16) | | |
(this[offset + 3] << 24) | |
} | |
Buffer.prototype.readInt32BE = function readInt32BE (offset, noAssert) { | |
if (!noAssert) checkOffset(offset, 4, this.length) | |
return (this[offset] << 24) | | |
(this[offset + 1] << 16) | | |
(this[offset + 2] << 8) | | |
(this[offset + 3]) | |
} | |
Buffer.prototype.readFloatLE = function readFloatLE (offset, noAssert) { | |
if (!noAssert) checkOffset(offset, 4, this.length) | |
return ieee754.read(this, offset, true, 23, 4) | |
} | |
Buffer.prototype.readFloatBE = function readFloatBE (offset, noAssert) { | |
if (!noAssert) checkOffset(offset, 4, this.length) | |
return ieee754.read(this, offset, false, 23, 4) | |
} | |
Buffer.prototype.readDoubleLE = function readDoubleLE (offset, noAssert) { | |
if (!noAssert) checkOffset(offset, 8, this.length) | |
return ieee754.read(this, offset, true, 52, 8) | |
} | |
Buffer.prototype.readDoubleBE = function readDoubleBE (offset, noAssert) { | |
if (!noAssert) checkOffset(offset, 8, this.length) | |
return ieee754.read(this, offset, false, 52, 8) | |
} | |
function checkInt (buf, value, offset, ext, max, min) { | |
if (!Buffer.isBuffer(buf)) throw new TypeError('"buffer" argument must be a Buffer instance') | |
if (value > max || value < min) throw new RangeError('"value" argument is out of bounds') | |
if (offset + ext > buf.length) throw new RangeError('Index out of range') | |
} | |
Buffer.prototype.writeUIntLE = function writeUIntLE (value, offset, byteLength, noAssert) { | |
value = +value | |
offset = offset | 0 | |
byteLength = byteLength | 0 | |
if (!noAssert) { | |
var maxBytes = Math.pow(2, 8 * byteLength) - 1 | |
checkInt(this, value, offset, byteLength, maxBytes, 0) | |
} | |
var mul = 1 | |
var i = 0 | |
this[offset] = value & 0xFF | |
while (++i < byteLength && (mul *= 0x100)) { | |
this[offset + i] = (value / mul) & 0xFF | |
} | |
return offset + byteLength | |
} | |
Buffer.prototype.writeUIntBE = function writeUIntBE (value, offset, byteLength, noAssert) { | |
value = +value | |
offset = offset | 0 | |
byteLength = byteLength | 0 | |
if (!noAssert) { | |
var maxBytes = Math.pow(2, 8 * byteLength) - 1 | |
checkInt(this, value, offset, byteLength, maxBytes, 0) | |
} | |
var i = byteLength - 1 | |
var mul = 1 | |
this[offset + i] = value & 0xFF | |
while (--i >= 0 && (mul *= 0x100)) { | |
this[offset + i] = (value / mul) & 0xFF | |
} | |
return offset + byteLength | |
} | |
Buffer.prototype.writeUInt8 = function writeUInt8 (value, offset, noAssert) { | |
value = +value | |
offset = offset | 0 | |
if (!noAssert) checkInt(this, value, offset, 1, 0xff, 0) | |
if (!Buffer.TYPED_ARRAY_SUPPORT) value = Math.floor(value) | |
this[offset] = (value & 0xff) | |
return offset + 1 | |
} | |
function objectWriteUInt16 (buf, value, offset, littleEndian) { | |
if (value < 0) value = 0xffff + value + 1 | |
for (var i = 0, j = Math.min(buf.length - offset, 2); i < j; ++i) { | |
buf[offset + i] = (value & (0xff << (8 * (littleEndian ? i : 1 - i)))) >>> | |
(littleEndian ? i : 1 - i) * 8 | |
} | |
} | |
Buffer.prototype.writeUInt16LE = function writeUInt16LE (value, offset, noAssert) { | |
value = +value | |
offset = offset | 0 | |
if (!noAssert) checkInt(this, value, offset, 2, 0xffff, 0) | |
if (Buffer.TYPED_ARRAY_SUPPORT) { | |
this[offset] = (value & 0xff) | |
this[offset + 1] = (value >>> 8) | |
} else { | |
objectWriteUInt16(this, value, offset, true) | |
} | |
return offset + 2 | |
} | |
Buffer.prototype.writeUInt16BE = function writeUInt16BE (value, offset, noAssert) { | |
value = +value | |
offset = offset | 0 | |
if (!noAssert) checkInt(this, value, offset, 2, 0xffff, 0) | |
if (Buffer.TYPED_ARRAY_SUPPORT) { | |
this[offset] = (value >>> 8) | |
this[offset + 1] = (value & 0xff) | |
} else { | |
objectWriteUInt16(this, value, offset, false) | |
} | |
return offset + 2 | |
} | |
function objectWriteUInt32 (buf, value, offset, littleEndian) { | |
if (value < 0) value = 0xffffffff + value + 1 | |
for (var i = 0, j = Math.min(buf.length - offset, 4); i < j; ++i) { | |
buf[offset + i] = (value >>> (littleEndian ? i : 3 - i) * 8) & 0xff | |
} | |
} | |
Buffer.prototype.writeUInt32LE = function writeUInt32LE (value, offset, noAssert) { | |
value = +value | |
offset = offset | 0 | |
if (!noAssert) checkInt(this, value, offset, 4, 0xffffffff, 0) | |
if (Buffer.TYPED_ARRAY_SUPPORT) { | |
this[offset + 3] = (value >>> 24) | |
this[offset + 2] = (value >>> 16) | |
this[offset + 1] = (value >>> 8) | |
this[offset] = (value & 0xff) | |
} else { | |
objectWriteUInt32(this, value, offset, true) | |
} | |
return offset + 4 | |
} | |
Buffer.prototype.writeUInt32BE = function writeUInt32BE (value, offset, noAssert) { | |
value = +value | |
offset = offset | 0 | |
if (!noAssert) checkInt(this, value, offset, 4, 0xffffffff, 0) | |
if (Buffer.TYPED_ARRAY_SUPPORT) { | |
this[offset] = (value >>> 24) | |
this[offset + 1] = (value >>> 16) | |
this[offset + 2] = (value >>> 8) | |
this[offset + 3] = (value & 0xff) | |
} else { | |
objectWriteUInt32(this, value, offset, false) | |
} | |
return offset + 4 | |
} | |
Buffer.prototype.writeIntLE = function writeIntLE (value, offset, byteLength, noAssert) { | |
value = +value | |
offset = offset | 0 | |
if (!noAssert) { | |
var limit = Math.pow(2, 8 * byteLength - 1) | |
checkInt(this, value, offset, byteLength, limit - 1, -limit) | |
} | |
var i = 0 | |
var mul = 1 | |
var sub = 0 | |
this[offset] = value & 0xFF | |
while (++i < byteLength && (mul *= 0x100)) { | |
if (value < 0 && sub === 0 && this[offset + i - 1] !== 0) { | |
sub = 1 | |
} | |
this[offset + i] = ((value / mul) >> 0) - sub & 0xFF | |
} | |
return offset + byteLength | |
} | |
Buffer.prototype.writeIntBE = function writeIntBE (value, offset, byteLength, noAssert) { | |
value = +value | |
offset = offset | 0 | |
if (!noAssert) { | |
var limit = Math.pow(2, 8 * byteLength - 1) | |
checkInt(this, value, offset, byteLength, limit - 1, -limit) | |
} | |
var i = byteLength - 1 | |
var mul = 1 | |
var sub = 0 | |
this[offset + i] = value & 0xFF | |
while (--i >= 0 && (mul *= 0x100)) { | |
if (value < 0 && sub === 0 && this[offset + i + 1] !== 0) { | |
sub = 1 | |
} | |
this[offset + i] = ((value / mul) >> 0) - sub & 0xFF | |
} | |
return offset + byteLength | |
} | |
Buffer.prototype.writeInt8 = function writeInt8 (value, offset, noAssert) { | |
value = +value | |
offset = offset | 0 | |
if (!noAssert) checkInt(this, value, offset, 1, 0x7f, -0x80) | |
if (!Buffer.TYPED_ARRAY_SUPPORT) value = Math.floor(value) | |
if (value < 0) value = 0xff + value + 1 | |
this[offset] = (value & 0xff) | |
return offset + 1 | |
} | |
Buffer.prototype.writeInt16LE = function writeInt16LE (value, offset, noAssert) { | |
value = +value | |
offset = offset | 0 | |
if (!noAssert) checkInt(this, value, offset, 2, 0x7fff, -0x8000) | |
if (Buffer.TYPED_ARRAY_SUPPORT) { | |
this[offset] = (value & 0xff) | |
this[offset + 1] = (value >>> 8) | |
} else { | |
objectWriteUInt16(this, value, offset, true) | |
} | |
return offset + 2 | |
} | |
Buffer.prototype.writeInt16BE = function writeInt16BE (value, offset, noAssert) { | |
value = +value | |
offset = offset | 0 | |
if (!noAssert) checkInt(this, value, offset, 2, 0x7fff, -0x8000) | |
if (Buffer.TYPED_ARRAY_SUPPORT) { | |
this[offset] = (value >>> 8) | |
this[offset + 1] = (value & 0xff) | |
} else { | |
objectWriteUInt16(this, value, offset, false) | |
} | |
return offset + 2 | |
} | |
Buffer.prototype.writeInt32LE = function writeInt32LE (value, offset, noAssert) { | |
value = +value | |
offset = offset | 0 | |
if (!noAssert) checkInt(this, value, offset, 4, 0x7fffffff, -0x80000000) | |
if (Buffer.TYPED_ARRAY_SUPPORT) { | |
this[offset] = (value & 0xff) | |
this[offset + 1] = (value >>> 8) | |
this[offset + 2] = (value >>> 16) | |
this[offset + 3] = (value >>> 24) | |
} else { | |
objectWriteUInt32(this, value, offset, true) | |
} | |
return offset + 4 | |
} | |
Buffer.prototype.writeInt32BE = function writeInt32BE (value, offset, noAssert) { | |
value = +value | |
offset = offset | 0 | |
if (!noAssert) checkInt(this, value, offset, 4, 0x7fffffff, -0x80000000) | |
if (value < 0) value = 0xffffffff + value + 1 | |
if (Buffer.TYPED_ARRAY_SUPPORT) { | |
this[offset] = (value >>> 24) | |
this[offset + 1] = (value >>> 16) | |
this[offset + 2] = (value >>> 8) | |
this[offset + 3] = (value & 0xff) | |
} else { | |
objectWriteUInt32(this, value, offset, false) | |
} | |
return offset + 4 | |
} | |
function checkIEEE754 (buf, value, offset, ext, max, min) { | |
if (offset + ext > buf.length) throw new RangeError('Index out of range') | |
if (offset < 0) throw new RangeError('Index out of range') | |
} | |
function writeFloat (buf, value, offset, littleEndian, noAssert) { | |
if (!noAssert) { | |
checkIEEE754(buf, value, offset, 4, 3.4028234663852886e+38, -3.4028234663852886e+38) | |
} | |
ieee754.write(buf, value, offset, littleEndian, 23, 4) | |
return offset + 4 | |
} | |
Buffer.prototype.writeFloatLE = function writeFloatLE (value, offset, noAssert) { | |
return writeFloat(this, value, offset, true, noAssert) | |
} | |
Buffer.prototype.writeFloatBE = function writeFloatBE (value, offset, noAssert) { | |
return writeFloat(this, value, offset, false, noAssert) | |
} | |
function writeDouble (buf, value, offset, littleEndian, noAssert) { | |
if (!noAssert) { | |
checkIEEE754(buf, value, offset, 8, 1.7976931348623157E+308, -1.7976931348623157E+308) | |
} | |
ieee754.write(buf, value, offset, littleEndian, 52, 8) | |
return offset + 8 | |
} | |
Buffer.prototype.writeDoubleLE = function writeDoubleLE (value, offset, noAssert) { | |
return writeDouble(this, value, offset, true, noAssert) | |
} | |
Buffer.prototype.writeDoubleBE = function writeDoubleBE (value, offset, noAssert) { | |
return writeDouble(this, value, offset, false, noAssert) | |
} | |
// copy(targetBuffer, targetStart=0, sourceStart=0, sourceEnd=buffer.length) | |
Buffer.prototype.copy = function copy (target, targetStart, start, end) { | |
if (!start) start = 0 | |
if (!end && end !== 0) end = this.length | |
if (targetStart >= target.length) targetStart = target.length | |
if (!targetStart) targetStart = 0 | |
if (end > 0 && end < start) end = start | |
// Copy 0 bytes; we're done | |
if (end === start) return 0 | |
if (target.length === 0 || this.length === 0) return 0 | |
// Fatal error conditions | |
if (targetStart < 0) { | |
throw new RangeError('targetStart out of bounds') | |
} | |
if (start < 0 || start >= this.length) throw new RangeError('sourceStart out of bounds') | |
if (end < 0) throw new RangeError('sourceEnd out of bounds') | |
// Are we oob? | |
if (end > this.length) end = this.length | |
if (target.length - targetStart < end - start) { | |
end = target.length - targetStart + start | |
} | |
var len = end - start | |
var i | |
if (this === target && start < targetStart && targetStart < end) { | |
// descending copy from end | |
for (i = len - 1; i >= 0; --i) { | |
target[i + targetStart] = this[i + start] | |
} | |
} else if (len < 1000 || !Buffer.TYPED_ARRAY_SUPPORT) { | |
// ascending copy from start | |
for (i = 0; i < len; ++i) { | |
target[i + targetStart] = this[i + start] | |
} | |
} else { | |
Uint8Array.prototype.set.call( | |
target, | |
this.subarray(start, start + len), | |
targetStart | |
) | |
} | |
return len | |
} | |
// Usage: | |
// buffer.fill(number[, offset[, end]]) | |
// buffer.fill(buffer[, offset[, end]]) | |
// buffer.fill(string[, offset[, end]][, encoding]) | |
Buffer.prototype.fill = function fill (val, start, end, encoding) { | |
// Handle string cases: | |
if (typeof val === 'string') { | |
if (typeof start === 'string') { | |
encoding = start | |
start = 0 | |
end = this.length | |
} else if (typeof end === 'string') { | |
encoding = end | |
end = this.length | |
} | |
if (val.length === 1) { | |
var code = val.charCodeAt(0) | |
if (code < 256) { | |
val = code | |
} | |
} | |
if (encoding !== undefined && typeof encoding !== 'string') { | |
throw new TypeError('encoding must be a string') | |
} | |
if (typeof encoding === 'string' && !Buffer.isEncoding(encoding)) { | |
throw new TypeError('Unknown encoding: ' + encoding) | |
} | |
} else if (typeof val === 'number') { | |
val = val & 255 | |
} | |
// Invalid ranges are not set to a default, so can range check early. | |
if (start < 0 || this.length < start || this.length < end) { | |
throw new RangeError('Out of range index') | |
} | |
if (end <= start) { | |
return this | |
} | |
start = start >>> 0 | |
end = end === undefined ? this.length : end >>> 0 | |
if (!val) val = 0 | |
var i | |
if (typeof val === 'number') { | |
for (i = start; i < end; ++i) { | |
this[i] = val | |
} | |
} else { | |
var bytes = Buffer.isBuffer(val) | |
? val | |
: utf8ToBytes(new Buffer(val, encoding).toString()) | |
var len = bytes.length | |
for (i = 0; i < end - start; ++i) { | |
this[i + start] = bytes[i % len] | |
} | |
} | |
return this | |
} | |
// HELPER FUNCTIONS | |
// ================ | |
var INVALID_BASE64_RE = /[^+\/0-9A-Za-z-_]/g | |
function base64clean (str) { | |
// Node strips out invalid characters like \n and \t from the string, base64-js does not | |
str = stringtrim(str).replace(INVALID_BASE64_RE, '') | |
// Node converts strings with length < 2 to '' | |
if (str.length < 2) return '' | |
// Node allows for non-padded base64 strings (missing trailing ===), base64-js does not | |
while (str.length % 4 !== 0) { | |
str = str + '=' | |
} | |
return str | |
} | |
function stringtrim (str) { | |
if (str.trim) return str.trim() | |
return str.replace(/^\s+|\s+$/g, '') | |
} | |
function toHex (n) { | |
if (n < 16) return '0' + n.toString(16) | |
return n.toString(16) | |
} | |
function utf8ToBytes (string, units) { | |
units = units || Infinity | |
var codePoint | |
var length = string.length | |
var leadSurrogate = null | |
var bytes = [] | |
for (var i = 0; i < length; ++i) { | |
codePoint = string.charCodeAt(i) | |
// is surrogate component | |
if (codePoint > 0xD7FF && codePoint < 0xE000) { | |
// last char was a lead | |
if (!leadSurrogate) { | |
// no lead yet | |
if (codePoint > 0xDBFF) { | |
// unexpected trail | |
if ((units -= 3) > -1) bytes.push(0xEF, 0xBF, 0xBD) | |
continue | |
} else if (i + 1 === length) { | |
// unpaired lead | |
if ((units -= 3) > -1) bytes.push(0xEF, 0xBF, 0xBD) | |
continue | |
} | |
// valid lead | |
leadSurrogate = codePoint | |
continue | |
} | |
// 2 leads in a row | |
if (codePoint < 0xDC00) { | |
if ((units -= 3) > -1) bytes.push(0xEF, 0xBF, 0xBD) | |
leadSurrogate = codePoint | |
continue | |
} | |
// valid surrogate pair | |
codePoint = (leadSurrogate - 0xD800 << 10 | codePoint - 0xDC00) + 0x10000 | |
} else if (leadSurrogate) { | |
// valid bmp char, but last char was a lead | |
if ((units -= 3) > -1) bytes.push(0xEF, 0xBF, 0xBD) | |
} | |
leadSurrogate = null | |
// encode utf8 | |
if (codePoint < 0x80) { | |
if ((units -= 1) < 0) break | |
bytes.push(codePoint) | |
} else if (codePoint < 0x800) { | |
if ((units -= 2) < 0) break | |
bytes.push( | |
codePoint >> 0x6 | 0xC0, | |
codePoint & 0x3F | 0x80 | |
) | |
} else if (codePoint < 0x10000) { | |
if ((units -= 3) < 0) break | |
bytes.push( | |
codePoint >> 0xC | 0xE0, | |
codePoint >> 0x6 & 0x3F | 0x80, | |
codePoint & 0x3F | 0x80 | |
) | |
} else if (codePoint < 0x110000) { | |
if ((units -= 4) < 0) break | |
bytes.push( | |
codePoint >> 0x12 | 0xF0, | |
codePoint >> 0xC & 0x3F | 0x80, | |
codePoint >> 0x6 & 0x3F | 0x80, | |
codePoint & 0x3F | 0x80 | |
) | |
} else { | |
throw new Error('Invalid code point') | |
} | |
} | |
return bytes | |
} | |
function asciiToBytes (str) { | |
var byteArray = [] | |
for (var i = 0; i < str.length; ++i) { | |
// Node's code seems to be doing this and not & 0x7F.. | |
byteArray.push(str.charCodeAt(i) & 0xFF) | |
} | |
return byteArray | |
} | |
function utf16leToBytes (str, units) { | |
var c, hi, lo | |
var byteArray = [] | |
for (var i = 0; i < str.length; ++i) { | |
if ((units -= 2) < 0) break | |
c = str.charCodeAt(i) | |
hi = c >> 8 | |
lo = c % 256 | |
byteArray.push(lo) | |
byteArray.push(hi) | |
} | |
return byteArray | |
} | |
function base64ToBytes (str) { | |
return base64.toByteArray(base64clean(str)) | |
} | |
function blitBuffer (src, dst, offset, length) { | |
for (var i = 0; i < length; ++i) { | |
if ((i + offset >= dst.length) || (i >= src.length)) break | |
dst[i + offset] = src[i] | |
} | |
return i | |
} | |
function isnan (val) { | |
return val !== val // eslint-disable-line no-self-compare | |
} | |
}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) | |
},{"base64-js":5,"ieee754":6,"isarray":7}],5:[function(require,module,exports){ | |
'use strict' | |
exports.toByteArray = toByteArray | |
exports.fromByteArray = fromByteArray | |
var lookup = [] | |
var revLookup = [] | |
var Arr = typeof Uint8Array !== 'undefined' ? Uint8Array : Array | |
function init () { | |
var code = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/' | |
for (var i = 0, len = code.length; i < len; ++i) { | |
lookup[i] = code[i] | |
revLookup[code.charCodeAt(i)] = i | |
} | |
revLookup['-'.charCodeAt(0)] = 62 | |
revLookup['_'.charCodeAt(0)] = 63 | |
} | |
init() | |
function toByteArray (b64) { | |
var i, j, l, tmp, placeHolders, arr | |
var len = b64.length | |
if (len % 4 > 0) { | |
throw new Error('Invalid string. Length must be a multiple of 4') | |
} | |
// the number of equal signs (place holders) | |
// if there are two placeholders, than the two characters before it | |
// represent one byte | |
// if there is only one, then the three characters before it represent 2 bytes | |
// this is just a cheap hack to not do indexOf twice | |
placeHolders = b64[len - 2] === '=' ? 2 : b64[len - 1] === '=' ? 1 : 0 | |
// base64 is 4/3 + up to two characters of the original data | |
arr = new Arr(len * 3 / 4 - placeHolders) | |
// if there are placeholders, only get up to the last complete 4 chars | |
l = placeHolders > 0 ? len - 4 : len | |
var L = 0 | |
for (i = 0, j = 0; i < l; i += 4, j += 3) { | |
tmp = (revLookup[b64.charCodeAt(i)] << 18) | (revLookup[b64.charCodeAt(i + 1)] << 12) | (revLookup[b64.charCodeAt(i + 2)] << 6) | revLookup[b64.charCodeAt(i + 3)] | |
arr[L++] = (tmp >> 16) & 0xFF | |
arr[L++] = (tmp >> 8) & 0xFF | |
arr[L++] = tmp & 0xFF | |
} | |
if (placeHolders === 2) { | |
tmp = (revLookup[b64.charCodeAt(i)] << 2) | (revLookup[b64.charCodeAt(i + 1)] >> 4) | |
arr[L++] = tmp & 0xFF | |
} else if (placeHolders === 1) { | |
tmp = (revLookup[b64.charCodeAt(i)] << 10) | (revLookup[b64.charCodeAt(i + 1)] << 4) | (revLookup[b64.charCodeAt(i + 2)] >> 2) | |
arr[L++] = (tmp >> 8) & 0xFF | |
arr[L++] = tmp & 0xFF | |
} | |
return arr | |
} | |
function tripletToBase64 (num) { | |
return lookup[num >> 18 & 0x3F] + lookup[num >> 12 & 0x3F] + lookup[num >> 6 & 0x3F] + lookup[num & 0x3F] | |
} | |
function encodeChunk (uint8, start, end) { | |
var tmp | |
var output = [] | |
for (var i = start; i < end; i += 3) { | |
tmp = (uint8[i] << 16) + (uint8[i + 1] << 8) + (uint8[i + 2]) | |
output.push(tripletToBase64(tmp)) | |
} | |
return output.join('') | |
} | |
function fromByteArray (uint8) { | |
var tmp | |
var len = uint8.length | |
var extraBytes = len % 3 // if we have 1 byte left, pad 2 bytes | |
var output = '' | |
var parts = [] | |
var maxChunkLength = 16383 // must be multiple of 3 | |
// go through the array every three bytes, we'll deal with trailing stuff later | |
for (var i = 0, len2 = len - extraBytes; i < len2; i += maxChunkLength) { | |
parts.push(encodeChunk(uint8, i, (i + maxChunkLength) > len2 ? len2 : (i + maxChunkLength))) | |
} | |
// pad the end with zeros, but make sure to not forget the extra bytes | |
if (extraBytes === 1) { | |
tmp = uint8[len - 1] | |
output += lookup[tmp >> 2] | |
output += lookup[(tmp << 4) & 0x3F] | |
output += '==' | |
} else if (extraBytes === 2) { | |
tmp = (uint8[len - 2] << 8) + (uint8[len - 1]) | |
output += lookup[tmp >> 10] | |
output += lookup[(tmp >> 4) & 0x3F] | |
output += lookup[(tmp << 2) & 0x3F] | |
output += '=' | |
} | |
parts.push(output) | |
return parts.join('') | |
} | |
},{}],6:[function(require,module,exports){ | |
exports.read = function (buffer, offset, isLE, mLen, nBytes) { | |
var e, m | |
var eLen = nBytes * 8 - mLen - 1 | |
var eMax = (1 << eLen) - 1 | |
var eBias = eMax >> 1 | |
var nBits = -7 | |
var i = isLE ? (nBytes - 1) : 0 | |
var d = isLE ? -1 : 1 | |
var s = buffer[offset + i] | |
i += d | |
e = s & ((1 << (-nBits)) - 1) | |
s >>= (-nBits) | |
nBits += eLen | |
for (; nBits > 0; e = e * 256 + buffer[offset + i], i += d, nBits -= 8) {} | |
m = e & ((1 << (-nBits)) - 1) | |
e >>= (-nBits) | |
nBits += mLen | |
for (; nBits > 0; m = m * 256 + buffer[offset + i], i += d, nBits -= 8) {} | |
if (e === 0) { | |
e = 1 - eBias | |
} else if (e === eMax) { | |
return m ? NaN : ((s ? -1 : 1) * Infinity) | |
} else { | |
m = m + Math.pow(2, mLen) | |
e = e - eBias | |
} | |
return (s ? -1 : 1) * m * Math.pow(2, e - mLen) | |
} | |
exports.write = function (buffer, value, offset, isLE, mLen, nBytes) { | |
var e, m, c | |
var eLen = nBytes * 8 - mLen - 1 | |
var eMax = (1 << eLen) - 1 | |
var eBias = eMax >> 1 | |
var rt = (mLen === 23 ? Math.pow(2, -24) - Math.pow(2, -77) : 0) | |
var i = isLE ? 0 : (nBytes - 1) | |
var d = isLE ? 1 : -1 | |
var s = value < 0 || (value === 0 && 1 / value < 0) ? 1 : 0 | |
value = Math.abs(value) | |
if (isNaN(value) || value === Infinity) { | |
m = isNaN(value) ? 1 : 0 | |
e = eMax | |
} else { | |
e = Math.floor(Math.log(value) / Math.LN2) | |
if (value * (c = Math.pow(2, -e)) < 1) { | |
e-- | |
c *= 2 | |
} | |
if (e + eBias >= 1) { | |
value += rt / c | |
} else { | |
value += rt * Math.pow(2, 1 - eBias) | |
} | |
if (value * c >= 2) { | |
e++ | |
c /= 2 | |
} | |
if (e + eBias >= eMax) { | |
m = 0 | |
e = eMax | |
} else if (e + eBias >= 1) { | |
m = (value * c - 1) * Math.pow(2, mLen) | |
e = e + eBias | |
} else { | |
m = value * Math.pow(2, eBias - 1) * Math.pow(2, mLen) | |
e = 0 | |
} | |
} | |
for (; mLen >= 8; buffer[offset + i] = m & 0xff, i += d, m /= 256, mLen -= 8) {} | |
e = (e << mLen) | m | |
eLen += mLen | |
for (; eLen > 0; buffer[offset + i] = e & 0xff, i += d, e /= 256, eLen -= 8) {} | |
buffer[offset + i - d] |= s * 128 | |
} | |
},{}],7:[function(require,module,exports){ | |
var toString = {}.toString; | |
module.exports = Array.isArray || function (arr) { | |
return toString.call(arr) == '[object Array]'; | |
}; | |
},{}],8:[function(require,module,exports){ | |
// Copyright Joyent, Inc. and other Node contributors. | |
// | |
// Permission is hereby granted, free of charge, to any person obtaining a | |
// copy of this software and associated documentation files (the | |
// "Software"), to deal in the Software without restriction, including | |
// without limitation the rights to use, copy, modify, merge, publish, | |
// distribute, sublicense, and/or sell copies of the Software, and to permit | |
// persons to whom the Software is furnished to do so, subject to the | |
// following conditions: | |
// | |
// The above copyright notice and this permission notice shall be included | |
// in all copies or substantial portions of the Software. | |
// | |
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS | |
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | |
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN | |
// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, | |
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR | |
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE | |
// USE OR OTHER DEALINGS IN THE SOFTWARE. | |
function EventEmitter() { | |
this._events = this._events || {}; | |
this._maxListeners = this._maxListeners || undefined; | |
} | |
module.exports = EventEmitter; | |
// Backwards-compat with node 0.10.x | |
EventEmitter.EventEmitter = EventEmitter; | |
EventEmitter.prototype._events = undefined; | |
EventEmitter.prototype._maxListeners = undefined; | |
// By default EventEmitters will print a warning if more than 10 listeners are | |
// added to it. This is a useful default which helps finding memory leaks. | |
EventEmitter.defaultMaxListeners = 10; | |
// Obviously not all Emitters should be limited to 10. This function allows | |
// that to be increased. Set to zero for unlimited. | |
EventEmitter.prototype.setMaxListeners = function(n) { | |
if (!isNumber(n) || n < 0 || isNaN(n)) | |
throw TypeError('n must be a positive number'); | |
this._maxListeners = n; | |
return this; | |
}; | |
EventEmitter.prototype.emit = function(type) { | |
var er, handler, len, args, i, listeners; | |
if (!this._events) | |
this._events = {}; | |
// If there is no 'error' event listener then throw. | |
if (type === 'error') { | |
if (!this._events.error || | |
(isObject(this._events.error) && !this._events.error.length)) { | |
er = arguments[1]; | |
if (er instanceof Error) { | |
throw er; // Unhandled 'error' event | |
} else { | |
// At least give some kind of context to the user | |
var err = new Error('Uncaught, unspecified "error" event. (' + er + ')'); | |
err.context = er; | |
throw err; | |
} | |
} | |
} | |
handler = this._events[type]; | |
if (isUndefined(handler)) | |
return false; | |
if (isFunction(handler)) { | |
switch (arguments.length) { | |
// fast cases | |
case 1: | |
handler.call(this); | |
break; | |
case 2: | |
handler.call(this, arguments[1]); | |
break; | |
case 3: | |
handler.call(this, arguments[1], arguments[2]); | |
break; | |
// slower | |
default: | |
args = Array.prototype.slice.call(arguments, 1); | |
handler.apply(this, args); | |
} | |
} else if (isObject(handler)) { | |
args = Array.prototype.slice.call(arguments, 1); | |
listeners = handler.slice(); | |
len = listeners.length; | |
for (i = 0; i < len; i++) | |
listeners[i].apply(this, args); | |
} | |
return true; | |
}; | |
EventEmitter.prototype.addListener = function(type, listener) { | |
var m; | |
if (!isFunction(listener)) | |
throw TypeError('listener must be a function'); | |
if (!this._events) | |
this._events = {}; | |
// To avoid recursion in the case that type === "newListener"! Before | |
// adding it to the listeners, first emit "newListener". | |
if (this._events.newListener) | |
this.emit('newListener', type, | |
isFunction(listener.listener) ? | |
listener.listener : listener); | |
if (!this._events[type]) | |
// Optimize the case of one listener. Don't need the extra array object. | |
this._events[type] = listener; | |
else if (isObject(this._events[type])) | |
// If we've already got an array, just append. | |
this._events[type].push(listener); | |
else | |
// Adding the second element, need to change to array. | |
this._events[type] = [this._events[type], listener]; | |
// Check for listener leak | |
if (isObject(this._events[type]) && !this._events[type].warned) { | |
if (!isUndefined(this._maxListeners)) { | |
m = this._maxListeners; | |
} else { | |
m = EventEmitter.defaultMaxListeners; | |
} | |
if (m && m > 0 && this._events[type].length > m) { | |
this._events[type].warned = true; | |
console.error('(node) warning: possible EventEmitter memory ' + | |
'leak detected. %d listeners added. ' + | |
'Use emitter.setMaxListeners() to increase limit.', | |
this._events[type].length); | |
if (typeof console.trace === 'function') { | |
// not supported in IE 10 | |
console.trace(); | |
} | |
} | |
} | |
return this; | |
}; | |
EventEmitter.prototype.on = EventEmitter.prototype.addListener; | |
EventEmitter.prototype.once = function(type, listener) { | |
if (!isFunction(listener)) | |
throw TypeError('listener must be a function'); | |
var fired = false; | |
function g() { | |
this.removeListener(type, g); | |
if (!fired) { | |
fired = true; | |
listener.apply(this, arguments); | |
} | |
} | |
g.listener = listener; | |
this.on(type, g); | |
return this; | |
}; | |
// emits a 'removeListener' event iff the listener was removed | |
EventEmitter.prototype.removeListener = function(type, listener) { | |
var list, position, length, i; | |
if (!isFunction(listener)) | |
throw TypeError('listener must be a function'); | |
if (!this._events || !this._events[type]) | |
return this; | |
list = this._events[type]; | |
length = list.length; | |
position = -1; | |
if (list === listener || | |
(isFunction(list.listener) && list.listener === listener)) { | |
delete this._events[type]; | |
if (this._events.removeListener) | |
this.emit('removeListener', type, listener); | |
} else if (isObject(list)) { | |
for (i = length; i-- > 0;) { | |
if (list[i] === listener || | |
(list[i].listener && list[i].listener === listener)) { | |
position = i; | |
break; | |
} | |
} | |
if (position < 0) | |
return this; | |
if (list.length === 1) { | |
list.length = 0; | |
delete this._events[type]; | |
} else { | |
list.splice(position, 1); | |
} | |
if (this._events.removeListener) | |
this.emit('removeListener', type, listener); | |
} | |
return this; | |
}; | |
EventEmitter.prototype.removeAllListeners = function(type) { | |
var key, listeners; | |
if (!this._events) | |
return this; | |
// not listening for removeListener, no need to emit | |
if (!this._events.removeListener) { | |
if (arguments.length === 0) | |
this._events = {}; | |
else if (this._events[type]) | |
delete this._events[type]; | |
return this; | |
} | |
// emit removeListener for all listeners on all events | |
if (arguments.length === 0) { | |
for (key in this._events) { | |
if (key === 'removeListener') continue; | |
this.removeAllListeners(key); | |
} | |
this.removeAllListeners('removeListener'); | |
this._events = {}; | |
return this; | |
} | |
listeners = this._events[type]; | |
if (isFunction(listeners)) { | |
this.removeListener(type, listeners); | |
} else if (listeners) { | |
// LIFO order | |
while (listeners.length) | |
this.removeListener(type, listeners[listeners.length - 1]); | |
} | |
delete this._events[type]; | |
return this; | |
}; | |
EventEmitter.prototype.listeners = function(type) { | |
var ret; | |
if (!this._events || !this._events[type]) | |
ret = []; | |
else if (isFunction(this._events[type])) | |
ret = [this._events[type]]; | |
else | |
ret = this._events[type].slice(); | |
return ret; | |
}; | |
EventEmitter.prototype.listenerCount = function(type) { | |
if (this._events) { | |
var evlistener = this._events[type]; | |
if (isFunction(evlistener)) | |
return 1; | |
else if (evlistener) | |
return evlistener.length; | |
} | |
return 0; | |
}; | |
EventEmitter.listenerCount = function(emitter, type) { | |
return emitter.listenerCount(type); | |
}; | |
function isFunction(arg) { | |
return typeof arg === 'function'; | |
} | |
function isNumber(arg) { | |
return typeof arg === 'number'; | |
} | |
function isObject(arg) { | |
return typeof arg === 'object' && arg !== null; | |
} | |
function isUndefined(arg) { | |
return arg === void 0; | |
} | |
},{}],9:[function(require,module,exports){ | |
if (typeof Object.create === 'function') { | |
// implementation from standard node.js 'util' module | |
module.exports = function inherits(ctor, superCtor) { | |
ctor.super_ = superCtor | |
ctor.prototype = Object.create(superCtor.prototype, { | |
constructor: { | |
value: ctor, | |
enumerable: false, | |
writable: true, | |
configurable: true | |
} | |
}); | |
}; | |
} else { | |
// old school shim for old browsers | |
module.exports = function inherits(ctor, superCtor) { | |
ctor.super_ = superCtor | |
var TempCtor = function () {} | |
TempCtor.prototype = superCtor.prototype | |
ctor.prototype = new TempCtor() | |
ctor.prototype.constructor = ctor | |
} | |
} | |
},{}],10:[function(require,module,exports){ | |
/** | |
* Determine if an object is Buffer | |
* | |
* Author: Feross Aboukhadijeh <feross@feross.org> <http://feross.org> | |
* License: MIT | |
* | |
* `npm install is-buffer` | |
*/ | |
module.exports = function (obj) { | |
return !!(obj != null && | |
(obj._isBuffer || // For Safari 5-7 (missing Object.prototype.constructor) | |
(obj.constructor && | |
typeof obj.constructor.isBuffer === 'function' && | |
obj.constructor.isBuffer(obj)) | |
)) | |
} | |
},{}],11:[function(require,module,exports){ | |
exports.endianness = function () { return 'LE' }; | |
exports.hostname = function () { | |
if (typeof location !== 'undefined') { | |
return location.hostname | |
} | |
else return ''; | |
}; | |
exports.loadavg = function () { return [] }; | |
exports.uptime = function () { return 0 }; | |
exports.freemem = function () { | |
return Number.MAX_VALUE; | |
}; | |
exports.totalmem = function () { | |
return Number.MAX_VALUE; | |
}; | |
exports.cpus = function () { return [] }; | |
exports.type = function () { return 'Browser' }; | |
exports.release = function () { | |
if (typeof navigator !== 'undefined') { | |
return navigator.appVersion; | |
} | |
return ''; | |
}; | |
exports.networkInterfaces | |
= exports.getNetworkInterfaces | |
= function () { return {} }; | |
exports.arch = function () { return 'javascript' }; | |
exports.platform = function () { return 'browser' }; | |
exports.tmpdir = exports.tmpDir = function () { | |
return '/tmp'; | |
}; | |
exports.EOL = '\n'; | |
},{}],12:[function(require,module,exports){ | |
(function (process){ | |
// Copyright Joyent, Inc. and other Node contributors. | |
// | |
// Permission is hereby granted, free of charge, to any person obtaining a | |
// copy of this software and associated documentation files (the | |
// "Software"), to deal in the Software without restriction, including | |
// without limitation the rights to use, copy, modify, merge, publish, | |
// distribute, sublicense, and/or sell copies of the Software, and to permit | |
// persons to whom the Software is furnished to do so, subject to the | |
// following conditions: | |
// | |
// The above copyright notice and this permission notice shall be included | |
// in all copies or substantial portions of the Software. | |
// | |
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS | |
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | |
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN | |
// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, | |
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR | |
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE | |
// USE OR OTHER DEALINGS IN THE SOFTWARE. | |
// resolves . and .. elements in a path array with directory names there | |
// must be no slashes, empty elements, or device names (c:\) in the array | |
// (so also no leading and trailing slashes - it does not distinguish | |
// relative and absolute paths) | |
function normalizeArray(parts, allowAboveRoot) { | |
// if the path tries to go above the root, `up` ends up > 0 | |
var up = 0; | |
for (var i = parts.length - 1; i >= 0; i--) { | |
var last = parts[i]; | |
if (last === '.') { | |
parts.splice(i, 1); | |
} else if (last === '..') { | |
parts.splice(i, 1); | |
up++; | |
} else if (up) { | |
parts.splice(i, 1); | |
up--; | |
} | |
} | |
// if the path is allowed to go above the root, restore leading ..s | |
if (allowAboveRoot) { | |
for (; up--; up) { | |
parts.unshift('..'); | |
} | |
} | |
return parts; | |
} | |
// Split a filename into [root, dir, basename, ext], unix version | |
// 'root' is just a slash, or nothing. | |
var splitPathRe = | |
/^(\/?|)([\s\S]*?)((?:\.{1,2}|[^\/]+?|)(\.[^.\/]*|))(?:[\/]*)$/; | |
var splitPath = function(filename) { | |
return splitPathRe.exec(filename).slice(1); | |
}; | |
// path.resolve([from ...], to) | |
// posix version | |
exports.resolve = function() { | |
var resolvedPath = '', | |
resolvedAbsolute = false; | |
for (var i = arguments.length - 1; i >= -1 && !resolvedAbsolute; i--) { | |
var path = (i >= 0) ? arguments[i] : process.cwd(); | |
// Skip empty and invalid entries | |
if (typeof path !== 'string') { | |
throw new TypeError('Arguments to path.resolve must be strings'); | |
} else if (!path) { | |
continue; | |
} | |
resolvedPath = path + '/' + resolvedPath; | |
resolvedAbsolute = path.charAt(0) === '/'; | |
} | |
// At this point the path should be resolved to a full absolute path, but | |
// handle relative paths to be safe (might happen when process.cwd() fails) | |
// Normalize the path | |
resolvedPath = normalizeArray(filter(resolvedPath.split('/'), function(p) { | |
return !!p; | |
}), !resolvedAbsolute).join('/'); | |
return ((resolvedAbsolute ? '/' : '') + resolvedPath) || '.'; | |
}; | |
// path.normalize(path) | |
// posix version | |
exports.normalize = function(path) { | |
var isAbsolute = exports.isAbsolute(path), | |
trailingSlash = substr(path, -1) === '/'; | |
// Normalize the path | |
path = normalizeArray(filter(path.split('/'), function(p) { | |
return !!p; | |
}), !isAbsolute).join('/'); | |
if (!path && !isAbsolute) { | |
path = '.'; | |
} | |
if (path && trailingSlash) { | |
path += '/'; | |
} | |
return (isAbsolute ? '/' : '') + path; | |
}; | |
// posix version | |
exports.isAbsolute = function(path) { | |
return path.charAt(0) === '/'; | |
}; | |
// posix version | |
exports.join = function() { | |
var paths = Array.prototype.slice.call(arguments, 0); | |
return exports.normalize(filter(paths, function(p, index) { | |
if (typeof p !== 'string') { | |
throw new TypeError('Arguments to path.join must be strings'); | |
} | |
return p; | |
}).join('/')); | |
}; | |
// path.relative(from, to) | |
// posix version | |
exports.relative = function(from, to) { | |
from = exports.resolve(from).substr(1); | |
to = exports.resolve(to).substr(1); | |
function trim(arr) { | |
var start = 0; | |
for (; start < arr.length; start++) { | |
if (arr[start] !== '') break; | |
} | |
var end = arr.length - 1; | |
for (; end >= 0; end--) { | |
if (arr[end] !== '') break; | |
} | |
if (start > end) return []; | |
return arr.slice(start, end - start + 1); | |
} | |
var fromParts = trim(from.split('/')); | |
var toParts = trim(to.split('/')); | |
var length = Math.min(fromParts.length, toParts.length); | |
var samePartsLength = length; | |
for (var i = 0; i < length; i++) { | |
if (fromParts[i] !== toParts[i]) { | |
samePartsLength = i; | |
break; | |
} | |
} | |
var outputParts = []; | |
for (var i = samePartsLength; i < fromParts.length; i++) { | |
outputParts.push('..'); | |
} | |
outputParts = outputParts.concat(toParts.slice(samePartsLength)); | |
return outputParts.join('/'); | |
}; | |
exports.sep = '/'; | |
exports.delimiter = ':'; | |
exports.dirname = function(path) { | |
var result = splitPath(path), | |
root = result[0], | |
dir = result[1]; | |
if (!root && !dir) { | |
// No dirname whatsoever | |
return '.'; | |
} | |
if (dir) { | |
// It has a dirname, strip trailing slash | |
dir = dir.substr(0, dir.length - 1); | |
} | |
return root + dir; | |
}; | |
exports.basename = function(path, ext) { | |
var f = splitPath(path)[2]; | |
// TODO: make this comparison case-insensitive on windows? | |
if (ext && f.substr(-1 * ext.length) === ext) { | |
f = f.substr(0, f.length - ext.length); | |
} | |
return f; | |
}; | |
exports.extname = function(path) { | |
return splitPath(path)[3]; | |
}; | |
function filter (xs, f) { | |
if (xs.filter) return xs.filter(f); | |
var res = []; | |
for (var i = 0; i < xs.length; i++) { | |
if (f(xs[i], i, xs)) res.push(xs[i]); | |
} | |
return res; | |
} | |
// String.prototype.substr - negative index don't work in IE8 | |
var substr = 'ab'.substr(-1) === 'b' | |
? function (str, start, len) { return str.substr(start, len) } | |
: function (str, start, len) { | |
if (start < 0) start = str.length + start; | |
return str.substr(start, len); | |
} | |
; | |
}).call(this,require('_process')) | |
},{"_process":13}],13:[function(require,module,exports){ | |
// shim for using process in browser | |
var process = module.exports = {}; | |
// cached from whatever global is present so that test runners that stub it | |
// don't break things. But we need to wrap it in a try catch in case it is | |
// wrapped in strict mode code which doesn't define any globals. It's inside a | |
// function because try/catches deoptimize in certain engines. | |
var cachedSetTimeout; | |
var cachedClearTimeout; | |
(function () { | |
try { | |
cachedSetTimeout = setTimeout; | |
} catch (e) { | |
cachedSetTimeout = function () { | |
throw new Error('setTimeout is not defined'); | |
} | |
} | |
try { | |
cachedClearTimeout = clearTimeout; | |
} catch (e) { | |
cachedClearTimeout = function () { | |
throw new Error('clearTimeout is not defined'); | |
} | |
} | |
} ()) | |
function runTimeout(fun) { | |
if (cachedSetTimeout === setTimeout) { | |
return setTimeout(fun, 0); | |
} else { | |
return cachedSetTimeout.call(null, fun, 0); | |
} | |
} | |
function runClearTimeout(marker) { | |
if (cachedClearTimeout === clearTimeout) { | |
clearTimeout(marker); | |
} else { | |
cachedClearTimeout.call(null, marker); | |
} | |
} | |
var queue = []; | |
var draining = false; | |
var currentQueue; | |
var queueIndex = -1; | |
function cleanUpNextTick() { | |
if (!draining || !currentQueue) { | |
return; | |
} | |
draining = false; | |
if (currentQueue.length) { | |
queue = currentQueue.concat(queue); | |
} else { | |
queueIndex = -1; | |
} | |
if (queue.length) { | |
drainQueue(); | |
} | |
} | |
function drainQueue() { | |
if (draining) { | |
return; | |
} | |
var timeout = runTimeout(cleanUpNextTick); | |
draining = true; | |
var len = queue.length; | |
while(len) { | |
currentQueue = queue; | |
queue = []; | |
while (++queueIndex < len) { | |
if (currentQueue) { | |
currentQueue[queueIndex].run(); | |
} | |
} | |
queueIndex = -1; | |
len = queue.length; | |
} | |
currentQueue = null; | |
draining = false; | |
runClearTimeout(timeout); | |
} | |
process.nextTick = function (fun) { | |
var args = new Array(arguments.length - 1); | |
if (arguments.length > 1) { | |
for (var i = 1; i < arguments.length; i++) { | |
args[i - 1] = arguments[i]; | |
} | |
} | |
queue.push(new Item(fun, args)); | |
if (queue.length === 1 && !draining) { | |
runTimeout(drainQueue); | |
} | |
}; | |
// v8 likes predictible objects | |
function Item(fun, array) { | |
this.fun = fun; | |
this.array = array; | |
} | |
Item.prototype.run = function () { | |
this.fun.apply(null, this.array); | |
}; | |
process.title = 'browser'; | |
process.browser = true; | |
process.env = {}; | |
process.argv = []; | |
process.version = ''; // empty string to avoid regexp issues | |
process.versions = {}; | |
function noop() {} | |
process.on = noop; | |
process.addListener = noop; | |
process.once = noop; | |
process.off = noop; | |
process.removeListener = noop; | |
process.removeAllListeners = noop; | |
process.emit = noop; | |
process.binding = function (name) { | |
throw new Error('process.binding is not supported'); | |
}; | |
process.cwd = function () { return '/' }; | |
process.chdir = function (dir) { | |
throw new Error('process.chdir is not supported'); | |
}; | |
process.umask = function() { return 0; }; | |
},{}],14:[function(require,module,exports){ | |
module.exports = function isBuffer(arg) { | |
return arg && typeof arg === 'object' | |
&& typeof arg.copy === 'function' | |
&& typeof arg.fill === 'function' | |
&& typeof arg.readUInt8 === 'function'; | |
} | |
},{}],15:[function(require,module,exports){ | |
(function (process,global){ | |
// Copyright Joyent, Inc. and other Node contributors. | |
// | |
// Permission is hereby granted, free of charge, to any person obtaining a | |
// copy of this software and associated documentation files (the | |
// "Software"), to deal in the Software without restriction, including | |
// without limitation the rights to use, copy, modify, merge, publish, | |
// distribute, sublicense, and/or sell copies of the Software, and to permit | |
// persons to whom the Software is furnished to do so, subject to the | |
// following conditions: | |
// | |
// The above copyright notice and this permission notice shall be included | |
// in all copies or substantial portions of the Software. | |
// | |
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS | |
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | |
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN | |
// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, | |
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR | |
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE | |
// USE OR OTHER DEALINGS IN THE SOFTWARE. | |
var formatRegExp = /%[sdj%]/g; | |
exports.format = function(f) { | |
if (!isString(f)) { | |
var objects = []; | |
for (var i = 0; i < arguments.length; i++) { | |
objects.push(inspect(arguments[i])); | |
} | |
return objects.join(' '); | |
} | |
var i = 1; | |
var args = arguments; | |
var len = args.length; | |
var str = String(f).replace(formatRegExp, function(x) { | |
if (x === '%%') return '%'; | |
if (i >= len) return x; | |
switch (x) { | |
case '%s': return String(args[i++]); | |
case '%d': return Number(args[i++]); | |
case '%j': | |
try { | |
return JSON.stringify(args[i++]); | |
} catch (_) { | |
return '[Circular]'; | |
} | |
default: | |
return x; | |
} | |
}); | |
for (var x = args[i]; i < len; x = args[++i]) { | |
if (isNull(x) || !isObject(x)) { | |
str += ' ' + x; | |
} else { | |
str += ' ' + inspect(x); | |
} | |
} | |
return str; | |
}; | |
// Mark that a method should not be used. | |
// Returns a modified function which warns once by default. | |
// If --no-deprecation is set, then it is a no-op. | |
exports.deprecate = function(fn, msg) { | |
// Allow for deprecating things in the process of starting up. | |
if (isUndefined(global.process)) { | |
return function() { | |
return exports.deprecate(fn, msg).apply(this, arguments); | |
}; | |
} | |
if (process.noDeprecation === true) { | |
return fn; | |
} | |
var warned = false; | |
function deprecated() { | |
if (!warned) { | |
if (process.throwDeprecation) { | |
throw new Error(msg); | |
} else if (process.traceDeprecation) { | |
console.trace(msg); | |
} else { | |
console.error(msg); | |
} | |
warned = true; | |
} | |
return fn.apply(this, arguments); | |
} | |
return deprecated; | |
}; | |
var debugs = {}; | |
var debugEnviron; | |
exports.debuglog = function(set) { | |
if (isUndefined(debugEnviron)) | |
debugEnviron = process.env.NODE_DEBUG || ''; | |
set = set.toUpperCase(); | |
if (!debugs[set]) { | |
if (new RegExp('\\b' + set + '\\b', 'i').test(debugEnviron)) { | |
var pid = process.pid; | |
debugs[set] = function() { | |
var msg = exports.format.apply(exports, arguments); | |
console.error('%s %d: %s', set, pid, msg); | |
}; | |
} else { | |
debugs[set] = function() {}; | |
} | |
} | |
return debugs[set]; | |
}; | |
/** | |
* Echos the value of a value. Trys to print the value out | |
* in the best way possible given the different types. | |
* | |
* @param {Object} obj The object to print out. | |
* @param {Object} opts Optional options object that alters the output. | |
*/ | |
/* legacy: obj, showHidden, depth, colors*/ | |
function inspect(obj, opts) { | |
// default options | |
var ctx = { | |
seen: [], | |
stylize: stylizeNoColor | |
}; | |
// legacy... | |
if (arguments.length >= 3) ctx.depth = arguments[2]; | |
if (arguments.length >= 4) ctx.colors = arguments[3]; | |
if (isBoolean(opts)) { | |
// legacy... | |
ctx.showHidden = opts; | |
} else if (opts) { | |
// got an "options" object | |
exports._extend(ctx, opts); | |
} | |
// set default options | |
if (isUndefined(ctx.showHidden)) ctx.showHidden = false; | |
if (isUndefined(ctx.depth)) ctx.depth = 2; | |
if (isUndefined(ctx.colors)) ctx.colors = false; | |
if (isUndefined(ctx.customInspect)) ctx.customInspect = true; | |
if (ctx.colors) ctx.stylize = stylizeWithColor; | |
return formatValue(ctx, obj, ctx.depth); | |
} | |
exports.inspect = inspect; | |
// http://en.wikipedia.org/wiki/ANSI_escape_code#graphics | |
inspect.colors = { | |
'bold' : [1, 22], | |
'italic' : [3, 23], | |
'underline' : [4, 24], | |
'inverse' : [7, 27], | |
'white' : [37, 39], | |
'grey' : [90, 39], | |
'black' : [30, 39], | |
'blue' : [34, 39], | |
'cyan' : [36, 39], | |
'green' : [32, 39], | |
'magenta' : [35, 39], | |
'red' : [31, 39], | |
'yellow' : [33, 39] | |
}; | |
// Don't use 'blue' not visible on cmd.exe | |
inspect.styles = { | |
'special': 'cyan', | |
'number': 'yellow', | |
'boolean': 'yellow', | |
'undefined': 'grey', | |
'null': 'bold', | |
'string': 'green', | |
'date': 'magenta', | |
// "name": intentionally not styling | |
'regexp': 'red' | |
}; | |
function stylizeWithColor(str, styleType) { | |
var style = inspect.styles[styleType]; | |
if (style) { | |
return '\u001b[' + inspect.colors[style][0] + 'm' + str + | |
'\u001b[' + inspect.colors[style][1] + 'm'; | |
} else { | |
return str; | |
} | |
} | |
function stylizeNoColor(str, styleType) { | |
return str; | |
} | |
function arrayToHash(array) { | |
var hash = {}; | |
array.forEach(function(val, idx) { | |
hash[val] = true; | |
}); | |
return hash; | |
} | |
function formatValue(ctx, value, recurseTimes) { | |
// Provide a hook for user-specified inspect functions. | |
// Check that value is an object with an inspect function on it | |
if (ctx.customInspect && | |
value && | |
isFunction(value.inspect) && | |
// Filter out the util module, it's inspect function is special | |
value.inspect !== exports.inspect && | |
// Also filter out any prototype objects using the circular check. | |
!(value.constructor && value.constructor.prototype === value)) { | |
var ret = value.inspect(recurseTimes, ctx); | |
if (!isString(ret)) { | |
ret = formatValue(ctx, ret, recurseTimes); | |
} | |
return ret; | |
} | |
// Primitive types cannot have properties | |
var primitive = formatPrimitive(ctx, value); | |
if (primitive) { | |
return primitive; | |
} | |
// Look up the keys of the object. | |
var keys = Object.keys(value); | |
var visibleKeys = arrayToHash(keys); | |
if (ctx.showHidden) { | |
keys = Object.getOwnPropertyNames(value); | |
} | |
// IE doesn't make error fields non-enumerable | |
// http://msdn.microsoft.com/en-us/library/ie/dww52sbt(v=vs.94).aspx | |
if (isError(value) | |
&& (keys.indexOf('message') >= 0 || keys.indexOf('description') >= 0)) { | |
return formatError(value); | |
} | |
// Some type of object without properties can be shortcutted. | |
if (keys.length === 0) { | |
if (isFunction(value)) { | |
var name = value.name ? ': ' + value.name : ''; | |
return ctx.stylize('[Function' + name + ']', 'special'); | |
} | |
if (isRegExp(value)) { | |
return ctx.stylize(RegExp.prototype.toString.call(value), 'regexp'); | |
} | |
if (isDate(value)) { | |
return ctx.stylize(Date.prototype.toString.call(value), 'date'); | |
} | |
if (isError(value)) { | |
return formatError(value); | |
} | |
} | |
var base = '', array = false, braces = ['{', '}']; | |
// Make Array say that they are Array | |
if (isArray(value)) { | |
array = true; | |
braces = ['[', ']']; | |
} | |
// Make functions say that they are functions | |
if (isFunction(value)) { | |
var n = value.name ? ': ' + value.name : ''; | |
base = ' [Function' + n + ']'; | |
} | |
// Make RegExps say that they are RegExps | |
if (isRegExp(value)) { | |
base = ' ' + RegExp.prototype.toString.call(value); | |
} | |
// Make dates with properties first say the date | |
if (isDate(value)) { | |
base = ' ' + Date.prototype.toUTCString.call(value); | |
} | |
// Make error with message first say the error | |
if (isError(value)) { | |
base = ' ' + formatError(value); | |
} | |
if (keys.length === 0 && (!array || value.length == 0)) { | |
return braces[0] + base + braces[1]; | |
} | |
if (recurseTimes < 0) { | |
if (isRegExp(value)) { | |
return ctx.stylize(RegExp.prototype.toString.call(value), 'regexp'); | |
} else { | |
return ctx.stylize('[Object]', 'special'); | |
} | |
} | |
ctx.seen.push(value); | |
var output; | |
if (array) { | |
output = formatArray(ctx, value, recurseTimes, visibleKeys, keys); | |
} else { | |
output = keys.map(function(key) { | |
return formatProperty(ctx, value, recurseTimes, visibleKeys, key, array); | |
}); | |
} | |
ctx.seen.pop(); | |
return reduceToSingleString(output, base, braces); | |
} | |
function formatPrimitive(ctx, value) { | |
if (isUndefined(value)) | |
return ctx.stylize('undefined', 'undefined'); | |
if (isString(value)) { | |
var simple = '\'' + JSON.stringify(value).replace(/^"|"$/g, '') | |
.replace(/'/g, "\\'") | |
.replace(/\\"/g, '"') + '\''; | |
return ctx.stylize(simple, 'string'); | |
} | |
if (isNumber(value)) | |
return ctx.stylize('' + value, 'number'); | |
if (isBoolean(value)) | |
return ctx.stylize('' + value, 'boolean'); | |
// For some reason typeof null is "object", so special case here. | |
if (isNull(value)) | |
return ctx.stylize('null', 'null'); | |
} | |
function formatError(value) { | |
return '[' + Error.prototype.toString.call(value) + ']'; | |
} | |
function formatArray(ctx, value, recurseTimes, visibleKeys, keys) { | |
var output = []; | |
for (var i = 0, l = value.length; i < l; ++i) { | |
if (hasOwnProperty(value, String(i))) { | |
output.push(formatProperty(ctx, value, recurseTimes, visibleKeys, | |
String(i), true)); | |
} else { | |
output.push(''); | |
} | |
} | |
keys.forEach(function(key) { | |
if (!key.match(/^\d+$/)) { | |
output.push(formatProperty(ctx, value, recurseTimes, visibleKeys, | |
key, true)); | |
} | |
}); | |
return output; | |
} | |
function formatProperty(ctx, value, recurseTimes, visibleKeys, key, array) { | |
var name, str, desc; | |
desc = Object.getOwnPropertyDescriptor(value, key) || { value: value[key] }; | |
if (desc.get) { | |
if (desc.set) { | |
str = ctx.stylize('[Getter/Setter]', 'special'); | |
} else { | |
str = ctx.stylize('[Getter]', 'special'); | |
} | |
} else { | |
if (desc.set) { | |
str = ctx.stylize('[Setter]', 'special'); | |
} | |
} | |
if (!hasOwnProperty(visibleKeys, key)) { | |
name = '[' + key + ']'; | |
} | |
if (!str) { | |
if (ctx.seen.indexOf(desc.value) < 0) { | |
if (isNull(recurseTimes)) { | |
str = formatValue(ctx, desc.value, null); | |
} else { | |
str = formatValue(ctx, desc.value, recurseTimes - 1); | |
} | |
if (str.indexOf('\n') > -1) { | |
if (array) { | |
str = str.split('\n').map(function(line) { | |
return ' ' + line; | |
}).join('\n').substr(2); | |
} else { | |
str = '\n' + str.split('\n').map(function(line) { | |
return ' ' + line; | |
}).join('\n'); | |
} | |
} | |
} else { | |
str = ctx.stylize('[Circular]', 'special'); | |
} | |
} | |
if (isUndefined(name)) { | |
if (array && key.match(/^\d+$/)) { | |
return str; | |
} | |
name = JSON.stringify('' + key); | |
if (name.match(/^"([a-zA-Z_][a-zA-Z_0-9]*)"$/)) { | |
name = name.substr(1, name.length - 2); | |
name = ctx.stylize(name, 'name'); | |
} else { | |
name = name.replace(/'/g, "\\'") | |
.replace(/\\"/g, '"') | |
.replace(/(^"|"$)/g, "'"); | |
name = ctx.stylize(name, 'string'); | |
} | |
} | |
return name + ': ' + str; | |
} | |
function reduceToSingleString(output, base, braces) { | |
var numLinesEst = 0; | |
var length = output.reduce(function(prev, cur) { | |
numLinesEst++; | |
if (cur.indexOf('\n') >= 0) numLinesEst++; | |
return prev + cur.replace(/\u001b\[\d\d?m/g, '').length + 1; | |
}, 0); | |
if (length > 60) { | |
return braces[0] + | |
(base === '' ? '' : base + '\n ') + | |
' ' + | |
output.join(',\n ') + | |
' ' + | |
braces[1]; | |
} | |
return braces[0] + base + ' ' + output.join(', ') + ' ' + braces[1]; | |
} | |
// NOTE: These type checking functions intentionally don't use `instanceof` | |
// because it is fragile and can be easily faked with `Object.create()`. | |
function isArray(ar) { | |
return Array.isArray(ar); | |
} | |
exports.isArray = isArray; | |
function isBoolean(arg) { | |
return typeof arg === 'boolean'; | |
} | |
exports.isBoolean = isBoolean; | |
function isNull(arg) { | |
return arg === null; | |
} | |
exports.isNull = isNull; | |
function isNullOrUndefined(arg) { | |
return arg == null; | |
} | |
exports.isNullOrUndefined = isNullOrUndefined; | |
function isNumber(arg) { | |
return typeof arg === 'number'; | |
} | |
exports.isNumber = isNumber; | |
function isString(arg) { | |
return typeof arg === 'string'; | |
} | |
exports.isString = isString; | |
function isSymbol(arg) { | |
return typeof arg === 'symbol'; | |
} | |
exports.isSymbol = isSymbol; | |
function isUndefined(arg) { | |
return arg === void 0; | |
} | |
exports.isUndefined = isUndefined; | |
function isRegExp(re) { | |
return isObject(re) && objectToString(re) === '[object RegExp]'; | |
} | |
exports.isRegExp = isRegExp; | |
function isObject(arg) { | |
return typeof arg === 'object' && arg !== null; | |
} | |
exports.isObject = isObject; | |
function isDate(d) { | |
return isObject(d) && objectToString(d) === '[object Date]'; | |
} | |
exports.isDate = isDate; | |
function isError(e) { | |
return isObject(e) && | |
(objectToString(e) === '[object Error]' || e instanceof Error); | |
} | |
exports.isError = isError; | |
function isFunction(arg) { | |
return typeof arg === 'function'; | |
} | |
exports.isFunction = isFunction; | |
function isPrimitive(arg) { | |
return arg === null || | |
typeof arg === 'boolean' || | |
typeof arg === 'number' || | |
typeof arg === 'string' || | |
typeof arg === 'symbol' || // ES6 symbol | |
typeof arg === 'undefined'; | |
} | |
exports.isPrimitive = isPrimitive; | |
exports.isBuffer = require('./support/isBuffer'); | |
function objectToString(o) { | |
return Object.prototype.toString.call(o); | |
} | |
function pad(n) { | |
return n < 10 ? '0' + n.toString(10) : n.toString(10); | |
} | |
var months = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', | |
'Oct', 'Nov', 'Dec']; | |
// 26 Feb 16:19:34 | |
function timestamp() { | |
var d = new Date(); | |
var time = [pad(d.getHours()), | |
pad(d.getMinutes()), | |
pad(d.getSeconds())].join(':'); | |
return [d.getDate(), months[d.getMonth()], time].join(' '); | |
} | |
// log is just a thin wrapper to console.log that prepends a timestamp | |
exports.log = function() { | |
console.log('%s - %s', timestamp(), exports.format.apply(exports, arguments)); | |
}; | |
/** | |
* Inherit the prototype methods from one constructor into another. | |
* | |
* The Function.prototype.inherits from lang.js rewritten as a standalone | |
* function (not on Function.prototype). NOTE: If this file is to be loaded | |
* during bootstrapping this function needs to be rewritten using some native | |
* functions as prototype setup using normal JavaScript does not work as | |
* expected during bootstrapping (see mirror.js in r114903). | |
* | |
* @param {function} ctor Constructor function which needs to inherit the | |
* prototype. | |
* @param {function} superCtor Constructor function to inherit prototype from. | |
*/ | |
exports.inherits = require('inherits'); | |
exports._extend = function(origin, add) { | |
// Don't do anything if add isn't an object | |
if (!add || !isObject(add)) return origin; | |
var keys = Object.keys(add); | |
var i = keys.length; | |
while (i--) { | |
origin[keys[i]] = add[keys[i]]; | |
} | |
return origin; | |
}; | |
function hasOwnProperty(obj, prop) { | |
return Object.prototype.hasOwnProperty.call(obj, prop); | |
} | |
}).call(this,require('_process'),typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) | |
},{"./support/isBuffer":14,"_process":13,"inherits":9}],16:[function(require,module,exports){ | |
// Copyright 2011 Timothy J Fontaine <tjfontaine@gmail.com> | |
// | |
// Permission is hereby granted, free of charge, to any person obtaining a copy | |
// of this software and associated documentation files (the "Software"), to deal | |
// in the Software without restriction, including without limitation the rights | |
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | |
// copies of the Software, and to permit persons to whom the Software is | |
// furnished to do so, subject to the following conditions: | |
// | |
// The above copyright notice and this permission notice shall be included in | |
// all copies or substantial portions of the Software. | |
// | |
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | |
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | |
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | |
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN | |
// THE SOFTWARE | |
"use strict"; | |
exports.platform = require('./lib/platform'); | |
exports.createServer = require('./lib/server').createServer; | |
exports.createUDPServer = require('./lib/server').createUDPServer; | |
exports.createTCPServer = require('./lib/server').createTCPServer; | |
var client = require('./lib/client'); | |
exports.lookup = client.lookup; | |
exports.resolve = client.resolve; | |
exports.resolve4 = client.resolve4; | |
exports.resolve6 = client.resolve6; | |
exports.resolveMx = client.resolveMx; | |
exports.resolveTxt = client.resolveTxt; | |
exports.resolveSrv = client.resolveSrv; | |
exports.resolveNs = client.resolveNs; | |
exports.resolveCname = client.resolveCname; | |
exports.reverse = client.reverse; | |
var consts = require('native-dns-packet').consts; | |
exports.BADNAME = consts.BADNAME; | |
exports.BADRESP = consts.BADRESP; | |
exports.CONNREFUSED = consts.CONNREFUSED; | |
exports.DESTRUCTION = consts.DESTRUCTION; | |
exports.REFUSED = consts.REFUSED; | |
exports.FORMERR = consts.FORMERR; | |
exports.NODATA = consts.NODATA; | |
exports.NOMEM = consts.NOMEM; | |
exports.NOTFOUND = consts.NOTFOUND; | |
exports.NOTIMP = consts.NOTIMP; | |
exports.SERVFAIL = consts.SERVFAIL; | |
exports.TIMEOUT = consts.TIMEOUT; | |
exports.consts = consts; | |
var definedTypes = [ | |
'A', | |
'AAAA', | |
'NS', | |
'CNAME', | |
'PTR', | |
'NAPTR', | |
'TXT', | |
'MX', | |
'SRV', | |
'SOA', | |
'TLSA', | |
].forEach(function (type) { | |
exports[type] = function (opts) { | |
var obj = {}; | |
opts = opts || {}; | |
obj.type = consts.nameToQtype(type); | |
obj.class = consts.NAME_TO_QCLASS.IN; | |
Object.keys(opts).forEach(function (k) { | |
if (opts.hasOwnProperty(k) && ['type', 'class'].indexOf(k) == -1) { | |
obj[k] = opts[k]; | |
} | |
}); | |
return obj; | |
}; | |
}); | |
exports.Question = function (opts) { | |
var q = {}, qtype; | |
opts = opts || {}; | |
q.name = opts.name; | |
qtype = opts.type || consts.NAME_TO_QTYPE.A; | |
if (typeof(qtype) === 'string' || qtype instanceof String) | |
qtype = consts.nameToQtype(qtype.toUpperCase()); | |
if (!qtype || typeof(qtype) !== 'number') | |
throw new Error("Question type must be defined and be valid"); | |
q.type = qtype; | |
q.class = opts.class || consts.NAME_TO_QCLASS.IN; | |
return q; | |
}; | |
exports.Request = client.Request; | |
},{"./lib/client":17,"./lib/platform":20,"./lib/server":21,"native-dns-packet":30}],17:[function(require,module,exports){ | |
(function (process){ | |
// Copyright 2011 Timothy J Fontaine <tjfontaine@gmail.com> | |
// | |
// Permission is hereby granted, free of charge, to any person obtaining a copy | |
// of this software and associated documentation files (the "Software"), to deal | |
// in the Software without restriction, including without limitation the rights | |
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | |
// copies of the Software, and to permit persons to whom the Software is | |
// furnished to do so, subject to the following conditions: | |
// | |
// The above copyright notice and this permission notice shall be included in | |
// all copies or substantial portions of the Software. | |
// | |
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | |
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | |
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | |
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN | |
// THE SOFTWARE | |
'use strict'; | |
var ipaddr = require('ipaddr.js'), | |
net = require('net'), | |
util = require('util'), | |
EventEmitter = require('events').EventEmitter, | |
PendingRequests = require('./pending'), | |
Packet = require('./packet'), | |
consts = require('native-dns-packet').consts, | |
utils = require('./utils'), | |
platform = require('./platform'); | |
var A = consts.NAME_TO_QTYPE.A, | |
AAAA = consts.NAME_TO_QTYPE.AAAA, | |
MX = consts.NAME_TO_QTYPE.MX, | |
TXT = consts.NAME_TO_QTYPE.TXT, | |
NS = consts.NAME_TO_QTYPE.NS, | |
CNAME = consts.NAME_TO_QTYPE.CNAME, | |
SRV = consts.NAME_TO_QTYPE.SRV, | |
PTR = consts.NAME_TO_QTYPE.PTR, | |
TLSA = consts.NAME_TO_QTYPE.TLSA; | |
var debug = function() {}; | |
if (process.env.NODE_DEBUG && process.env.NODE_DEBUG.match(/dns/)) { | |
debug = function debug() { | |
var args = Array.prototype.slice.call(arguments); | |
console.error.apply(this, ['client', Date.now().toString()].concat(args)); | |
}; | |
} | |
var Request = exports.Request = function(opts) { | |
if (!(this instanceof Request)) return new Request(opts); | |
this.question = opts.question; | |
this.server = opts.server; | |
if (typeof(this.server) === 'string' || this.server instanceof String) | |
this.server = { address: this.server, port: 53, type: 'udp'}; | |
if (!this.server || !this.server.address || !net.isIP(this.server.address)) | |
throw new Error('Server object must be supplied with at least address'); | |
if (!this.server.type || ['udp', 'tcp'].indexOf(this.server.type) === -1) | |
this.server.type = 'udp'; | |
if (!this.server.port) | |
this.server.port = 53; | |
this.timeout = opts.timeout || 4 * 1000; | |
this.try_edns = opts.try_edns || false; | |
this.fired = false; | |
this.id = undefined; | |
if (opts.cache || opts.cache === false) { | |
this.cache = opts.cache; | |
} else { | |
this.cache = platform.cache; | |
} | |
debug('request created', this.question); | |
}; | |
util.inherits(Request, EventEmitter); | |
Request.prototype.handle = function(err, answer, cached) { | |
if (!this.fired) { | |
debug('request handled', this.id, this.question); | |
if (!cached && this.cache && this.cache.store && answer) { | |
this.cache.store(answer); | |
} | |
this.emit('message', err, answer); | |
this.done(); | |
} | |
}; | |
Request.prototype.done = function() { | |
debug('request finished', this.id, this.question); | |
this.fired = true; | |
clearTimeout(this.timer_); | |
PendingRequests.remove(this); | |
this.emit('end'); | |
this.id = undefined; | |
}; | |
Request.prototype.handleTimeout = function() { | |
if (!this.fired) { | |
debug('request timedout', this.id, this.question); | |
this.emit('timeout'); | |
this.done(); | |
} | |
}; | |
Request.prototype.error = function(err) { | |
if (!this.fired) { | |
debug('request error', err, this.id, this.question); | |
this.emit('error', err); | |
this.done(); | |
} | |
}; | |
Request.prototype.send = function() { | |
debug('request starting', this.question); | |
var self = this; | |
if (this.cache && this.cache.lookup) { | |
this.cache.lookup(this.question, function(results) { | |
var packet; | |
if (!results) { | |
self._send(); | |
} else { | |
packet = new Packet(); | |
packet.answer = results.slice(); | |
self.handle(null, packet, true); | |
} | |
}); | |
} else { | |
this._send(); | |
} | |
}; | |
Request.prototype._send = function() { | |
debug('request not in cache', this.question); | |
var self = this; | |
this.timer_ = setTimeout(function() { | |
self.handleTimeout(); | |
}, this.timeout); | |
PendingRequests.send(self); | |
}; | |
Request.prototype.cancel = function() { | |
debug('request cancelled', this.id, this.question); | |
this.emit('cancelled'); | |
this.done(); | |
}; | |
var _queue = []; | |
var sendQueued = function() { | |
debug('platform ready sending queued requests'); | |
_queue.forEach(function(request) { | |
request.start(); | |
}); | |
_queue = []; | |
}; | |
platform.on('ready', function() { | |
sendQueued(); | |
}); | |
if (platform.ready) { | |
sendQueued(); | |
} | |
var Resolve = function Resolve(opts, cb) { | |
if (!(this instanceof Resolve)) return new Resolve(opts, cb); | |
this.opts = util._extend({ | |
retryOnTruncate: true, | |
}, opts); | |
this._domain = opts.domain; | |
this._rrtype = opts.rrtype; | |
this._buildQuestion(this._domain); | |
this._started = false; | |
this._current_server = undefined; | |
this._server_list = []; | |
if (opts.remote) { | |
this._server_list.push({ | |
address: opts.remote, | |
port: 53, | |
type: 'tcp', | |
}); | |
this._server_list.push({ | |
address: opts.remote, | |
port: 53, | |
type: 'udp', | |
}); | |
} | |
this._request = undefined; | |
this._type = 'getHostByName'; | |
this._cb = cb; | |
if (!platform.ready) { | |
_queue.push(this); | |
} else { | |
this.start(); | |
} | |
}; | |
util.inherits(Resolve, EventEmitter); | |
Resolve.prototype.cancel = function() { | |
if (this._request) { | |
this._request.cancel(); | |
} | |
}; | |
Resolve.prototype._buildQuestion = function(name) { | |
debug('building question', name); | |
this.question = { | |
type: this._rrtype, | |
class: consts.NAME_TO_QCLASS.IN, | |
name: name | |
}; | |
}; | |
exports.Resolve = Resolve; | |
Resolve.prototype._emit = function(err, answer) { | |
debug('resolve end', this._domain); | |
var self = this; | |
process.nextTick(function() { | |
if (err) { | |
err.syscall = self._type; | |
} | |
self._cb(err, answer); | |
}); | |
}; | |
Resolve.prototype._fillServers = function() { | |
debug('resolve filling servers', this._domain); | |
var tries = 0, s, t, u, slist; | |
slist = platform.name_servers; | |
while (this._server_list.length < platform.attempts) { | |
s = slist[tries % slist.length]; | |
u = { | |
address: s.address, | |
port: s.port, | |
type: 'udp' | |
}; | |
t = { | |
address: s.address, | |
port: s.port, | |
type: 'tcp' | |
}; | |
this._server_list.push(u); | |
this._server_list.push(t); | |
tries += 1; | |
} | |
this._server_list.reverse(); | |
}; | |
Resolve.prototype._popServer = function() { | |
debug('resolve pop server', this._current_server, this._domain); | |
this._server_list.splice(0, 1, this._current_server); | |
}; | |
Resolve.prototype._preStart = function() { | |
if (!this._started) { | |
this._started = new Date().getTime(); | |
this.try_edns = platform.edns; | |
if (!this._server_list.length) | |
this._fillServers(); | |
} | |
}; | |
Resolve.prototype._shouldContinue = function() { | |
debug('resolve should continue', this._server_list.length, this._domain); | |
return this._server_list.length; | |
}; | |
Resolve.prototype._nextQuestion = function() { | |
debug('resolve next question', this._domain); | |
}; | |
Resolve.prototype.start = function() { | |
if (!this._started) { | |
this._preStart(); | |
} | |
if (this._server_list.length === 0) { | |
debug('resolve no more servers', this._domain); | |
this.handleTimeout(); | |
} else { | |
this._current_server = this._server_list.pop(); | |
debug('resolve start', this._current_server, this._domain); | |
this._request = Request({ | |
question: this.question, | |
server: this._current_server, | |
timeout: platform.timeout, | |
try_edns: this.try_edns | |
}); | |
this._request.on('timeout', this._handleTimeout.bind(this)); | |
this._request.on('message', this._handle.bind(this)); | |
this._request.on('error', this._handle.bind(this)); | |
this._request.send(); | |
} | |
}; | |
var NOERROR = consts.NAME_TO_RCODE.NOERROR, | |
SERVFAIL = consts.NAME_TO_RCODE.SERVFAIL, | |
NOTFOUND = consts.NAME_TO_RCODE.NOTFOUND, | |
FORMERR = consts.NAME_TO_RCODE.FORMERR; | |
Resolve.prototype._handle = function(err, answer) { | |
var rcode, errno; | |
if (answer) { | |
rcode = answer.header.rcode; | |
} | |
debug('resolve handle', rcode, this._domain); | |
switch (rcode) { | |
case NOERROR: | |
// answer trucated retry with tcp | |
//console.log(answer); | |
if (answer.header.tc && | |
this.opts.retryOnTruncate && | |
this._shouldContinue()) { | |
debug('truncated', this._domain, answer); | |
this.emit('truncated', err, answer); | |
// remove udp servers | |
this._server_list = this._server_list.filter(function(server) { | |
return server.type === 'tcp'; | |
}); | |
answer = undefined; | |
} | |
break; | |
case SERVFAIL: | |
if (this._shouldContinue()) { | |
this._nextQuestion(); | |
//this._popServer(); | |
} else { | |
errno = consts.SERVFAIL; | |
} | |
answer = undefined; | |
break; | |
case NOTFOUND: | |
if (this._shouldContinue()) { | |
this._nextQuestion(); | |
} else { | |
errno = consts.NOTFOUND; | |
} | |
answer = undefined; | |
break; | |
case FORMERR: | |
if (this.try_edns) { | |
this.try_edns = false; | |
//this._popServer(); | |
} else { | |
errno = consts.FORMERR; | |
} | |
answer = undefined; | |
break; | |
default: | |
if (!err) { | |
errno = consts.RCODE_TO_NAME[rcode]; | |
answer = undefined; | |
} else { | |
errno = consts.NOTFOUND; | |
} | |
break; | |
} | |
if (errno || answer) { | |
if (errno) { | |
err = new Error(this._type + ' ' + errno); | |
err.errno = err.code = errno; | |
} | |
this._emit(err, answer); | |
} else { | |
this.start(); | |
} | |
}; | |
Resolve.prototype._handleTimeout = function() { | |
var err; | |
if (this._server_list.length === 0) { | |
debug('resolve timeout no more servers', this._domain); | |
err = new Error(this._type + ' ' + consts.TIMEOUT); | |
err.errno = consts.TIMEOUT; | |
this._emit(err, undefined); | |
} else { | |
debug('resolve timeout continue', this._domain); | |
this.start(); | |
} | |
}; | |
var resolve = function(domain, rrtype, ip, callback) { | |
var res; | |
if (!callback) { | |
callback = ip; | |
ip = undefined; | |
} | |
if (!callback) { | |
callback = rrtype; | |
rrtype = undefined; | |
} | |
rrtype = consts.NAME_TO_QTYPE[rrtype || 'A']; | |
if (rrtype === PTR) { | |
return reverse(domain, callback); | |
} | |
var opts = { | |
domain: domain, | |
rrtype: rrtype, | |
remote: ip, | |
}; | |
res = new Resolve(opts); | |
res._cb = function(err, response) { | |
var ret = [], i, a; | |
if (err) { | |
callback(err, response); | |
return; | |
} | |
for (i = 0; i < response.answer.length; i++) { | |
a = response.answer[i]; | |
if (a.type === rrtype) { | |
switch (rrtype) { | |
case A: | |
case AAAA: | |
ret.push(a.address); | |
break; | |
case consts.NAME_TO_QTYPE.MX: | |
ret.push({ | |
priority: a.priority, | |
exchange: a.exchange | |
}); | |
break; | |
case TXT: | |
case NS: | |
case CNAME: | |
case PTR: | |
ret.push(a.data); | |
break; | |
case SRV: | |
ret.push({ | |
priority: a.priority, | |
weight: a.weight, | |
port: a.port, | |
name: a.target | |
}); | |
break; | |
default: | |
ret.push(a); | |
break; | |
} | |
} | |
} | |
if (ret.length === 0) { | |
ret = undefined; | |
} | |
callback(err, ret); | |
}; | |
return res; | |
}; | |
exports.resolve = resolve; | |
var resolve4 = function(domain, callback) { | |
return resolve(domain, 'A', function(err, results) { | |
callback(err, results); | |
}); | |
}; | |
exports.resolve4 = resolve4; | |
var resolve6 = function(domain, callback) { | |
return resolve(domain, 'AAAA', function(err, results) { | |
callback(err, results); | |
}); | |
}; | |
exports.resolve6 = resolve6; | |
var resolveMx = function(domain, callback) { | |
return resolve(domain, 'MX', function(err, results) { | |
callback(err, results); | |
}); | |
}; | |
exports.resolveMx = resolveMx; | |
var resolveTxt = function(domain, callback) { | |
return resolve(domain, 'TXT', function(err, results) { | |
callback(err, results); | |
}); | |
}; | |
exports.resolveTxt = resolveTxt; | |
var resolveSrv = function(domain, callback) { | |
return resolve(domain, 'SRV', function(err, results) { | |
callback(err, results); | |
}); | |
}; | |
exports.resolveSrv = resolveSrv; | |
var resolveNs = function(domain, callback) { | |
return resolve(domain, 'NS', function(err, results) { | |
callback(err, results); | |
}); | |
}; | |
exports.resolveNs = resolveNs; | |
var resolveCname = function(domain, callback) { | |
return resolve(domain, 'CNAME', function(err, results) { | |
callback(err, results); | |
}); | |
}; | |
exports.resolveCname = resolveCname; | |
var resolveTlsa = function(domain, callback) { | |
return resolve(domain, 'TLSA', function(err, results) { | |
callback(err, results); | |
}); | |
}; | |
exports.resolveTlsa = resolveTlsa; | |
var reverse = function(ip, callback) { | |
var error, opts, res; | |
if (!net.isIP(ip)) { | |
error = new Error('getHostByAddr ENOTIMP'); | |
error.errno = error.code = 'ENOTIMP'; | |
throw error; | |
} | |
opts = { | |
domain: utils.reverseIP(ip), | |
rrtype: PTR | |
}; | |
res = new Lookup(opts); | |
res._cb = function(err, response) { | |
var results = []; | |
if (response) { | |
response.answer.forEach(function(a) { | |
if (a.type === PTR) { | |
results.push(a.data); | |
} | |
}); | |
} | |
if (results.length === 0) { | |
results = undefined; | |
} | |
callback(err, results); | |
}; | |
return res; | |
}; | |
exports.reverse = reverse; | |
var Lookup = function(opts) { | |
Resolve.call(this, opts); | |
this._type = 'getaddrinfo'; | |
}; | |
util.inherits(Lookup, Resolve); | |
Lookup.prototype.start = function() { | |
var self = this; | |
if (!this._started) { | |
this._search_path = platform.search_path.slice(0); | |
this._preStart(); | |
} | |
platform.hosts.lookup(this.question, function(results) { | |
var packet; | |
if (results && results.length) { | |
debug('Lookup in hosts', results); | |
packet = new Packet(); | |
packet.answer = results.slice(); | |
self._emit(null, packet); | |
} else { | |
debug('Lookup not in hosts'); | |
Resolve.prototype.start.call(self); | |
} | |
}); | |
}; | |
Lookup.prototype._shouldContinue = function() { | |
debug('Lookup should continue', this._server_list.length, | |
this._search_path.length); | |
return this._server_list.length && this._search_path.length; | |
}; | |
Lookup.prototype._nextQuestion = function() { | |
debug('Lookup next question'); | |
this._buildQuestion([this._domain, this._search_path.pop()].join('.')); | |
}; | |
var lookup = function(domain, family, callback) { | |
var rrtype, revip, res; | |
if (!callback) { | |
callback = family; | |
family = undefined; | |
} | |
if (!family) { | |
family = 4; | |
} | |
revip = net.isIP(domain); | |
if (revip === 4 || revip === 6) { | |
process.nextTick(function() { | |
callback(null, domain, revip); | |
}); | |
return {}; | |
} | |
if (!domain) { | |
process.nextTick(function() { | |
callback(null, null, family); | |
}); | |
return {}; | |
} | |
rrtype = consts.FAMILY_TO_QTYPE[family]; | |
var opts = { | |
domain: domain, | |
rrtype: rrtype | |
}; | |
res = new Lookup(opts); | |
res._cb = function(err, response) { | |
var i, afamily, address, a, all; | |
if (err) { | |
callback(err, undefined, undefined); | |
return; | |
} | |
all = response.answer.concat(response.additional); | |
for (i = 0; i < all.length; i++) { | |
a = all[i]; | |
if (a.type === A || a.type === AAAA) { | |
afamily = consts.QTYPE_TO_FAMILY[a.type]; | |
address = a.address; | |
break; | |
} | |
} | |
callback(err, address, afamily); | |
}; | |
return res; | |
}; | |
exports.lookup = lookup; | |
}).call(this,require('_process')) | |
},{"./packet":18,"./pending":19,"./platform":20,"./utils":22,"_process":13,"events":8,"ipaddr.js":23,"native-dns-packet":30,"net":2,"util":15}],18:[function(require,module,exports){ | |
// Copyright 2011 Timothy J Fontaine <tjfontaine@gmail.com> | |
// | |
// Permission is hereby granted, free of charge, to any person obtaining a copy | |
// of this software and associated documentation files (the 'Software'), to deal | |
// in the Software without restriction, including without limitation the rights | |
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | |
// copies of the Software, and to permit persons to whom the Software is | |
// furnished to do so, subject to the following conditions: | |
// | |
// The above copyright notice and this permission notice shall be included in | |
// all copies or substantial portions of the Software. | |
// | |
// THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | |
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | |
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | |
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN | |
// THE SOFTWARE | |
'use strict'; | |
var NDP = require('native-dns-packet'), | |
util = require('util'); | |
var Packet = module.exports = function(socket) { | |
NDP.call(this); | |
this.address = undefined; | |
this._socket = socket; | |
}; | |
util.inherits(Packet, NDP); | |
Packet.prototype.send = function() { | |
var buff, len, size; | |
if (typeof(this.edns_version) !== 'undefined') { | |
size = 4096; | |
} | |
this.payload = size = size || this._socket.base_size; | |
buff = this._socket.buffer(size); | |
len = Packet.write(buff, this); | |
this._socket.send(len); | |
}; | |
Packet.parse = function (msg, socket) { | |
var p = NDP.parse(msg); | |
p._socket = socket; | |
return p; | |
}; | |
Packet.write = NDP.write; | |
},{"native-dns-packet":30,"util":15}],19:[function(require,module,exports){ | |
// Copyright 2012 Timothy J Fontaine <tjfontaine@gmail.com> | |
// | |
// Permission is hereby granted, free of charge, to any person obtaining a copy | |
// of this software and associated documentation files (the "Software"), to deal | |
// in the Software without restriction, including without limitation the rights | |
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | |
// copies of the Software, and to permit persons to whom the Software is | |
// furnished to do so, subject to the following conditions: | |
// | |
// The above copyright notice and this permission notice shall be included in | |
// all copies or substantial portions of the Software. | |
// | |
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | |
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | |
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | |
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN | |
// THE SOFTWARE | |
'use strict'; | |
var net = require('net'), | |
util = require('util'), | |
EventEmitter = require('events').EventEmitter, | |
Packet = require('./packet'), | |
consts = require('native-dns-packet').consts, | |
UDPSocket = require('./utils').UDPSocket, | |
TCPSocket = require('./utils').TCPSocket; | |
var debug = function() { | |
//var args = Array.prototype.slice.call(arguments); | |
//console.log.apply(this, ['pending', Date.now().toString()].concat(args)); | |
}; | |
var SocketQueue = function(socket, server) { | |
this._active = {}; | |
this._active_count = 0; | |
this._pending = []; | |
debug('created', server); | |
this._server = server; | |
this._socket = socket; | |
this._socket.on('ready', this._onlisten.bind(this)); | |
this._socket.on('message', this._onmessage.bind(this)); | |
this._socket.on('close', this._onclose.bind(this)); | |
this._socket.bind(server); | |
this._refd = true; | |
}; | |
util.inherits(SocketQueue, EventEmitter); | |
SocketQueue.prototype.send = function(request) { | |
debug('added', request.question); | |
this._pending.push(request); | |
this._fill(); | |
}; | |
SocketQueue.prototype.remove = function(request) { | |
var req = this._active[request.id]; | |
var idx = this._pending.indexOf(request); | |
if (req) { | |
delete this._active[request.id]; | |
this._active_count -= 1; | |
this._fill(); | |
} | |
if (idx > -1) | |
this._pending.splice(idx, 1); | |
this._unref(); | |
}; | |
SocketQueue.prototype.close = function() { | |
debug('closing', this._server); | |
this._socket.close(); | |
this._socket = undefined; | |
this.emit('close'); | |
}; | |
SocketQueue.prototype._fill = function() { | |
debug('pre fill, active:', this._active_count, 'pending:', | |
this._pending.length); | |
while (this._listening && this._pending.length && | |
this._active_count < 100) { | |
this._dequeue(); | |
} | |
debug('post fill, active:', this._active_count, 'pending:', | |
this._pending.length); | |
}; | |
var random_integer = function() { | |
return Math.floor(Math.random() * 50000 + 1); | |
}; | |
SocketQueue.prototype._dequeue = function() { | |
var req = this._pending.pop(); | |
var id, packet, dnssocket; | |
if (req) { | |
id = random_integer(); | |
while (this._active[id]) | |
id = random_integer(); | |
debug('sending', req.question, id); | |
req.id = id; | |
this._active[id] = req; | |
this._active_count += 1; | |
try { | |
packet = new Packet(this._socket.remote(req.server)); | |
packet.header.id = id; | |
packet.header.rd = 1; | |
if (req.try_edns) { | |
packet.edns_version = 0; | |
//TODO when we support dnssec | |
//packet.do = 1 | |
} | |
packet.question.push(req.question); | |
packet.send(); | |
this._ref(); | |
} catch (e) { | |
req.error(e); | |
} | |
} | |
}; | |
SocketQueue.prototype._onmessage = function(msg, remote) { | |
var req, packet; | |
debug('got a message', this._server); | |
try { | |
packet = Packet.parse(msg, remote); | |
req = this._active[packet.header.id]; | |
debug('associated message', packet.header.id); | |
} catch (e) { | |
debug('error parsing packet', e); | |
} | |
if (req) { | |
delete this._active[packet.header.id]; | |
this._active_count -= 1; | |
req.handle(null, packet); | |
this._fill(); | |
} | |
this._unref(); | |
}; | |
SocketQueue.prototype._unref = function() { | |
var self = this; | |
this._refd = false; | |
if (this._active_count <= 0) { | |
if (this._socket.unref) { | |
debug('unrefd socket'); | |
this._socket.unref(); | |
} else if (!this._timer) { | |
this._timer = setTimeout(function() { | |
self.close(); | |
}, 300); | |
} | |
} | |
}; | |
SocketQueue.prototype._ref = function() { | |
this._refd = true; | |
if (this._socket.ref) { | |
debug('refd socket'); | |
this._socket.ref(); | |
} else if (this._timer) { | |
clearTimeout(this._timer); | |
this._timer = null; | |
} | |
}; | |
SocketQueue.prototype._onlisten = function() { | |
this._unref(); | |
this._listening = true; | |
this._fill(); | |
}; | |
SocketQueue.prototype._onclose = function() { | |
var req, err, self = this; | |
debug('socket closed', this); | |
this._listening = false; | |
err = new Error('getHostByName ' + consts.TIMEOUT); | |
err.errno = consts.TIMEOUT; | |
while (this._pending.length) { | |
req = this._pending.pop(); | |
req.error(err); | |
} | |
Object.keys(this._active).forEach(function(key) { | |
var req = self._active[key]; | |
req.error(err); | |
delete self._active[key]; | |
self._active_count -= 1; | |
}); | |
}; | |
var serverHash = function(server) { | |
if (server.type === 'tcp') | |
return server.address + ':' + server.port; | |
else | |
return 'udp' + net.isIP(server.address); | |
}; | |
var _sockets = {}; | |
exports.send = function(request) { | |
var hash = serverHash(request.server); | |
var socket = _sockets[hash]; | |
if (!socket) { | |
switch (hash) { | |
case 'udp4': | |
case 'udp6': | |
socket = new SocketQueue(new UDPSocket(), hash); | |
break; | |
default: | |
socket = new SocketQueue(new TCPSocket(), request.server); | |
break; | |
} | |
socket.on('close', function() { | |
delete _sockets[hash]; | |
}); | |
_sockets[hash] = socket; | |
} | |
socket.send(request); | |
}; | |
exports.remove = function(request) { | |
var hash = serverHash(request.server); | |
var socket = _sockets[hash]; | |
if (socket) { | |
socket.remove(request); | |
} | |
}; | |
},{"./packet":18,"./utils":22,"events":8,"native-dns-packet":30,"net":2,"util":15}],20:[function(require,module,exports){ | |
(function (process){ | |
// Copyright 2011 Timothy J Fontaine <tjfontaine@gmail.com> | |
// | |
// Permission is hereby granted, free of charge, to any person obtaining a copy | |
// of this software and associated documentation files (the "Software"), to deal | |
// in the Software without restriction, including without limitation the rights | |
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | |
// copies of the Software, and to permit persons to whom the Software is | |
// furnished to do so, subject to the following conditions: | |
// | |
// The above copyright notice and this permission notice shall be included in | |
// all copies or substantial portions of the Software. | |
// | |
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | |
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | |
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | |
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN | |
// THE SOFTWARE | |
'use strict'; | |
var fs = require('fs'), | |
EventEmitter = require('events').EventEmitter, | |
net = require('net'), | |
os = require('os'), | |
util = require('util'), | |
Cache = require('native-dns-cache'), | |
consts = require('native-dns-packet').consts, | |
path = require('path'), | |
utils = require('./utils'); | |
var A = consts.NAME_TO_QTYPE.A, | |
AAAA = consts.NAME_TO_QTYPE.AAAA, | |
PTR = consts.NAME_TO_QTYPE.PTR; | |
var Platform = function() { | |
this._nsReady = false; | |
this._hostsReady = false; | |
Object.defineProperty(this, 'ready', { | |
get: function() { | |
return this._nsReady && this._hostsReady; | |
} | |
}); | |
this._watches = {}; | |
Object.defineProperty(this, 'watching', { | |
get: function() { | |
return Object.keys(this._watches).length > 0; | |
}, | |
set: function(value) { | |
var k; | |
if (value) | |
this._watchFiles(); | |
else { | |
for (k in this._watches) { | |
this._watches[k].close(); | |
delete this._watches[k]; | |
} | |
} | |
} | |
}); | |
this.hosts = new Cache(); | |
this._initNameServers(); | |
this._initHostsFile(); | |
this._populate(); | |
this.cache = false; //new Cache(); | |
}; | |
util.inherits(Platform, EventEmitter); | |
Platform.prototype.reload = function() { | |
this.emit('unready'); | |
this._initNameServers(); | |
this._initHostsFile(); | |
this._populate(); | |
}; | |
Platform.prototype._initNameServers = function() { | |
this._nsReady = false; | |
this.name_servers = []; | |
this.search_path = []; | |
this.timeout = 5 * 1000; | |
this.attempts = 5; | |
this.edns = false; | |
}; | |
Platform.prototype._initHostsFile = function() { | |
this._hostsReady = false; | |
this.hosts.purge(); | |
}; | |
Platform.prototype._populate = function() { | |
var hostsfile, self = this; | |
switch (os.platform()) { | |
case 'win32': | |
this.name_servers = [ | |
{ | |
address: '8.8.8.8', | |
port: 53 | |
}, | |
{ | |
address: '8.8.4.4', | |
port: 53 | |
} | |
]; | |
self._nsReady = true; | |
hostsfile = path.join(process.env.SystemRoot, | |
'\\System32\\drivers\\etc\\hosts'); | |
break; | |
default: | |
this.parseResolv(); | |
hostsfile = '/etc/hosts'; | |
break; | |
} | |
this._parseHosts(hostsfile); | |
}; | |
Platform.prototype._watchFiles = function() { | |
var self = this, watchParams; | |
watchParams = {persistent: false}; | |
switch (os.platform()) { | |
case 'win32': | |
//TODO XXX FIXME: it would be nice if this existed | |
break; | |
default: | |
this._watches.resolve = fs.watch('/etc/resolv.conf', watchParams, | |
function(event, filename) { | |
if (event === 'change') { | |
self.emit('unready'); | |
self._initNameServers(); | |
self.parseResolv(); | |
} | |
}); | |
this._watches.hosts = fs.watch('/etc/hosts', watchParams, | |
function(event, filename) { | |
if (event === 'change') { | |
self.emit('unready'); | |
self._initHostsFile(); | |
self._parseHosts(hostsfile); | |
} | |
}); | |
break; | |
} | |
}; | |
Platform.prototype._checkReady = function() { | |
if (this.ready) { | |
this.emit('ready'); | |
} | |
}; | |
Platform.prototype.parseResolv = function() { | |
var self = this; | |
fs.readFile('/etc/resolv.conf', 'ascii', function(err, file) { | |
if (err) { | |
throw err; | |
} | |
file.split(/\n/).forEach(function(line) { | |
var i, parts, subparts; | |
line = line.replace(/^\s+|\s+$/g, ''); | |
if (!line.match(/^#/)) { | |
parts = line.split(/\s+/); | |
switch (parts[0]) { | |
case 'nameserver': | |
self.name_servers.push({ | |
address: parts[1], | |
port: 53 | |
}); | |
break; | |
case 'domain': | |
self.search_path = [parts[1]]; | |
break; | |
case 'search': | |
self.search_path = [parts.slice(1)]; | |
break; | |
case 'options': | |
for (i = 1; i < parts.length; i++) { | |
subparts = parts[i].split(/:/); | |
switch (subparts[0]) { | |
case 'timeout': | |
self.timeout = parseInt(subparts[1], 10) * 1000; | |
break; | |
case 'attempts': | |
self.attempts = parseInt(subparts[1], 10); | |
break; | |
case 'edns0': | |
self.edns = true; | |
break; | |
} | |
} | |
break; | |
} | |
} | |
}); | |
self._nsReady = true; | |
self._checkReady(); | |
}); | |
}; | |
Platform.prototype._parseHosts = function(hostsfile) { | |
var self = this; | |
fs.readFile(hostsfile, 'ascii', function(err, file) { | |
var toStore = {}; | |
if (err) { | |
throw err; | |
} | |
file.split(/\n/).forEach(function(line) { | |
var i, parts, ip, revip, kind; | |
line = line.replace(/^\s+|\s+$/g, ''); | |
if (!line.match(/^#/)) { | |
parts = line.split(/\s+/); | |
ip = parts[0]; | |
parts = parts.slice(1); | |
kind = net.isIP(ip); | |
if (parts.length && ip && kind) { | |
/* IP -> Domain */ | |
revip = utils.reverseIP(ip); | |
parts.forEach(function(domain) { | |
var r = toStore[revip]; | |
if (!r) | |
r = toStore[revip] = {}; | |
var t = r[PTR]; | |
if (!t) | |
t = r[PTR] = []; | |
t.push({ | |
type: PTR, | |
class: 1, | |
name: revip, | |
data: domain, | |
ttl: Infinity | |
}); | |
}); | |
/* Domain -> IP */ | |
parts.forEach(function(domain) { | |
var r = toStore[domain.toLowerCase()]; | |
if (!r) { | |
r = toStore[domain.toLowerCase()] = {}; | |
} | |
var type = kind === 4 ? A : AAAA; | |
var t = r[type]; | |
if (!t) | |
t = r[type] = []; | |
t.push({ | |
type: type, | |
name: domain.toLowerCase(), | |
address: ip, | |
ttl: Infinity | |
}); | |
}); | |
} | |
} | |
}); | |
Object.keys(toStore).forEach(function (key) { | |
self.hosts._store.set(self.hosts._zone, key, toStore[key]); | |
}); | |
self._hostsReady = true; | |
self._checkReady(); | |
}); | |
}; | |
module.exports = new Platform(); | |
}).call(this,require('_process')) | |
},{"./utils":22,"_process":13,"events":8,"fs":2,"native-dns-cache":25,"native-dns-packet":30,"net":2,"os":11,"path":12,"util":15}],21:[function(require,module,exports){ | |
// Copyright 2011 Timothy J Fontaine <tjfontaine@gmail.com> | |
// | |
// Permission is hereby granted, free of charge, to any person obtaining a copy | |
// of this software and associated documentation files (the "Software"), to deal | |
// in the Software without restriction, including without limitation the rights | |
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | |
// copies of the Software, and to permit persons to whom the Software is | |
// furnished to do so, subject to the following conditions: | |
// | |
// The above copyright notice and this permission notice shall be included in | |
// all copies or substantial portions of the Software. | |
// | |
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | |
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | |
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | |
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN | |
// THE SOFTWARE | |
'use strict'; | |
var dgram = require('dgram'), | |
EventEmitter = require('events').EventEmitter, | |
net = require('net'), | |
util = require('util'), | |
UDPSocket = require('./utils').UDPSocket, | |
TCPSocket = require('./utils').TCPSocket, | |
Packet = require('./packet'); | |
var Server = function(opts) { | |
var self = this; | |
this._socket.on('listening', function() { | |
self.emit('listening'); | |
}); | |
this._socket.on('close', function() { | |
self.emit('close'); | |
}); | |
this._socket.on('error', function(err) { | |
self.emit('socketError', err, self._socket); | |
}); | |
}; | |
util.inherits(Server, EventEmitter); | |
Server.prototype.close = function() { | |
this._socket.close(); | |
}; | |
Server.prototype.address = function() { | |
return this._socket.address(); | |
}; | |
Server.prototype.handleMessage = function(msg, remote, address) { | |
var request, response = new Packet(remote); | |
try { | |
request = Packet.parse(msg, remote); | |
request.address = address; | |
response.header.id = request.header.id; | |
response.header.qr = 1; | |
response.question = request.question; | |
this.emit('request', request, response); | |
} catch (e) { | |
this.emit('error', e, msg, response); | |
} | |
}; | |
var UDPServer = function(opts) { | |
var self = this; | |
this._socket = dgram.createSocket(opts.dgram_type || 'udp4'); | |
this._socket.on('message', function(msg, remote) { | |
self.handleMessage(msg, new UDPSocket(self._socket, remote), remote); | |
}); | |
Server.call(this, opts); | |
}; | |
util.inherits(UDPServer, Server); | |
UDPServer.prototype.serve = function(port, address) { | |
this._socket.bind(port, address); | |
}; | |
var TCPServer = function(opts) { | |
var self = this; | |
this._socket = net.createServer(function(client) { | |
var tcp = new TCPSocket(client); | |
var address = client.address(); | |
tcp.on('message', function(msg, remote) { | |
self.handleMessage(msg, tcp, address); | |
}); | |
tcp.catchMessages(); | |
}); | |
Server.call(this, opts); | |
}; | |
util.inherits(TCPServer, Server); | |
TCPServer.prototype.serve = function(port, address) { | |
this._socket.listen(port, address); | |
}; | |
exports.createServer = function(opts) { | |
return new UDPServer(opts || {}); | |
}; | |
exports.createUDPServer = function(opts) { | |
return exports.createServer(opts); | |
}; | |
exports.createTCPServer = function(opts) { | |
return new TCPServer(opts || {}); | |
}; | |
},{"./packet":18,"./utils":22,"dgram":2,"events":8,"net":2,"util":15}],22:[function(require,module,exports){ | |
(function (Buffer){ | |
// Copyright 2012 Timothy J Fontaine <tjfontaine@gmail.com> | |
// | |
// Permission is hereby granted, free of charge, to any person obtaining a copy | |
// of this software and associated documentation files (the "Software"), to deal | |
// in the Software without restriction, including without limitation the rights | |
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | |
// copies of the Software, and to permit persons to whom the Software is | |
// furnished to do so, subject to the following conditions: | |
// | |
// The above copyright notice and this permission notice shall be included in | |
// all copies or substantial portions of the Software. | |
// | |
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | |
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | |
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | |
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN | |
// THE SOFTWARE | |
var dgram = require('dgram'), | |
EventEmitter = require('events').EventEmitter, | |
ipaddr = require('ipaddr.js'), | |
net = require('net'), | |
util = require('util'); | |
var UDPSocket = exports.UDPSocket = function(socket, remote) { | |
this._socket = socket; | |
this._remote = remote; | |
this._buff = undefined; | |
this.base_size = 512; | |
this.bound = false; | |
this.unref = undefined; | |
this.ref = undefined; | |
}; | |
util.inherits(UDPSocket, EventEmitter); | |
UDPSocket.prototype.buffer = function(size) { | |
this._buff = new Buffer(size); | |
return this._buff; | |
}; | |
UDPSocket.prototype.send = function(len) { | |
this._socket.send(this._buff, 0, len, this._remote.port, | |
this._remote.address); | |
}; | |
UDPSocket.prototype.bind = function(type) { | |
var self = this; | |
if (this.bound) { | |
this.emit('ready'); | |
} else { | |
this._socket = dgram.createSocket(type); | |
this._socket.on('listening', function() { | |
self.bound = true; | |
if (self._socket.unref) { | |
self.unref = function() { | |
self._socket.unref(); | |
} | |
self.ref = function() { | |
self._socket.ref(); | |
} | |
} | |
self.emit('ready'); | |
}); | |
this._socket.on('message', this.emit.bind(this, 'message')); | |
this._socket.on('close', function() { | |
self.bound = false; | |
self.emit('close'); | |
}); | |
this._socket.bind(); | |
} | |
}; | |
UDPSocket.prototype.close = function() { | |
this._socket.close(); | |
}; | |
UDPSocket.prototype.remote = function(remote) { | |
return new UDPSocket(this._socket, remote); | |
}; | |
var TCPSocket = exports.TCPSocket = function(socket) { | |
UDPSocket.call(this, socket); | |
this.base_size = 4096; | |
this._rest = undefined; | |
}; | |
util.inherits(TCPSocket, UDPSocket); | |
TCPSocket.prototype.buffer = function(size) { | |
this._buff = new Buffer(size + 2); | |
return this._buff.slice(2); | |
}; | |
TCPSocket.prototype.send = function(len) { | |
this._buff.writeUInt16BE(len, 0); | |
this._socket.write(this._buff.slice(0, len + 2)); | |
}; | |
TCPSocket.prototype.bind = function(server) { | |
var self = this; | |
if (this.bound) { | |
this.emit('ready'); | |
} else { | |
this._socket = net.connect(server.port, server.address); | |
this._socket.on('connect', function() { | |
self.bound = true; | |
if (self._socket.unref) { | |
self.unref = function() { | |
self._socket.unref(); | |
} | |
self.ref = function() { | |
self._socket.ref(); | |
} | |
} | |
self.emit('ready'); | |
}); | |
this._socket.on('timeout', function() { | |
self.bound = false; | |
self.emit('close'); | |
}); | |
this._socket.on('close', function() { | |
self.bound = false; | |
self.emit('close'); | |
}); | |
this.catchMessages(); | |
} | |
}; | |
TCPSocket.prototype.catchMessages = function() { | |
var self = this; | |
this._socket.on('data', function(data) { | |
var len, tmp; | |
if (!self._rest) { | |
self._rest = data; | |
} else { | |
tmp = new Buffer(self._rest.length + data.length); | |
self._rest.copy(tmp, 0); | |
data.copy(tmp, self._rest.length); | |
self._rest = tmp; | |
} | |
while (self._rest && self._rest.length > 2) { | |
len = self._rest.readUInt16BE(0); | |
if (self._rest.length >= len + 2) { | |
self.emit('message', self._rest.slice(2, len + 2), self); | |
self._rest = self._rest.slice(len + 2); | |
} else { | |
break; | |
} | |
} | |
}); | |
}; | |
TCPSocket.prototype.close = function() { | |
this._socket.end(); | |
}; | |
TCPSocket.prototype.remote = function() { | |
return this; | |
}; | |
exports.reverseIP = function(ip) { | |
var address, kind, reverseip, parts; | |
address = ipaddr.parse(ip.split(/%/)[0]); | |
kind = address.kind(); | |
switch (kind) { | |
case 'ipv4': | |
address = address.toByteArray(); | |
address.reverse(); | |
reverseip = address.join('.') + '.IN-ADDR.ARPA'; | |
break; | |
case 'ipv6': | |
parts = []; | |
address.toNormalizedString().split(':').forEach(function(part) { | |
var i, pad = 4 - part.length; | |
for (i = 0; i < pad; i++) { | |
part = '0' + part; | |
} | |
part.split('').forEach(function(p) { | |
parts.push(p); | |
}); | |
}); | |
parts.reverse(); | |
reverseip = parts.join('.') + '.IP6.ARPA'; | |
break; | |
} | |
return reverseip; | |
}; | |
}).call(this,require("buffer").Buffer) | |
},{"buffer":4,"dgram":2,"events":8,"ipaddr.js":23,"net":2,"util":15}],23:[function(require,module,exports){ | |
(function() { | |
var expandIPv6, ipaddr, ipv4Part, ipv4Regexes, ipv6Part, ipv6Regexes, matchCIDR, root; | |
ipaddr = {}; | |
root = this; | |
if ((typeof module !== "undefined" && module !== null) && module.exports) { | |
module.exports = ipaddr; | |
} else { | |
root['ipaddr'] = ipaddr; | |
} | |
matchCIDR = function(first, second, partSize, cidrBits) { | |
var part, shift; | |
if (first.length !== second.length) { | |
throw new Error("ipaddr: cannot match CIDR for objects with different lengths"); | |
} | |
part = 0; | |
while (cidrBits > 0) { | |
shift = partSize - cidrBits; | |
if (shift < 0) { | |
shift = 0; | |
} | |
if (first[part] >> shift !== second[part] >> shift) { | |
return false; | |
} | |
cidrBits -= partSize; | |
part += 1; | |
} | |
return true; | |
}; | |
ipaddr.subnetMatch = function(address, rangeList, defaultName) { | |
var rangeName, rangeSubnets, subnet, _i, _len; | |
if (defaultName == null) { | |
defaultName = 'unicast'; | |
} | |
for (rangeName in rangeList) { | |
rangeSubnets = rangeList[rangeName]; | |
if (toString.call(rangeSubnets[0]) !== '[object Array]') { | |
rangeSubnets = [rangeSubnets]; | |
} | |
for (_i = 0, _len = rangeSubnets.length; _i < _len; _i++) { | |
subnet = rangeSubnets[_i]; | |
if (address.match.apply(address, subnet)) { | |
return rangeName; | |
} | |
} | |
} | |
return defaultName; | |
}; | |
ipaddr.IPv4 = (function() { | |
function IPv4(octets) { | |
var octet, _i, _len; | |
if (octets.length !== 4) { | |
throw new Error("ipaddr: ipv4 octet count should be 4"); | |
} | |
for (_i = 0, _len = octets.length; _i < _len; _i++) { | |
octet = octets[_i]; | |
if (!((0 <= octet && octet <= 255))) { | |
throw new Error("ipaddr: ipv4 octet is a byte"); | |
} | |
} | |
this.octets = octets; | |
} | |
IPv4.prototype.kind = function() { | |
return 'ipv4'; | |
}; | |
IPv4.prototype.toString = function() { | |
return this.octets.join("."); | |
}; | |
IPv4.prototype.toByteArray = function() { | |
return this.octets.slice(0); | |
}; | |
IPv4.prototype.match = function(other, cidrRange) { | |
if (other.kind() !== 'ipv4') { | |
throw new Error("ipaddr: cannot match ipv4 address with non-ipv4 one"); | |
} | |
return matchCIDR(this.octets, other.octets, 8, cidrRange); | |
}; | |
IPv4.prototype.SpecialRanges = { | |
unspecified: [[new IPv4([0, 0, 0, 0]), 8]], | |
broadcast: [[new IPv4([255, 255, 255, 255]), 32]], | |
multicast: [[new IPv4([224, 0, 0, 0]), 4]], | |
linkLocal: [[new IPv4([169, 254, 0, 0]), 16]], | |
loopback: [[new IPv4([127, 0, 0, 0]), 8]], | |
"private": [[new IPv4([10, 0, 0, 0]), 8], [new IPv4([172, 16, 0, 0]), 12], [new IPv4([192, 168, 0, 0]), 16]], | |
reserved: [[new IPv4([192, 0, 0, 0]), 24], [new IPv4([192, 0, 2, 0]), 24], [new IPv4([192, 88, 99, 0]), 24], [new IPv4([198, 51, 100, 0]), 24], [new IPv4([203, 0, 113, 0]), 24], [new IPv4([240, 0, 0, 0]), 4]] | |
}; | |
IPv4.prototype.range = function() { | |
return ipaddr.subnetMatch(this, this.SpecialRanges); | |
}; | |
IPv4.prototype.toIPv4MappedAddress = function() { | |
return ipaddr.IPv6.parse("::ffff:" + (this.toString())); | |
}; | |
return IPv4; | |
})(); | |
ipv4Part = "(0?\\d+|0x[a-f0-9]+)"; | |
ipv4Regexes = { | |
fourOctet: new RegExp("^" + ipv4Part + "\\." + ipv4Part + "\\." + ipv4Part + "\\." + ipv4Part + "$", 'i'), | |
longValue: new RegExp("^" + ipv4Part + "$", 'i') | |
}; | |
ipaddr.IPv4.parser = function(string) { | |
var match, parseIntAuto, part, shift, value; | |
parseIntAuto = function(string) { | |
if (string[0] === "0" && string[1] !== "x") { | |
return parseInt(string, 8); | |
} else { | |
return parseInt(string); | |
} | |
}; | |
if (match = string.match(ipv4Regexes.fourOctet)) { | |
return (function() { | |
var _i, _len, _ref, _results; | |
_ref = match.slice(1, 6); | |
_results = []; | |
for (_i = 0, _len = _ref.length; _i < _len; _i++) { | |
part = _ref[_i]; | |
_results.push(parseIntAuto(part)); | |
} | |
return _results; | |
})(); | |
} else if (match = string.match(ipv4Regexes.longValue)) { | |
value = parseIntAuto(match[1]); | |
if (value > 0xffffffff || value < 0) { | |
throw new Error("ipaddr: address outside defined range"); | |
} | |
return ((function() { | |
var _i, _results; | |
_results = []; | |
for (shift = _i = 0; _i <= 24; shift = _i += 8) { | |
_results.push((value >> shift) & 0xff); | |
} | |
return _results; | |
})()).reverse(); | |
} else { | |
return null; | |
} | |
}; | |
ipaddr.IPv6 = (function() { | |
function IPv6(parts) { | |
var part, _i, _len; | |
if (parts.length !== 8) { | |
throw new Error("ipaddr: ipv6 part count should be 8"); | |
} | |
for (_i = 0, _len = parts.length; _i < _len; _i++) { | |
part = parts[_i]; | |
if (!((0 <= part && part <= 0xffff))) { | |
throw new Error("ipaddr: ipv6 part should fit to two octets"); | |
} | |
} | |
this.parts = parts; | |
} | |
IPv6.prototype.kind = function() { | |
return 'ipv6'; | |
}; | |
IPv6.prototype.toString = function() { | |
var compactStringParts, part, pushPart, state, stringParts, _i, _len; | |
stringParts = (function() { | |
var _i, _len, _ref, _results; | |
_ref = this.parts; | |
_results = []; | |
for (_i = 0, _len = _ref.length; _i < _len; _i++) { | |
part = _ref[_i]; | |
_results.push(part.toString(16)); | |
} | |
return _results; | |
}).call(this); | |
compactStringParts = []; | |
pushPart = function(part) { | |
return compactStringParts.push(part); | |
}; | |
state = 0; | |
for (_i = 0, _len = stringParts.length; _i < _len; _i++) { | |
part = stringParts[_i]; | |
switch (state) { | |
case 0: | |
if (part === '0') { | |
pushPart(''); | |
} else { | |
pushPart(part); | |
} | |
state = 1; | |
break; | |
case 1: | |
if (part === '0') { | |
state = 2; | |
} else { | |
pushPart(part); | |
} | |
break; | |
case 2: | |
if (part !== '0') { | |
pushPart(''); | |
pushPart(part); | |
state = 3; | |
} | |
break; | |
case 3: | |
pushPart(part); | |
} | |
} | |
if (state === 2) { | |
pushPart(''); | |
pushPart(''); | |
} | |
return compactStringParts.join(":"); | |
}; | |
IPv6.prototype.toByteArray = function() { | |
var bytes, part, _i, _len, _ref; | |
bytes = []; | |
_ref = this.parts; | |
for (_i = 0, _len = _ref.length; _i < _len; _i++) { | |
part = _ref[_i]; | |
bytes.push(part >> 8); | |
bytes.push(part & 0xff); | |
} | |
return bytes; | |
}; | |
IPv6.prototype.toNormalizedString = function() { | |
var part; | |
return ((function() { | |
var _i, _len, _ref, _results; | |
_ref = this.parts; | |
_results = []; | |
for (_i = 0, _len = _ref.length; _i < _len; _i++) { | |
part = _ref[_i]; | |
_results.push(part.toString(16)); | |
} | |
return _results; | |
}).call(this)).join(":"); | |
}; | |
IPv6.prototype.match = function(other, cidrRange) { | |
if (other.kind() !== 'ipv6') { | |
throw new Error("ipaddr: cannot match ipv6 address with non-ipv6 one"); | |
} | |
return matchCIDR(this.parts, other.parts, 16, cidrRange); | |
}; | |
IPv6.prototype.SpecialRanges = { | |
unspecified: [new IPv6([0, 0, 0, 0, 0, 0, 0, 0]), 128], | |
linkLocal: [new IPv6([0xfe80, 0, 0, 0, 0, 0, 0, 0]), 10], | |
multicast: [new IPv6([0xff00, 0, 0, 0, 0, 0, 0, 0]), 8], | |
loopback: [new IPv6([0, 0, 0, 0, 0, 0, 0, 1]), 128], | |
uniqueLocal: [new IPv6([0xfc00, 0, 0, 0, 0, 0, 0, 0]), 7], | |
ipv4Mapped: [new IPv6([0, 0, 0, 0, 0, 0xffff, 0, 0]), 96], | |
rfc6145: [new IPv6([0, 0, 0, 0, 0xffff, 0, 0, 0]), 96], | |
rfc6052: [new IPv6([0x64, 0xff9b, 0, 0, 0, 0, 0, 0]), 96], | |
'6to4': [new IPv6([0x2002, 0, 0, 0, 0, 0, 0, 0]), 16], | |
teredo: [new IPv6([0x2001, 0, 0, 0, 0, 0, 0, 0]), 32], | |
reserved: [[new IPv6([0x2001, 0xdb8, 0, 0, 0, 0, 0, 0]), 32]] | |
}; | |
IPv6.prototype.range = function() { | |
return ipaddr.subnetMatch(this, this.SpecialRanges); | |
}; | |
IPv6.prototype.isIPv4MappedAddress = function() { | |
return this.range() === 'ipv4Mapped'; | |
}; | |
IPv6.prototype.toIPv4Address = function() { | |
var high, low, _ref; | |
if (!this.isIPv4MappedAddress()) { | |
throw new Error("ipaddr: trying to convert a generic ipv6 address to ipv4"); | |
} | |
_ref = this.parts.slice(-2), high = _ref[0], low = _ref[1]; | |
return new ipaddr.IPv4([high >> 8, high & 0xff, low >> 8, low & 0xff]); | |
}; | |
return IPv6; | |
})(); | |
ipv6Part = "(?:[0-9a-f]+::?)+"; | |
ipv6Regexes = { | |
"native": new RegExp("^(::)?(" + ipv6Part + ")?([0-9a-f]+)?(::)?$", 'i'), | |
transitional: new RegExp(("^((?:" + ipv6Part + ")|(?:::)(?:" + ipv6Part + ")?)") + ("" + ipv4Part + "\\." + ipv4Part + "\\." + ipv4Part + "\\." + ipv4Part + "$"), 'i') | |
}; | |
expandIPv6 = function(string, parts) { | |
var colonCount, lastColon, part, replacement, replacementCount; | |
if (string.indexOf('::') !== string.lastIndexOf('::')) { | |
return null; | |
} | |
colonCount = 0; | |
lastColon = -1; | |
while ((lastColon = string.indexOf(':', lastColon + 1)) >= 0) { | |
colonCount++; | |
} | |
if (string[0] === ':') { | |
colonCount--; | |
} | |
if (string[string.length - 1] === ':') { | |
colonCount--; | |
} | |
if (colonCount > parts) { | |
return null; | |
} | |
replacementCount = parts - colonCount; | |
replacement = ':'; | |
while (replacementCount--) { | |
replacement += '0:'; | |
} | |
string = string.replace('::', replacement); | |
if (string[0] === ':') { | |
string = string.slice(1); | |
} | |
if (string[string.length - 1] === ':') { | |
string = string.slice(0, -1); | |
} | |
return (function() { | |
var _i, _len, _ref, _results; | |
_ref = string.split(":"); | |
_results = []; | |
for (_i = 0, _len = _ref.length; _i < _len; _i++) { | |
part = _ref[_i]; | |
_results.push(parseInt(part, 16)); | |
} | |
return _results; | |
})(); | |
}; | |
ipaddr.IPv6.parser = function(string) { | |
var match, parts; | |
if (string.match(ipv6Regexes['native'])) { | |
return expandIPv6(string, 8); | |
} else if (match = string.match(ipv6Regexes['transitional'])) { | |
parts = expandIPv6(match[1].slice(0, -1), 6); | |
if (parts) { | |
parts.push(parseInt(match[2]) << 8 | parseInt(match[3])); | |
parts.push(parseInt(match[4]) << 8 | parseInt(match[5])); | |
return parts; | |
} | |
} | |
return null; | |
}; | |
ipaddr.IPv4.isIPv4 = ipaddr.IPv6.isIPv6 = function(string) { | |
return this.parser(string) !== null; | |
}; | |
ipaddr.IPv4.isValid = ipaddr.IPv6.isValid = function(string) { | |
var e; | |
try { | |
new this(this.parser(string)); | |
return true; | |
} catch (_error) { | |
e = _error; | |
return false; | |
} | |
}; | |
ipaddr.IPv4.parse = ipaddr.IPv6.parse = function(string) { | |
var parts; | |
parts = this.parser(string); | |
if (parts === null) { | |
throw new Error("ipaddr: string is not formatted like ip address"); | |
} | |
return new this(parts); | |
}; | |
ipaddr.isValid = function(string) { | |
return ipaddr.IPv6.isValid(string) || ipaddr.IPv4.isValid(string); | |
}; | |
ipaddr.parse = function(string) { | |
if (ipaddr.IPv6.isValid(string)) { | |
return ipaddr.IPv6.parse(string); | |
} else if (ipaddr.IPv4.isValid(string)) { | |
return ipaddr.IPv4.parse(string); | |
} else { | |
throw new Error("ipaddr: the address has neither IPv6 nor IPv4 format"); | |
} | |
}; | |
ipaddr.process = function(string) { | |
var addr; | |
addr = this.parse(string); | |
if (addr.kind() === 'ipv6' && addr.isIPv4MappedAddress()) { | |
return addr.toIPv4Address(); | |
} else { | |
return addr; | |
} | |
}; | |
}).call(this); | |
},{}],24:[function(require,module,exports){ | |
// Copyright 2012 Timothy J Fontaine <tjfontaine@gmail.com> | |
// | |
// Permission is hereby granted, free of charge, to any person obtaining a copy | |
// of this software and associated documentation files (the "Software"), to deal | |
// in the Software without restriction, including without limitation the rights | |
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | |
// copies of the Software, and to permit persons to whom the Software is | |
// furnished to do so, subject to the following conditions: | |
// | |
// The above copyright notice and this permission notice shall be included in | |
// all copies or substantial portions of the Software. | |
// | |
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | |
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | |
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | |
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN | |
// THE SOFTWARE | |
'use strict'; | |
var MemoryStore = require('./memory').MemoryStore; | |
var utils = require('./lookup'); | |
var Lookup = utils.Lookup; | |
var util = require('util'); | |
var Heap = require('binaryheap'); | |
var MemoryStoreExpire = function (store, zone, opts) { | |
opts = opts || {}; | |
this._store = store; | |
this._zone = zone; | |
this._max_keys = opts.max_keys; | |
this._ttl = new Heap(true); | |
}; | |
MemoryStoreExpire.prototype.get = function (domain, key, cb) { | |
var self = this; | |
this._store.get(domain, key, function (err, results) { | |
var i, j, type, record; | |
var nresults = {}; | |
var now = Date.now(); | |
for (i in results) { | |
type = results[i]; | |
for (j in type) { | |
record = type[j]; | |
record.ttl = Math.round((record._ttl_expires - now) / 1000) | |
if (record.ttl > 0) { | |
if (!nresults[i]) { | |
nresults[i] = []; | |
} | |
nresults[i].push(record); | |
} else { | |
self._ttl.remove(record); | |
self._store.delete(self._zone, record.name, record.type, function () {}); | |
} | |
} | |
} | |
cb(err, nresults); | |
}); | |
}; | |
MemoryStoreExpire.prototype.set = function (domain, key, data, cb) { | |
var i, j, type, record, expires; | |
var self = this; | |
var now = Date.now(); | |
key = utils.ensure_absolute(key); | |
for (i in data) { | |
type = data[i]; | |
for (j in type) { | |
record = type[j]; | |
expires = (record.ttl * 1000) + now; | |
record._ttl_expires = expires; | |
self._ttl.insert(record, expires); | |
} | |
} | |
while (this._ttl.length > this._max_keys) { | |
var record = this._ttl.pop(); | |
this._store.delete(this._zone, record.name, record.type); | |
} | |
this._store.set(domain, key, data, function (err, results) { | |
if (cb) | |
cb(err, results); | |
}); | |
}; | |
MemoryStoreExpire.prototype.delete = function (domain, key, type, cb) { | |
if (!cb) { | |
cb = type; | |
type = undefined; | |
} | |
var self = this; | |
this._store.get(domain, utils.ensure_absolute(key), function (gerr, gresults) { | |
var i, j, ktype, record; | |
for (i in gresults) { | |
ktype = gresults[i]; | |
for (j in ktype) { | |
record = ktype[j]; | |
self._ttl.remove(record); | |
} | |
} | |
if (!gresults) { | |
if (cb) | |
cb(gerr, gresults); | |
return; | |
} | |
self._store.delete(domain, key, type, function (err, results) { | |
if (cb) | |
cb(err, results); | |
}); | |
}); | |
}; | |
var Cache = module.exports = function (opts) { | |
opts = opts || {}; | |
this._zone = '.' || opts.zone; | |
this._store = undefined; | |
this.purge = function () { | |
this._store = new MemoryStoreExpire(opts.store || new MemoryStore(), this._zone, opts); | |
} | |
this.purge(); | |
}; | |
Cache.prototype.store = function (packet) { | |
var self = this; | |
var c = {}; | |
function each(record) { | |
var r = c[record.name.toLowerCase()]; | |
var t; | |
if (!r) | |
r = c[record.name.toLowerCase()] = {}; | |
t = r[record.type]; | |
if (!t) | |
t = r[record.type] = []; | |
t.push(record); | |
} | |
packet.answer.forEach(each); | |
packet.authority.forEach(each); | |
packet.additional.forEach(each); | |
Object.keys(c).forEach(function (key) { | |
self._store.set(self._zone, utils.ensure_absolute(key), c[key]); | |
}); | |
}; | |
Cache.prototype.lookup = function (question, cb) { | |
var self = this; | |
Lookup(this._store, this._zone, question, function (err, results) { | |
var i, record, found = false; | |
for (i in results) { | |
record = results[i]; | |
if (record.type == question.type) { | |
found = true; | |
break; | |
} | |
} | |
if (results && !found) { | |
self._store.delete(self._zone, utils.ensure_absolute(question.name)); | |
results.forEach(function (rr) { | |
self._store.delete(self._zone, utils.ensure_absolute(rr.name)); | |
}); | |
results = null; | |
} | |
cb(results); | |
}); | |
}; | |
},{"./lookup":26,"./memory":27,"binaryheap":28,"util":15}],25:[function(require,module,exports){ | |
module.exports = require('./cache'); | |
module.exports.MemoryStore = require('./memory').MemoryStore; | |
module.exports.Lookup = require('./lookup').Lookup; | |
module.exports.is_absolute = require('./lookup').is_absolute; | |
module.exports.ensure_absolute = require('./lookup').ensure_absolute; | |
},{"./cache":24,"./lookup":26,"./memory":27}],26:[function(require,module,exports){ | |
// Copyright 2012 Timothy J Fontaine <tjfontaine@gmail.com> | |
// | |
// Permission is hereby granted, free of charge, to any person obtaining a copy | |
// of this software and associated documentation files (the "Software"), to deal | |
// in the Software without restriction, including without limitation the rights | |
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | |
// copies of the Software, and to permit persons to whom the Software is | |
// furnished to do so, subject to the following conditions: | |
// | |
// The above copyright notice and this permission notice shall be included in | |
// all copies or substantial portions of the Software. | |
// | |
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | |
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | |
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | |
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN | |
// THE SOFTWARE | |
var dgram = require('dgram'), | |
EventEmitter = require('events').EventEmitter, | |
net = require('net'), | |
util = require('util'); | |
var is_absolute = exports.is_absolute = function (f) { | |
return f && /\.$/.test(f); | |
}; | |
var ensure_absolute = exports.ensure_absolute = function (f) { | |
if (!is_absolute(f)) | |
return f += '.'; | |
return f; | |
}; | |
var CNAME = require('native-dns-packet').consts.NAME_TO_QTYPE.CNAME; | |
var Lookup = exports.Lookup = function (store, zone, question, cb) { | |
if (!(this instanceof Lookup)) | |
return new Lookup(store, zone, question, cb); | |
this.store = store; | |
this.zone = zone; | |
this.cb = cb; | |
this.question = question; | |
this.results = []; | |
this.wildcard = undefined; | |
this.name = ensure_absolute(question.name); | |
this.store.get(this.zone, this.name, this.lookup.bind(this)); | |
}; | |
Lookup.prototype.send = function (err) { | |
this.cb(err, this.results); | |
}; | |
Lookup.prototype.lookup = function (err, results) { | |
var type, ret, name, self = this; | |
if (err) | |
return this.send(err); | |
if (!results) { | |
if (!this.wildcard) | |
this.wildcard = this.question.name; | |
if (this.wildcard.toLowerCase() == this.zone.toLowerCase()) | |
return this.send(); | |
name = this.wildcard = this.wildcard.split('.').splice(1).join('.'); | |
// 'com.'.split('.').splice(1) will return empty string, we're at the end | |
if (!this.wildcard) | |
return this.send(); | |
name = '*.' + name; | |
} else if (results[this.question.type]) { | |
type = this.question.type; | |
ret = results; | |
} else if (results[CNAME]) { | |
type = CNAME; | |
ret = results; | |
this.name = name = results[CNAME][0].data | |
} | |
if (ret) { | |
ret = ret[type]; | |
ret.forEach(function (r) { | |
var rr, k; | |
if (self.wildcard && /^\*/.test(r.name)) { | |
rr = {}; | |
for (k in r) { | |
rr[k] = r[k]; | |
} | |
rr.name = self.name; | |
} else { | |
rr = r; | |
} | |
self.results.push(rr); | |
}); | |
} | |
if (name) | |
this.store.get(this.zone, ensure_absolute(name), this.lookup.bind(this)); | |
else | |
this.send(); | |
}; | |
},{"dgram":2,"events":8,"native-dns-packet":30,"net":2,"util":15}],27:[function(require,module,exports){ | |
(function (process){ | |
// Copyright 2012 Timothy J Fontaine <tjfontaine@gmail.com> | |
// | |
// Permission is hereby granted, free of charge, to any person obtaining a copy | |
// of this software and associated documentation files (the "Software"), to deal | |
// in the Software without restriction, including without limitation the rights | |
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | |
// copies of the Software, and to permit persons to whom the Software is | |
// furnished to do so, subject to the following conditions: | |
// | |
// The above copyright notice and this permission notice shall be included in | |
// all copies or substantial portions of the Software. | |
// | |
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | |
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | |
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | |
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN | |
'use strict'; | |
var MemoryStore = exports.MemoryStore = function (opts) { | |
this._store = {}; | |
}; | |
MemoryStore.prototype.get = function (domain, key, cb) { | |
var d = domain.toLowerCase(); | |
var k = key.toLowerCase(); | |
var result = this._store[d]; | |
if (result) | |
result = result[k]; | |
process.nextTick(function () { | |
cb(null, result); | |
}); | |
}; | |
MemoryStore.prototype.set = function (domain, key, data, cb) { | |
var d = domain.toLowerCase(); | |
var k = key.toLowerCase(); | |
var result_domain = this._store[d]; | |
if (!result_domain) | |
result_domain = this._store[d] = {}; | |
result_domain[k] = data; | |
if (cb) { | |
process.nextTick(function () { | |
cb(null, data); | |
}); | |
} | |
}; | |
MemoryStore.prototype.delete = function (domain, key, type, cb) { | |
var d, k; | |
if (!cb) { | |
cb = type; | |
type = undefined; | |
} | |
if (!cb) { | |
cb = key; | |
type = undefined; | |
} | |
d = this._store[domain.toLowerCase()]; | |
if (d && key) | |
k = d[key.toLowerCase()]; | |
if (domain && key && type) { | |
if (d && k) { | |
delete k[type]; | |
} | |
} else if (domain && key) { | |
if (d) { | |
delete d[k]; | |
} | |
} else if (domain) { | |
if (d) { | |
delete this._store[domain.toLowerCase()]; | |
} | |
} | |
if (cb) { | |
process.nextTick(function () { | |
cb(null, domain); | |
}); | |
} | |
}; | |
}).call(this,require('_process')) | |
},{"_process":13}],28:[function(require,module,exports){ | |
// Copyright 2012 Timothy J Fontaine <tjfontaine@gmail.com> | |
// | |
// Permission is hereby granted, free of charge, to any person obtaining a copy | |
// of this software and associated documentation files (the "Software"), to deal | |
// in the Software without restriction, including without limitation the rights | |
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | |
// copies of the Software, and to permit persons to whom the Software is | |
// furnished to do so, subject to the following conditions: | |
// | |
// The above copyright notice and this permission notice shall be included in | |
// all copies or substantial portions of the Software. | |
// | |
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | |
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | |
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | |
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN | |
// THE SOFTWARE | |
'use strict'; | |
var assert = require('assert'); | |
var Heap = function(min) { | |
this.length = 0; | |
this.root = undefined; | |
if (min) { | |
this._comparator = this._smallest; | |
} else { | |
this._comparator = this._largest; | |
} | |
}; | |
Heap.init = function(obj, key) { | |
obj._parent = null; | |
obj._left = null; | |
obj._right = null; | |
obj._key = key; | |
return obj; | |
}; | |
Heap.prototype.count = function (node) { | |
if (!node) return 0; | |
var c = 1; | |
c += this.count(node._left); | |
c += this.count(node._right); | |
return c; | |
}; | |
Heap.prototype.insert = function(obj, key) { | |
var insert, node; | |
this.length += 1; | |
node = Heap.init(obj, key); | |
if (!this.root) { | |
this.root = node; | |
} else { | |
insert = this._last(); | |
node._parent = insert; | |
if (!insert._left) | |
insert._left = node; | |
else | |
insert._right = node; | |
this._up(node); | |
} | |
this._head(); | |
return node; | |
}; | |
Heap.prototype.pop = function() { | |
var ret, last; | |
if (!this.root) | |
return null; | |
return this.remove(this.root); | |
}; | |
Heap.prototype.remove = function(node) { | |
var ret, last; | |
ret = node; | |
last = this._last(); | |
if (last._right) | |
last = last._right; | |
else | |
last = last._left; | |
this.length -= 1; | |
if (!last) { | |
if (ret == this.root) | |
this.root = null; | |
return ret; | |
} | |
if (ret == last) { | |
if (ret._parent._left == node) | |
ret._parent._left = null; | |
else | |
ret._parent._right = null; | |
last = ret._parent; | |
ret._parent = null; | |
} else if (!ret._left && !ret._right) { | |
// we're trying to remove an element without any children and its not the last | |
// move the last under its parent and heap-up | |
if (last._parent._left == last) last._parent._left = null; | |
else last._parent._right = null; | |
if (ret._parent._left == ret) ret._parent._left = last; | |
else ret._parent._right = last; | |
last._parent = ret._parent; | |
ret._parent = null; | |
// TODO in this case we shouldn't later also do a down, but it should only visit once | |
this._up(last); | |
} else { | |
this._delete_swap(ret, last); | |
} | |
if (ret == this.root) | |
this.root = last; | |
this._down(last); | |
this._head(); | |
return ret; | |
}; | |
// TODO this probably isn't the most efficient way to ensure that we're always | |
// at the root of the tree, but it works for now | |
Heap.prototype._head = function() { | |
if (!this.root) | |
return; | |
var tmp = this.root; | |
while (tmp._parent) { | |
tmp = tmp._parent; | |
} | |
this.root = tmp; | |
}; | |
// TODO is there a more efficient way to store this instead of an array? | |
Heap.prototype._last = function() { | |
var path, pos, mod, insert; | |
pos = this.length; | |
path = []; | |
while (pos > 1) { | |
mod = pos % 2; | |
pos = Math.floor(pos / 2); | |
path.push(mod); | |
} | |
insert = this.root; | |
while (path.length > 1) { | |
pos = path.pop(); | |
if (pos === 0) | |
insert = insert._left; | |
else | |
insert = insert._right; | |
} | |
return insert; | |
}; | |
Heap.prototype._swap = function(a, b) { | |
var cleft, cright, tparent; | |
cleft = b._left; | |
cright = b._right; | |
if (a._parent) { | |
if (a._parent._left == a) a._parent._left = b; | |
else a._parent._right = b; | |
} | |
b._parent = a._parent; | |
a._parent = b; | |
// This assumes direct descendents | |
if (a._left == b) { | |
b._left = a; | |
b._right = a._right; | |
if (b._right) b._right._parent = b; | |
} else { | |
b._right = a; | |
b._left = a._left; | |
if (b._left) b._left._parent = b; | |
} | |
a._left = cleft; | |
a._right = cright; | |
if (a._left) a._left._parent = a; | |
if (a._right) a._right._parent = a; | |
assert.notEqual(a._parent, a, "A shouldn't refer to itself"); | |
assert.notEqual(b._parent, b, "B shouldn't refer to itself"); | |
}; | |
Heap.prototype._delete_swap = function(a, b) { | |
if (a._left != b) b._left = a._left; | |
if (a._right != b) b._right = a._right; | |
if (b._parent._left == b) b._parent._left = null; | |
else b._parent._right = null; | |
if (a._parent) { | |
if (a._parent._left == a) a._parent._left = b; | |
else a._parent._right = b; | |
} | |
b._parent = a._parent; | |
if (b._left) b._left._parent = b; | |
if (b._right) b._right._parent = b; | |
a._parent = null; | |
a._left = null; | |
a._right = null; | |
}; | |
Heap.prototype._smallest = function(heap) { | |
var small = heap; | |
if (heap._left && heap._key > heap._left._key) { | |
small = heap._left; | |
} | |
if (heap._right && small._key > heap._right._key) { | |
small = heap._right; | |
} | |
return small; | |
}; | |
Heap.prototype._largest = function(heap) { | |
var large = heap; | |
if (heap._left && heap._key < heap._left._key) { | |
large = heap._left; | |
} | |
if (heap._right && large._key < heap._right._key) { | |
large = heap._right; | |
} | |
return large; | |
}; | |
Heap.prototype._up = function(node) { | |
if (!node || !node._parent) | |
return; | |
var next = this._comparator(node._parent); | |
if (next != node._parent) { | |
this._swap(node._parent, node); | |
this._up(node); | |
} | |
}; | |
Heap.prototype._down = function(node) { | |
if (!node) | |
return; | |
var next = this._comparator(node); | |
if (next != node) { | |
this._swap(node, next); | |
this._down(node); | |
} | |
}; | |
var util = require('util'); | |
Heap.prototype.print = function(stream) { | |
stream.write('digraph {\n'); | |
Heap._print(this.root, stream); | |
stream.write('}\n'); | |
}; | |
Heap._print = function(heap, stream) { | |
if (!heap) return; | |
if (heap._left) { | |
stream.write(util.format('' + heap._key, '->', heap._left._key, '\n')); | |
Heap._print(heap._left, stream); | |
} | |
if (heap._right) { | |
stream.write(util.format('' + heap._key, '->', heap._right._key, '\n')); | |
Heap._print(heap._right, stream); | |
} | |
}; | |
module.exports = Heap; | |
},{"assert":3,"util":15}],29:[function(require,module,exports){ | |
// Copyright 2011 Timothy J Fontaine <tjfontaine@gmail.com> | |
// | |
// Permission is hereby granted, free of charge, to any person obtaining a copy | |
// of this software and associated documentation files (the "Software"), to deal | |
// in the Software without restriction, including without limitation the rights | |
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | |
// copies of the Software, and to permit persons to whom the Software is | |
// furnished to do so, subject to the following conditions: | |
// | |
// The above copyright notice and this permission notice shall be included in | |
// all copies or substantial portions of the Software. | |
// | |
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | |
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | |
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | |
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN | |
// THE SOFTWARE | |
'use strict'; | |
function reverse_map(src) { | |
var dst = {}, | |
k; | |
for (k in src) { | |
if (src.hasOwnProperty(k)) { | |
dst[src[k]] = k; | |
} | |
} | |
return dst; | |
} | |
/* http://www.iana.org/assignments/dns-parameters */ | |
var NAME_TO_QTYPE = exports.NAME_TO_QTYPE = { | |
A: 1, | |
NS: 2, | |
MD: 3, | |
MF: 4, | |
CNAME: 5, | |
SOA: 6, | |
MB: 7, | |
MG: 8, | |
MR: 9, | |
'NULL': 10, | |
WKS: 11, | |
PTR: 12, | |
HINFO: 13, | |
MINFO: 14, | |
MX: 15, | |
TXT: 16, | |
RP: 17, | |
AFSDB: 18, | |
X25: 19, | |
ISDN: 20, | |
RT: 21, | |
NSAP: 22, | |
'NSAP-PTR': 23, | |
SIG: 24, | |
KEY: 25, | |
PX: 26, | |
GPOS: 27, | |
AAAA: 28, | |
LOC: 29, | |
NXT: 30, | |
EID: 31, | |
NIMLOC: 32, | |
SRV: 33, | |
ATMA: 34, | |
NAPTR: 35, | |
KX: 36, | |
CERT: 37, | |
A6: 38, | |
DNAME: 39, | |
SINK: 40, | |
OPT: 41, | |
APL: 42, | |
DS: 43, | |
SSHFP: 44, | |
IPSECKEY: 45, | |
RRSIG: 46, | |
NSEC: 47, | |
DNSKEY: 48, | |
DHCID: 49, | |
NSEC3: 50, | |
NSEC3PARAM: 51, | |
TLSA: 52, | |
HIP: 55, | |
NINFO: 56, | |
RKEY: 57, | |
TALINK: 58, | |
CDS: 59, | |
SPF: 99, | |
UINFO: 100, | |
UID: 101, | |
GID: 102, | |
UNSPEC: 103, | |
TKEY: 249, | |
TSIG: 250, | |
IXFR: 251, | |
AXFR: 252, | |
MAILB: 253, | |
MAILA: 254, | |
ANY: 255, | |
URI: 256, | |
CAA: 257, | |
TA: 32768, | |
DLV: 32769 | |
}; | |
exports.QTYPE_TO_NAME = reverse_map(NAME_TO_QTYPE); | |
exports.nameToQtype = function(n) { | |
return NAME_TO_QTYPE[n.toUpperCase()]; | |
}; | |
exports.qtypeToName = function(t) { | |
return exports.QTYPE_TO_NAME[t]; | |
}; | |
var NAME_TO_QCLASS = exports.NAME_TO_QCLASS = { | |
IN: 1 | |
}; | |
exports.QCLASS_TO_NAME = reverse_map(NAME_TO_QCLASS); | |
exports.FAMILY_TO_QTYPE = { | |
4: NAME_TO_QTYPE.A, | |
6: NAME_TO_QTYPE.AAAA | |
}; | |
exports.QTYPE_TO_FAMILY = {}; | |
exports.QTYPE_TO_FAMILY[exports.NAME_TO_QTYPE.A] = 4; | |
exports.QTYPE_TO_FAMILY[exports.NAME_TO_QTYPE.AAAA] = 6; | |
exports.NAME_TO_RCODE = { | |
NOERROR: 0, | |
FORMERR: 1, | |
SERVFAIL: 2, | |
NOTFOUND: 3, | |
NOTIMP: 4, | |
REFUSED: 5, | |
YXDOMAIN: 6, //Name Exists when it should not | |
YXRRSET: 7, //RR Set Exists when it should not | |
NXRRSET: 8, //RR Set that should exist does not | |
NOTAUTH: 9, | |
NOTZONE: 10, | |
BADVERS: 16, | |
BADSIG: 16, // really? | |
BADKEY: 17, | |
BADTIME: 18, | |
BADMODE: 19, | |
BADNAME: 20, | |
BADALG: 21, | |
BADTRUNC: 22 | |
}; | |
exports.RCODE_TO_NAME = reverse_map(exports.NAME_TO_RCODE); | |
exports.BADNAME = 'EBADNAME'; | |
exports.BADRESP = 'EBADRESP'; | |
exports.CONNREFUSED = 'ECONNREFUSED'; | |
exports.DESTRUCTION = 'EDESTRUCTION'; | |
exports.REFUSED = 'EREFUSED'; | |
exports.FORMERR = 'EFORMERR'; | |
exports.NODATA = 'ENODATA'; | |
exports.NOMEM = 'ENOMEM'; | |
exports.NOTFOUND = 'ENOTFOUND'; | |
exports.NOTIMP = 'ENOTIMP'; | |
exports.SERVFAIL = 'ESERVFAIL'; | |
exports.TIMEOUT = 'ETIMEOUT'; | |
},{}],30:[function(require,module,exports){ | |
module.exports = require('./packet'); | |
module.exports.consts = require('./consts'); | |
},{"./consts":29,"./packet":35}],31:[function(require,module,exports){ | |
// Copyright 2012 Timothy J Fontaine <tjfontaine@gmail.com> | |
// | |
// Permission is hereby granted, free of charge, to any person obtaining a copy | |
// of this software and associated documentation files (the "Software"), to deal | |
// in the Software without restriction, including without limitation the rights | |
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | |
// copies of the Software, and to permit persons to whom the Software is | |
// furnished to do so, subject to the following conditions: | |
// | |
// The above copyright notice and this permission notice shall be included in | |
// all copies or substantial portions of the Software. | |
// | |
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | |
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | |
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | |
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN | |
// THE SOFTWARE | |
var util = require('util'); | |
var VError = require('verror'); | |
var BufferCursor = module.exports = function(buff, noAssert) { | |
if (!(this instanceof BufferCursor)) | |
return new BufferCursor(buff, noAssert); | |
this._pos = 0; | |
this._noAssert = noAssert; | |
if (this._noAssert === undefined) | |
this._noAssert = true; | |
this.buffer = buff; | |
this.length = buff.length; | |
}; | |
var BCO = BufferCursor.BufferCursorOverflow = function(length, pos, size) { | |
this.kind = 'BufferCursorOverflow'; | |
this.length = length; | |
this.position = pos; | |
this.size = size; | |
VError.call(this, | |
'BufferCursorOverflow: length %d, position %d, size %d', | |
length, | |
pos, | |
size); | |
}; | |
util.inherits(BCO, VError); | |
BufferCursor.prototype._move = function(step) { | |
this._checkWrite(step); | |
this._pos += step; | |
}; | |
BufferCursor.prototype._checkWrite = function(size) { | |
var shouldThrow = false; | |
var length = this.length; | |
var pos = this._pos; | |
if (size > length) | |
shouldThrow = true; | |
if (length - pos < size) | |
shouldThrow = true; | |
if (shouldThrow) { | |
var bco = new BCO(length, | |
pos, | |
size); | |
throw bco; | |
} | |
} | |
BufferCursor.prototype.seek = function(pos) { | |
if (pos < 0) | |
throw new VError(new RangeError('Cannot seek before start of buffer'), | |
'Negative seek values not allowed: %d', pos); | |
if (pos > this.length) | |
throw new VError(new RangeError('Trying to seek beyond buffer'), | |
'Requested %d position is beyond length %d', | |
pos, this.length); | |
this._pos = pos; | |
return this; | |
}; | |
BufferCursor.prototype.eof = function() { | |
return this._pos == this.length; | |
}; | |
BufferCursor.prototype.toByteArray = function(method) { | |
var arr = [], i, part, count; | |
if (!method) { | |
method = 'readUInt8'; | |
part = 1; | |
} | |
if (method.indexOf('16') > 0) | |
part = 2; | |
else if (method.indexOf('32') > 0) | |
part = 4; | |
count = this.length / part; | |
for (i = 0; i < this.buffer.length; i += part) { | |
arr.push(this.buffer[method](i)); | |
} | |
return arr; | |
}; | |
BufferCursor.prototype.tell = function() { | |
return this._pos; | |
}; | |
BufferCursor.prototype.slice = function(length) { | |
var end, b; | |
if (length === undefined) { | |
end = this.length; | |
} else { | |
end = this._pos + length; | |
} | |
b = new BufferCursor(this.buffer.slice(this._pos, end)); | |
this.seek(end); | |
return b; | |
}; | |
BufferCursor.prototype.toString = function(encoding, length) { | |
var end, ret; | |
if (length === undefined) { | |
end = this.length; | |
} else { | |
end = this._pos + length; | |
} | |
if (!encoding) { | |
encoding = 'utf8'; | |
} | |
ret = this.buffer.toString(encoding, this._pos, end); | |
this.seek(end); | |
return ret; | |
}; | |
// This method doesn't need to _checkWrite because Buffer implicitly truncates | |
// to the length of the buffer, it's the only method in Node core that behaves | |
// this way by default | |
BufferCursor.prototype.write = function(value, length, encoding) { | |
var end, ret; | |
ret = this.buffer.write(value, this._pos, length, encoding); | |
this._move(ret); | |
return this; | |
}; | |
BufferCursor.prototype.fill = function(value, length) { | |
var end; | |
if (length === undefined) { | |
end = this.length; | |
} else { | |
end = this._pos + length; | |
} | |
this._checkWrite(end - this._pos); | |
this.buffer.fill(value, this._pos, end); | |
this.seek(end); | |
return this; | |
}; | |
// This prototype is not entirely like the upstream Buffer.copy, instead it | |
// is the target buffer, and accepts the source buffer -- since the target | |
// buffer knows its starting position | |
BufferCursor.prototype.copy = function copy(source, sourceStart, sourceEnd) { | |
var sBC = source instanceof BufferCursor; | |
if (isNaN(sourceEnd)) | |
sourceEnd = source.length; | |
if (isNaN(sourceStart)) { | |
if (sBC) | |
sourceStart = source._pos; | |
else | |
sourceStart = 0; | |
} | |
var length = sourceEnd - sourceStart; | |
this._checkWrite(length); | |
var buf = sBC ? source.buffer : source; | |
buf.copy(this.buffer, this._pos, sourceStart, sourceEnd); | |
this._move(length); | |
return this; | |
}; | |
BufferCursor.prototype.readUInt8 = function() { | |
var ret = this.buffer.readUInt8(this._pos, this._noAssert); | |
this._move(1); | |
return ret; | |
}; | |
BufferCursor.prototype.readInt8 = function() { | |
var ret = this.buffer.readInt8(this._pos, this._noAssert); | |
this._move(1); | |
return ret; | |
}; | |
BufferCursor.prototype.readInt16BE = function() { | |
var ret = this.buffer.readInt16BE(this._pos, this._noAssert); | |
this._move(2); | |
return ret; | |
}; | |
BufferCursor.prototype.readInt16LE = function() { | |
var ret = this.buffer.readInt16LE(this._pos, this._noAssert); | |
this._move(2); | |
return ret; | |
}; | |
BufferCursor.prototype.readUInt16BE = function() { | |
var ret = this.buffer.readUInt16BE(this._pos, this._noAssert); | |
this._move(2); | |
return ret; | |
}; | |
BufferCursor.prototype.readUInt16LE = function() { | |
var ret = this.buffer.readUInt16LE(this._pos, this._noAssert); | |
this._move(2); | |
return ret; | |
}; | |
BufferCursor.prototype.readUInt32LE = function() { | |
var ret = this.buffer.readUInt32LE(this._pos, this._noAssert); | |
this._move(4); | |
return ret; | |
}; | |
BufferCursor.prototype.readUInt32BE = function() { | |
var ret = this.buffer.readUInt32BE(this._pos, this._noAssert); | |
this._move(4); | |
return ret; | |
}; | |
BufferCursor.prototype.readInt32LE = function() { | |
var ret = this.buffer.readInt32LE(this._pos, this._noAssert); | |
this._move(4); | |
return ret; | |
}; | |
BufferCursor.prototype.readInt32BE = function() { | |
var ret = this.buffer.readInt32BE(this._pos, this._noAssert); | |
this._move(4); | |
return ret; | |
}; | |
BufferCursor.prototype.readFloatBE = function() { | |
var ret = this.buffer.readFloatBE(this._pos, this._noAssert); | |
this._move(4); | |
return ret; | |
}; | |
BufferCursor.prototype.readFloatLE = function() { | |
var ret = this.buffer.readFloatLE(this._pos, this._noAssert); | |
this._move(4); | |
return ret; | |
}; | |
BufferCursor.prototype.readDoubleBE = function() { | |
var ret = this.buffer.readDoubleBE(this._pos, this._noAssert); | |
this._move(8); | |
return ret; | |
}; | |
BufferCursor.prototype.readDoubleLE = function() { | |
var ret = this.buffer.readDoubleLE(this._pos, this._noAssert); | |
this._move(8); | |
return ret; | |
}; | |
BufferCursor.prototype.writeUInt8 = function(value) { | |
this._checkWrite(1); | |
this.buffer.writeUInt8(value, this._pos, this._noAssert); | |
this._move(1); | |
return this; | |
}; | |
BufferCursor.prototype.writeInt8 = function(value) { | |
this._checkWrite(1); | |
this.buffer.writeInt8(value, this._pos, this._noAssert); | |
this._move(1); | |
return this; | |
}; | |
BufferCursor.prototype.writeUInt16BE = function(value) { | |
this._checkWrite(2); | |
this.buffer.writeUInt16BE(value, this._pos, this._noAssert); | |
this._move(2); | |
return this; | |
}; | |
BufferCursor.prototype.writeUInt16LE = function(value) { | |
this._checkWrite(2); | |
this.buffer.writeUInt16LE(value, this._pos, this._noAssert); | |
this._move(2); | |
return this; | |
}; | |
BufferCursor.prototype.writeInt16BE = function(value) { | |
this._checkWrite(2); | |
this.buffer.writeInt16BE(value, this._pos, this._noAssert); | |
this._move(2); | |
return this; | |
}; | |
BufferCursor.prototype.writeInt16LE = function(value) { | |
this._checkWrite(2); | |
this.buffer.writeInt16LE(value, this._pos, this._noAssert); | |
this._move(2); | |
return this; | |
}; | |
BufferCursor.prototype.writeUInt32BE = function(value) { | |
this._checkWrite(4); | |
this.buffer.writeUInt32BE(value, this._pos, this._noAssert); | |
this._move(4); | |
return this; | |
}; | |
BufferCursor.prototype.writeUInt32LE = function(value) { | |
this._checkWrite(4); | |
this.buffer.writeUInt32LE(value, this._pos, this._noAssert); | |
this._move(4); | |
return this; | |
}; | |
BufferCursor.prototype.writeInt32BE = function(value) { | |
this._checkWrite(4); | |
this.buffer.writeInt32BE(value, this._pos, this._noAssert); | |
this._move(4); | |
return this; | |
}; | |
BufferCursor.prototype.writeInt32LE = function(value) { | |
this._checkWrite(4); | |
this.buffer.writeInt32LE(value, this._pos, this._noAssert); | |
this._move(4); | |
return this; | |
}; | |
BufferCursor.prototype.writeFloatBE = function(value) { | |
this._checkWrite(4); | |
this.buffer.writeFloatBE(value, this._pos, this._noAssert); | |
this._move(4); | |
return this; | |
}; | |
BufferCursor.prototype.writeFloatLE = function(value) { | |
this._checkWrite(4); | |
this.buffer.writeFloatLE(value, this._pos, this._noAssert); | |
this._move(4); | |
return this; | |
}; | |
BufferCursor.prototype.writeDoubleBE = function(value) { | |
this._checkWrite(8); | |
this.buffer.writeDoubleBE(value, this._pos, this._noAssert); | |
this._move(8); | |
return this; | |
}; | |
BufferCursor.prototype.writeDoubleLE = function(value) { | |
this._checkWrite(8); | |
this.buffer.writeDoubleLE(value, this._pos, this._noAssert); | |
this._move(8); | |
return this; | |
}; | |
},{"util":15,"verror":32}],32:[function(require,module,exports){ | |
/* | |
* verror.js: richer JavaScript errors | |
*/ | |
var mod_assert = require('assert'); | |
var mod_util = require('util'); | |
var mod_extsprintf = require('extsprintf'); | |
var mod_isError = require('core-util-is').isError; | |
/* | |
* Public interface | |
*/ | |
/* So you can 'var VError = require('verror')' */ | |
module.exports = VError; | |
/* For compatibility */ | |
VError.VError = VError; | |
/* Other exported classes */ | |
VError.SError = SError; | |
VError.WError = WError; | |
VError.MultiError = MultiError; | |
/* | |
* VError([cause], fmt[, arg...]): Like JavaScript's built-in Error class, but | |
* supports a "cause" argument (another error) and a printf-style message. The | |
* cause argument can be null or omitted entirely. | |
* | |
* Examples: | |
* | |
* CODE MESSAGE | |
* new VError('something bad happened') "something bad happened" | |
* new VError('missing file: "%s"', file) "missing file: "/etc/passwd" | |
* with file = '/etc/passwd' | |
* new VError(err, 'open failed') "open failed: file not found" | |
* with err.message = 'file not found' | |
*/ | |
function VError(options) | |
{ | |
var args, obj, causedBy, ctor, tailmsg; | |
/* | |
* This is a regrettable pattern, but JavaScript's built-in Error class | |
* is defined to work this way, so we allow the constructor to be called | |
* without "new". | |
*/ | |
if (!(this instanceof VError)) { | |
args = Array.prototype.slice.call(arguments, 0); | |
obj = Object.create(VError.prototype); | |
VError.apply(obj, arguments); | |
return (obj); | |
} | |
if (mod_isError(options) || typeof (options) === 'object') { | |
args = Array.prototype.slice.call(arguments, 1); | |
} else { | |
args = Array.prototype.slice.call(arguments, 0); | |
options = undefined; | |
} | |
/* | |
* extsprintf (which we invoke here with our caller's arguments in order | |
* to construct this Error's message) is strict in its interpretation of | |
* values to be processed by the "%s" specifier. The value passed to | |
* extsprintf must actually be a string or something convertible to a | |
* String using .toString(). Passing other values (notably "null" and | |
* "undefined") is considered a programmer error. The assumption is | |
* that if you actually want to print the string "null" or "undefined", | |
* then that's easy to do that when you're calling extsprintf; on the | |
* other hand, if you did NOT want that (i.e., there's actually a bug | |
* where the program assumes some variable is non-null and tries to | |
* print it, which might happen when constructing a packet or file in | |
* some specific format), then it's better to stop immediately than | |
* produce bogus output. | |
* | |
* However, sometimes the bug is only in the code calling VError, and a | |
* programmer might prefer to have the error message contain "null" or | |
* "undefined" rather than have the bug in the error path crash the | |
* program (making the first bug harder to identify). For that reason, | |
* by default VError converts "null" or "undefined" arguments to their | |
* string representations and passes those to extsprintf. Programmers | |
* desiring the strict behavior can use the SError class or pass the | |
* "strict" option to the VError constructor. | |
*/ | |
if (!options || !options.strict) { | |
args = args.map(function (a) { | |
return (a === null ? 'null' : | |
a === undefined ? 'undefined' : a); | |
}); | |
} | |
tailmsg = args.length > 0 ? | |
mod_extsprintf.sprintf.apply(null, args) : ''; | |
this.jse_shortmsg = tailmsg; | |
this.jse_summary = tailmsg; | |
if (options) { | |
causedBy = options.cause; | |
if (!causedBy || !mod_isError(options.cause)) | |
causedBy = options; | |
if (causedBy && mod_isError(causedBy)) { | |
this.jse_cause = causedBy; | |
this.jse_summary += ': ' + causedBy.message; | |
} | |
} | |
this.message = this.jse_summary; | |
Error.call(this, this.jse_summary); | |
if (Error.captureStackTrace) { | |
ctor = options ? options.constructorOpt : undefined; | |
ctor = ctor || arguments.callee; | |
Error.captureStackTrace(this, ctor); | |
} | |
return (this); | |
} | |
mod_util.inherits(VError, Error); | |
VError.prototype.name = 'VError'; | |
VError.prototype.toString = function ve_toString() | |
{ | |
var str = (this.hasOwnProperty('name') && this.name || | |
this.constructor.name || this.constructor.prototype.name); | |
if (this.message) | |
str += ': ' + this.message; | |
return (str); | |
}; | |
VError.prototype.cause = function ve_cause() | |
{ | |
return (this.jse_cause); | |
}; | |
/* | |
* SError is like VError, but stricter about types. You cannot pass "null" or | |
* "undefined" as string arguments to the formatter. Since SError is only a | |
* different function, not really a different class, we don't set | |
* SError.prototype.name. | |
*/ | |
function SError() | |
{ | |
var fmtargs, opts, key, args; | |
opts = {}; | |
opts.constructorOpt = SError; | |
if (mod_isError(arguments[0])) { | |
opts.cause = arguments[0]; | |
fmtargs = Array.prototype.slice.call(arguments, 1); | |
} else if (typeof (arguments[0]) == 'object') { | |
for (key in arguments[0]) | |
opts[key] = arguments[0][key]; | |
fmtargs = Array.prototype.slice.call(arguments, 1); | |
} else { | |
fmtargs = Array.prototype.slice.call(arguments, 0); | |
} | |
opts.strict = true; | |
args = [ opts ].concat(fmtargs); | |
VError.apply(this, args); | |
} | |
mod_util.inherits(SError, VError); | |
/* | |
* Represents a collection of errors for the purpose of consumers that generally | |
* only deal with one error. Callers can extract the individual errors | |
* contained in this object, but may also just treat it as a normal single | |
* error, in which case a summary message will be printed. | |
*/ | |
function MultiError(errors) | |
{ | |
mod_assert.ok(errors.length > 0); | |
this.ase_errors = errors; | |
VError.call(this, errors[0], 'first of %d error%s', | |
errors.length, errors.length == 1 ? '' : 's'); | |
} | |
mod_util.inherits(MultiError, VError); | |
/* | |
* Like JavaScript's built-in Error class, but supports a "cause" argument which | |
* is wrapped, not "folded in" as with VError. Accepts a printf-style message. | |
* The cause argument can be null. | |
*/ | |
function WError(options) | |
{ | |
Error.call(this); | |
var args, cause, ctor; | |
if (typeof (options) === 'object') { | |
args = Array.prototype.slice.call(arguments, 1); | |
} else { | |
args = Array.prototype.slice.call(arguments, 0); | |
options = undefined; | |
} | |
if (args.length > 0) { | |
this.message = mod_extsprintf.sprintf.apply(null, args); | |
} else { | |
this.message = ''; | |
} | |
if (options) { | |
if (mod_isError(options)) { | |
cause = options; | |
} else { | |
cause = options.cause; | |
ctor = options.constructorOpt; | |
} | |
} | |
Error.captureStackTrace(this, ctor || this.constructor); | |
if (cause) | |
this.cause(cause); | |
} | |
mod_util.inherits(WError, Error); | |
WError.prototype.name = 'WError'; | |
WError.prototype.toString = function we_toString() | |
{ | |
var str = (this.hasOwnProperty('name') && this.name || | |
this.constructor.name || this.constructor.prototype.name); | |
if (this.message) | |
str += ': ' + this.message; | |
if (this.we_cause && this.we_cause.message) | |
str += '; caused by ' + this.we_cause.toString(); | |
return (str); | |
}; | |
WError.prototype.cause = function we_cause(c) | |
{ | |
if (mod_isError(c)) | |
this.we_cause = c; | |
return (this.we_cause); | |
}; | |
},{"assert":3,"core-util-is":33,"extsprintf":34,"util":15}],33:[function(require,module,exports){ | |
(function (Buffer){ | |
// Copyright Joyent, Inc. and other Node contributors. | |
// | |
// Permission is hereby granted, free of charge, to any person obtaining a | |
// copy of this software and associated documentation files (the | |
// "Software"), to deal in the Software without restriction, including | |
// without limitation the rights to use, copy, modify, merge, publish, | |
// distribute, sublicense, and/or sell copies of the Software, and to permit | |
// persons to whom the Software is furnished to do so, subject to the | |
// following conditions: | |
// | |
// The above copyright notice and this permission notice shall be included | |
// in all copies or substantial portions of the Software. | |
// | |
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS | |
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | |
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN | |
// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, | |
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR | |
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE | |
// USE OR OTHER DEALINGS IN THE SOFTWARE. | |
// NOTE: These type checking functions intentionally don't use `instanceof` | |
// because it is fragile and can be easily faked with `Object.create()`. | |
function isArray(arg) { | |
if (Array.isArray) { | |
return Array.isArray(arg); | |
} | |
return objectToString(arg) === '[object Array]'; | |
} | |
exports.isArray = isArray; | |
function isBoolean(arg) { | |
return typeof arg === 'boolean'; | |
} | |
exports.isBoolean = isBoolean; | |
function isNull(arg) { | |
return arg === null; | |
} | |
exports.isNull = isNull; | |
function isNullOrUndefined(arg) { | |
return arg == null; | |
} | |
exports.isNullOrUndefined = isNullOrUndefined; | |
function isNumber(arg) { | |
return typeof arg === 'number'; | |
} | |
exports.isNumber = isNumber; | |
function isString(arg) { | |
return typeof arg === 'string'; | |
} | |
exports.isString = isString; | |
function isSymbol(arg) { | |
return typeof arg === 'symbol'; | |
} | |
exports.isSymbol = isSymbol; | |
function isUndefined(arg) { | |
return arg === void 0; | |
} | |
exports.isUndefined = isUndefined; | |
function isRegExp(re) { | |
return objectToString(re) === '[object RegExp]'; | |
} | |
exports.isRegExp = isRegExp; | |
function isObject(arg) { | |
return typeof arg === 'object' && arg !== null; | |
} | |
exports.isObject = isObject; | |
function isDate(d) { | |
return objectToString(d) === '[object Date]'; | |
} | |
exports.isDate = isDate; | |
function isError(e) { | |
return (objectToString(e) === '[object Error]' || e instanceof Error); | |
} | |
exports.isError = isError; | |
function isFunction(arg) { | |
return typeof arg === 'function'; | |
} | |
exports.isFunction = isFunction; | |
function isPrimitive(arg) { | |
return arg === null || | |
typeof arg === 'boolean' || | |
typeof arg === 'number' || | |
typeof arg === 'string' || | |
typeof arg === 'symbol' || // ES6 symbol | |
typeof arg === 'undefined'; | |
} | |
exports.isPrimitive = isPrimitive; | |
exports.isBuffer = Buffer.isBuffer; | |
function objectToString(o) { | |
return Object.prototype.toString.call(o); | |
} | |
}).call(this,{"isBuffer":require("../../../../../../../../../../grunt-browserify/node_modules/browserify/node_modules/insert-module-globals/node_modules/is-buffer/index.js")}) | |
},{"../../../../../../../../../../grunt-browserify/node_modules/browserify/node_modules/insert-module-globals/node_modules/is-buffer/index.js":10}],34:[function(require,module,exports){ | |
(function (process){ | |
/* | |
* extsprintf.js: extended POSIX-style sprintf | |
*/ | |
var mod_assert = require('assert'); | |
var mod_util = require('util'); | |
/* | |
* Public interface | |
*/ | |
exports.sprintf = jsSprintf; | |
exports.printf = jsPrintf; | |
/* | |
* Stripped down version of s[n]printf(3c). We make a best effort to throw an | |
* exception when given a format string we don't understand, rather than | |
* ignoring it, so that we won't break existing programs if/when we go implement | |
* the rest of this. | |
* | |
* This implementation currently supports specifying | |
* - field alignment ('-' flag), | |
* - zero-pad ('0' flag) | |
* - always show numeric sign ('+' flag), | |
* - field width | |
* - conversions for strings, decimal integers, and floats (numbers). | |
* - argument size specifiers. These are all accepted but ignored, since | |
* Javascript has no notion of the physical size of an argument. | |
* | |
* Everything else is currently unsupported, most notably precision, unsigned | |
* numbers, non-decimal numbers, and characters. | |
*/ | |
function jsSprintf(fmt) | |
{ | |
var regex = [ | |
'([^%]*)', /* normal text */ | |
'%', /* start of format */ | |
'([\'\\-+ #0]*?)', /* flags (optional) */ | |
'([1-9]\\d*)?', /* width (optional) */ | |
'(\\.([1-9]\\d*))?', /* precision (optional) */ | |
'[lhjztL]*?', /* length mods (ignored) */ | |
'([diouxXfFeEgGaAcCsSp%jr])' /* conversion */ | |
].join(''); | |
var re = new RegExp(regex); | |
var args = Array.prototype.slice.call(arguments, 1); | |
var flags, width, precision, conversion; | |
var left, pad, sign, arg, match; | |
var ret = ''; | |
var argn = 1; | |
mod_assert.equal('string', typeof (fmt)); | |
while ((match = re.exec(fmt)) !== null) { | |
ret += match[1]; | |
fmt = fmt.substring(match[0].length); | |
flags = match[2] || ''; | |
width = match[3] || 0; | |
precision = match[4] || ''; | |
conversion = match[6]; | |
left = false; | |
sign = false; | |
pad = ' '; | |
if (conversion == '%') { | |
ret += '%'; | |
continue; | |
} | |
if (args.length === 0) | |
throw (new Error('too few args to sprintf')); | |
arg = args.shift(); | |
argn++; | |
if (flags.match(/[\' #]/)) | |
throw (new Error( | |
'unsupported flags: ' + flags)); | |
if (precision.length > 0) | |
throw (new Error( | |
'non-zero precision not supported')); | |
if (flags.match(/-/)) | |
left = true; | |
if (flags.match(/0/)) | |
pad = '0'; | |
if (flags.match(/\+/)) | |
sign = true; | |
switch (conversion) { | |
case 's': | |
if (arg === undefined || arg === null) | |
throw (new Error('argument ' + argn + | |
': attempted to print undefined or null ' + | |
'as a string')); | |
ret += doPad(pad, width, left, arg.toString()); | |
break; | |
case 'd': | |
arg = Math.floor(arg); | |
/*jsl:fallthru*/ | |
case 'f': | |
sign = sign && arg > 0 ? '+' : ''; | |
ret += sign + doPad(pad, width, left, | |
arg.toString()); | |
break; | |
case 'x': | |
ret += doPad(pad, width, left, arg.toString(16)); | |
break; | |
case 'j': /* non-standard */ | |
if (width === 0) | |
width = 10; | |
ret += mod_util.inspect(arg, false, width); | |
break; | |
case 'r': /* non-standard */ | |
ret += dumpException(arg); | |
break; | |
default: | |
throw (new Error('unsupported conversion: ' + | |
conversion)); | |
} | |
} | |
ret += fmt; | |
return (ret); | |
} | |
function jsPrintf() { | |
process.stdout.write(jsSprintf.apply(this, arguments)); | |
} | |
function doPad(chr, width, left, str) | |
{ | |
var ret = str; | |
while (ret.length < width) { | |
if (left) | |
ret += chr; | |
else | |
ret = chr + ret; | |
} | |
return (ret); | |
} | |
/* | |
* This function dumps long stack traces for exceptions having a cause() method. | |
* See node-verror for an example. | |
*/ | |
function dumpException(ex) | |
{ | |
var ret; | |
if (!(ex instanceof Error)) | |
throw (new Error(jsSprintf('invalid type for %%r: %j', ex))); | |
/* Note that V8 prepends "ex.stack" with ex.toString(). */ | |
ret = 'EXCEPTION: ' + ex.constructor.name + ': ' + ex.stack; | |
if (ex.cause && typeof (ex.cause) === 'function') { | |
var cex = ex.cause(); | |
if (cex) { | |
ret += '\nCaused by: ' + dumpException(cex); | |
} | |
} | |
return (ret); | |
} | |
}).call(this,require('_process')) | |
},{"_process":13,"assert":3,"util":15}],35:[function(require,module,exports){ | |
(function (Buffer){ | |
// Copyright 2011 Timothy J Fontaine <tjfontaine@gmail.com> | |
// | |
// Permission is hereby granted, free of charge, to any person obtaining a copy | |
// of this software and associated documentation files (the 'Software'), to deal | |
// in the Software without restriction, including without limitation the rights | |
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | |
// copies of the Software, and to permit persons to whom the Software is | |
// furnished to do so, subject to the following conditions: | |
// | |
// The above copyright notice and this permission notice shall be included in | |
// all copies or substantial portions of the Software. | |
// | |
// THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | |
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | |
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | |
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN | |
// THE SOFTWARE | |
// TODO: change the default UDP packet size that node-dns sends | |
// from 4096 to conform to these: | |
// - [requestor's payload size](https://tools.ietf.org/html/rfc6891#section-6.2.3) | |
// - [responders's payload size](https://tools.ietf.org/html/rfc6891#section-6.2.4) | |
'use strict'; | |
var consts = require('./consts'), | |
BufferCursor = require('buffercursor'), | |
BufferCursorOverflow = BufferCursor.BufferCursorOverflow, | |
ipaddr = require('ipaddr.js'), | |
assert = require('assert'), | |
util = require('util'); | |
function assertUndefined(val, msg) { | |
assert(typeof val != 'undefined', msg); | |
} | |
var Packet = module.exports = function() { | |
this.header = { | |
id: 0, | |
qr: 0, | |
opcode: 0, | |
aa: 0, | |
tc: 0, | |
rd: 1, | |
ra: 0, | |
res1: 0, | |
res2: 0, | |
res3: 0, | |
rcode: 0 | |
}; | |
this.question = []; | |
this.answer = []; | |
this.authority = []; | |
this.additional = []; | |
this.edns_options = []; // TODO: DEPRECATED! Use `.edns.options` instead! | |
this.payload = undefined; // TODO: DEPRECATED! Use `.edns.payload` instead! | |
}; | |
var LABEL_POINTER = 0xC0; | |
var isPointer = function(len) { | |
return (len & LABEL_POINTER) === LABEL_POINTER; | |
}; | |
function nameUnpack(buff) { | |
var len, comp, end, pos, part, combine = ''; | |
len = buff.readUInt8(); | |
comp = false; | |
end = buff.tell(); | |
while (len !== 0) { | |
if (isPointer(len)) { | |
len -= LABEL_POINTER; | |
len = len << 8; | |
pos = len + buff.readUInt8(); | |
if (!comp) | |
end = buff.tell(); | |
buff.seek(pos); | |
len = buff.readUInt8(); | |
comp = true; | |
continue; | |
} | |
part = buff.toString('ascii', len); | |
if (combine.length) | |
combine = combine + '.' + part; | |
else | |
combine = part; | |
len = buff.readUInt8(); | |
if (!comp) | |
end = buff.tell(); | |
} | |
buff.seek(end); | |
return combine; | |
} | |
function namePack(str, buff, index) { | |
var offset, dot, part; | |
while (str) { | |
if (index[str]) { | |
offset = (LABEL_POINTER << 8) + index[str]; | |
buff.writeUInt16BE(offset); | |
break; | |
} else { | |
index[str] = buff.tell(); | |
dot = str.indexOf('.'); | |
if (dot > -1) { | |
part = str.slice(0, dot); | |
str = str.slice(dot + 1); | |
} else { | |
part = str; | |
str = undefined; | |
} | |
buff.writeUInt8(part.length); | |
buff.write(part, part.length, 'ascii'); | |
} | |
} | |
if (!str) { | |
buff.writeUInt8(0); | |
} | |
} | |
var | |
WRITE_HEADER = 100001, | |
WRITE_TRUNCATE = 100002, | |
WRITE_QUESTION = 100003, | |
WRITE_RESOURCE_RECORD = 100004, | |
WRITE_RESOURCE_WRITE = 100005, | |
WRITE_RESOURCE_DONE = 100006, | |
WRITE_RESOURCE_END = 100007, | |
WRITE_EDNS = 100008, | |
WRITE_END = 100009, | |
WRITE_A = consts.NAME_TO_QTYPE.A, | |
WRITE_AAAA = consts.NAME_TO_QTYPE.AAAA, | |
WRITE_NS = consts.NAME_TO_QTYPE.NS, | |
WRITE_CNAME = consts.NAME_TO_QTYPE.CNAME, | |
WRITE_PTR = consts.NAME_TO_QTYPE.PTR, | |
WRITE_SPF = consts.NAME_TO_QTYPE.SPF, | |
WRITE_MX = consts.NAME_TO_QTYPE.MX, | |
WRITE_SRV = consts.NAME_TO_QTYPE.SRV, | |
WRITE_TXT = consts.NAME_TO_QTYPE.TXT, | |
WRITE_SOA = consts.NAME_TO_QTYPE.SOA, | |
WRITE_OPT = consts.NAME_TO_QTYPE.OPT, | |
WRITE_NAPTR = consts.NAME_TO_QTYPE.NAPTR, | |
WRITE_TLSA = consts.NAME_TO_QTYPE.TLSA; | |
function writeHeader(buff, packet) { | |
assert(packet.header, 'Packet requires "header"'); | |
buff.writeUInt16BE(packet.header.id & 0xFFFF); | |
var val = 0; | |
val += (packet.header.qr << 15) & 0x8000; | |
val += (packet.header.opcode << 11) & 0x7800; | |
val += (packet.header.aa << 10) & 0x400; | |
val += (packet.header.tc << 9) & 0x200; | |
val += (packet.header.rd << 8) & 0x100; | |
val += (packet.header.ra << 7) & 0x80; | |
val += (packet.header.res1 << 6) & 0x40; | |
val += (packet.header.res2 << 5) & 0x20; | |
val += (packet.header.res3 << 4) & 0x10; | |
val += packet.header.rcode & 0xF; | |
buff.writeUInt16BE(val & 0xFFFF); | |
assert(packet.question.length == 1, 'DNS requires one question'); | |
// aren't used | |
buff.writeUInt16BE(1); | |
// answer offset 6 | |
buff.writeUInt16BE(packet.answer.length & 0xFFFF); | |
// authority offset 8 | |
buff.writeUInt16BE(packet.authority.length & 0xFFFF); | |
// additional offset 10 | |
buff.writeUInt16BE(packet.additional.length & 0xFFFF); | |
return WRITE_QUESTION; | |
} | |
function writeTruncate(buff, packet, section, val) { | |
// XXX FIXME TODO truncation is currently done wrong. | |
// Quote rfc2181 section 9 | |
// The TC bit should not be set merely because some extra information | |
// could have been included, but there was insufficient room. This | |
// includes the results of additional section processing. In such cases | |
// the entire RRSet that will not fit in the response should be omitted, | |
// and the reply sent as is, with the TC bit clear. If the recipient of | |
// the reply needs the omitted data, it can construct a query for that | |
// data and send that separately. | |
// | |
// TODO IOW only set TC if we hit it in ANSWERS otherwise make sure an | |
// entire RRSet is removed during a truncation. | |
var pos; | |
buff.seek(2); | |
val = buff.readUInt16BE(); | |
val |= (1 << 9) & 0x200; | |
buff.seek(2); | |
buff.writeUInt16BE(val); | |
switch (section) { | |
case 'answer': | |
pos = 6; | |
// seek to authority and clear it and additional out | |
buff.seek(8); | |
buff.writeUInt16BE(0); | |
buff.writeUInt16BE(0); | |
break; | |
case 'authority': | |
pos = 8; | |
// seek to additional and clear it out | |
buff.seek(10); | |
buff.writeUInt16BE(0); | |
break; | |
case 'additional': | |
pos = 10; | |
break; | |
} | |
buff.seek(pos); | |
buff.writeUInt16BE(count - 1); // TODO: count not defined! | |
buff.seek(last_resource); // TODO: last_resource not defined! | |
return WRITE_END; | |
} | |
function writeQuestion(buff, val, label_index) { | |
assert(val, 'Packet requires a question'); | |
assertUndefined(val.name, 'Question requires a "name"'); | |
assertUndefined(val.type, 'Question requires a "type"'); | |
assertUndefined(val.class, 'Questionn requires a "class"'); | |
namePack(val.name, buff, label_index); | |
buff.writeUInt16BE(val.type & 0xFFFF); | |
buff.writeUInt16BE(val.class & 0xFFFF); | |
return WRITE_RESOURCE_RECORD; | |
} | |
function writeResource(buff, val, label_index, rdata) { | |
assert(val, 'Resource must be defined'); | |
assertUndefined(val.name, 'Resource record requires "name"'); | |
assertUndefined(val.type, 'Resource record requires "type"'); | |
assertUndefined(val.class, 'Resource record requires "class"'); | |
assertUndefined(val.ttl, 'Resource record requires "ttl"'); | |
namePack(val.name, buff, label_index); | |
buff.writeUInt16BE(val.type & 0xFFFF); | |
buff.writeUInt16BE(val.class & 0xFFFF); | |
buff.writeUInt32BE(val.ttl & 0xFFFFFFFF); | |
rdata.pos = buff.tell(); | |
buff.writeUInt16BE(0); // if there is rdata, then this value will be updated | |
// to the correct value by 'writeResourceDone' | |
return val.type; | |
} | |
function writeResourceDone(buff, rdata) { | |
var pos = buff.tell(); | |
buff.seek(rdata.pos); | |
buff.writeUInt16BE(pos - rdata.pos - 2); | |
buff.seek(pos); | |
return WRITE_RESOURCE_RECORD; | |
} | |
function writeIp(buff, val) { | |
//TODO XXX FIXME -- assert that address is of proper type | |
assertUndefined(val.address, 'A/AAAA record requires "address"'); | |
val = ipaddr.parse(val.address).toByteArray(); | |
val.forEach(function(b) { | |
buff.writeUInt8(b); | |
}); | |
return WRITE_RESOURCE_DONE; | |
} | |
function writeCname(buff, val, label_index) { | |
assertUndefined(val.data, 'NS/CNAME/PTR record requires "data"'); | |
namePack(val.data, buff, label_index); | |
return WRITE_RESOURCE_DONE; | |
} | |
// For <character-string> see: http://tools.ietf.org/html/rfc1035#section-3.3 | |
// For TXT: http://tools.ietf.org/html/rfc1035#section-3.3.14 | |
function writeTxt(buff, val) { | |
//TODO XXX FIXME -- split on max char string and loop | |
assertUndefined(val.data, 'TXT record requires "data"'); | |
for (var i=0,len=val.data.length; i<len; i++) { | |
var dataLen = Buffer.byteLength(val.data[i], 'utf8'); | |
buff.writeUInt8(dataLen); | |
buff.write(val.data[i], dataLen, 'utf8'); | |
} | |
return WRITE_RESOURCE_DONE; | |
} | |
function writeMx(buff, val, label_index) { | |
assertUndefined(val.priority, 'MX record requires "priority"'); | |
assertUndefined(val.exchange, 'MX record requires "exchange"'); | |
buff.writeUInt16BE(val.priority & 0xFFFF); | |
namePack(val.exchange, buff, label_index); | |
return WRITE_RESOURCE_DONE; | |
} | |
// SRV: https://tools.ietf.org/html/rfc2782 | |
// TODO: SRV fixture failing for '_xmpp-server._tcp.gmail.com.srv.js' | |
function writeSrv(buff, val, label_index) { | |
assertUndefined(val.priority, 'SRV record requires "priority"'); | |
assertUndefined(val.weight, 'SRV record requires "weight"'); | |
assertUndefined(val.port, 'SRV record requires "port"'); | |
assertUndefined(val.target, 'SRV record requires "target"'); | |
buff.writeUInt16BE(val.priority & 0xFFFF); | |
buff.writeUInt16BE(val.weight & 0xFFFF); | |
buff.writeUInt16BE(val.port & 0xFFFF); | |
namePack(val.target, buff, label_index); | |
return WRITE_RESOURCE_DONE; | |
} | |
function writeSoa(buff, val, label_index) { | |
assertUndefined(val.primary, 'SOA record requires "primary"'); | |
assertUndefined(val.admin, 'SOA record requires "admin"'); | |
assertUndefined(val.serial, 'SOA record requires "serial"'); | |
assertUndefined(val.refresh, 'SOA record requires "refresh"'); | |
assertUndefined(val.retry, 'SOA record requires "retry"'); | |
assertUndefined(val.expiration, 'SOA record requires "expiration"'); | |
assertUndefined(val.minimum, 'SOA record requires "minimum"'); | |
namePack(val.primary, buff, label_index); | |
namePack(val.admin, buff, label_index); | |
buff.writeUInt32BE(val.serial & 0xFFFFFFFF); | |
buff.writeInt32BE(val.refresh & 0xFFFFFFFF); | |
buff.writeInt32BE(val.retry & 0xFFFFFFFF); | |
buff.writeInt32BE(val.expiration & 0xFFFFFFFF); | |
buff.writeInt32BE(val.minimum & 0xFFFFFFFF); | |
return WRITE_RESOURCE_DONE; | |
} | |
// http://tools.ietf.org/html/rfc3403#section-4.1 | |
function writeNaptr(buff, val, label_index) { | |
assertUndefined(val.order, 'NAPTR record requires "order"'); | |
assertUndefined(val.preference, 'NAPTR record requires "preference"'); | |
assertUndefined(val.flags, 'NAPTR record requires "flags"'); | |
assertUndefined(val.service, 'NAPTR record requires "service"'); | |
assertUndefined(val.regexp, 'NAPTR record requires "regexp"'); | |
assertUndefined(val.replacement, 'NAPTR record requires "replacement"'); | |
buff.writeUInt16BE(val.order & 0xFFFF); | |
buff.writeUInt16BE(val.preference & 0xFFFF); | |
buff.writeUInt8(val.flags.length); | |
buff.write(val.flags, val.flags.length, 'ascii'); | |
buff.writeUInt8(val.service.length); | |
buff.write(val.service, val.service.length, 'ascii'); | |
buff.writeUInt8(val.regexp.length); | |
buff.write(val.regexp, val.regexp.length, 'ascii'); | |
namePack(val.replacement, buff, label_index); | |
return WRITE_RESOURCE_DONE; | |
} | |
// https://tools.ietf.org/html/rfc6698 | |
function writeTlsa(buff, val) { | |
assertUndefined(val.usage, 'TLSA record requires "usage"'); | |
assertUndefined(val.selector, 'TLSA record requires "selector"'); | |
assertUndefined(val.matchingtype, 'TLSA record requires "matchingtype"'); | |
assertUndefined(val.buff, 'TLSA record requires "buff"'); | |
buff.writeUInt8(val.usage); | |
buff.writeUInt8(val.selector); | |
buff.writeUInt8(val.matchingtype); | |
buff.copy(val.buff); | |
return WRITE_RESOURCE_DONE; | |
} | |
function makeEdns(packet) { | |
packet.edns = { | |
name: '', | |
type: consts.NAME_TO_QTYPE.OPT, | |
class: packet.payload, | |
options: [], | |
ttl: 0 | |
}; | |
packet.edns_options = packet.edns.options; // TODO: 'edns_options' is DEPRECATED! | |
packet.additional.push(packet.edns); | |
return WRITE_HEADER; | |
} | |
function writeOpt(buff, val) { | |
var opt; | |
for (var i=0, len=val.options.length; i<len; i++) { | |
opt = val.options[i]; | |
buff.writeUInt16BE(opt.code); | |
buff.writeUInt16BE(opt.data.length); | |
buff.copy(opt.data); | |
} | |
return WRITE_RESOURCE_DONE; | |
} | |
Packet.write = function(buff, packet) { | |
var state = WRITE_HEADER, | |
val, | |
section, | |
count, | |
rdata, | |
last_resource, | |
label_index = {}; | |
buff = new BufferCursor(buff); | |
// the existence of 'edns' in a packet indicates that a proper OPT record exists | |
// in 'additional' and that all of the other fields in packet (that are parsed by | |
// 'parseOpt') are properly set. If it does not exist, we assume that the user | |
// is requesting that we create one for them. | |
if (typeof packet.edns_version !== 'undefined' && typeof packet.edns === "undefined") | |
state = makeEdns(packet); | |
// TODO: this is unnecessarily inefficient. rewrite this using a | |
// function table instead. (same for Packet.parse too). | |
while (true) { | |
try { | |
switch (state) { | |
case WRITE_HEADER: | |
state = writeHeader(buff, packet); | |
break; | |
case WRITE_TRUNCATE: | |
state = writeTruncate(buff, packet, section, last_resource); | |
break; | |
case WRITE_QUESTION: | |
state = writeQuestion(buff, packet.question[0], label_index); | |
section = 'answer'; | |
count = 0; | |
break; | |
case WRITE_RESOURCE_RECORD: | |
last_resource = buff.tell(); | |
if (packet[section].length == count) { | |
switch (section) { | |
case 'answer': | |
section = 'authority'; | |
state = WRITE_RESOURCE_RECORD; | |
break; | |
case 'authority': | |
section = 'additional'; | |
state = WRITE_RESOURCE_RECORD; | |
break; | |
case 'additional': | |
state = WRITE_END; | |
break; | |
} | |
count = 0; | |
} else { | |
state = WRITE_RESOURCE_WRITE; | |
} | |
break; | |
case WRITE_RESOURCE_WRITE: | |
rdata = {}; | |
val = packet[section][count]; | |
state = writeResource(buff, val, label_index, rdata); | |
break; | |
case WRITE_RESOURCE_DONE: | |
count += 1; | |
state = writeResourceDone(buff, rdata); | |
break; | |
case WRITE_A: | |
case WRITE_AAAA: | |
state = writeIp(buff, val); | |
break; | |
case WRITE_NS: | |
case WRITE_CNAME: | |
case WRITE_PTR: | |
state = writeCname(buff, val, label_index); | |
break; | |
case WRITE_SPF: | |
case WRITE_TXT: | |
state = writeTxt(buff, val); | |
break; | |
case WRITE_MX: | |
state = writeMx(buff, val, label_index); | |
break; | |
case WRITE_SRV: | |
state = writeSrv(buff, val, label_index); | |
break; | |
case WRITE_SOA: | |
state = writeSoa(buff, val, label_index); | |
break; | |
case WRITE_OPT: | |
state = writeOpt(buff, val); | |
break; | |
case WRITE_NAPTR: | |
state = writeNaptr(buff, val, label_index); | |
break; | |
case WRITE_TLSA: | |
state = writeTlsa(buff, val); | |
break; | |
case WRITE_END: | |
return buff.tell(); | |
default: | |
if (typeof val.data !== 'object') | |
throw new Error('Packet.write Unknown State: ' + state); | |
// write unhandled RR type | |
buff.copy(val.data); | |
state = WRITE_RESOURCE_DONE; | |
} | |
} catch (e) { | |
if (e instanceof BufferCursorOverflow) { | |
state = WRITE_TRUNCATE; | |
} else { | |
throw e; | |
} | |
} | |
} | |
}; | |
function parseHeader(msg, packet) { | |
packet.header.id = msg.readUInt16BE(); | |
var val = msg.readUInt16BE(); | |
packet.header.qr = (val & 0x8000) >> 15; | |
packet.header.opcode = (val & 0x7800) >> 11; | |
packet.header.aa = (val & 0x400) >> 10; | |
packet.header.tc = (val & 0x200) >> 9; | |
packet.header.rd = (val & 0x100) >> 8; | |
packet.header.ra = (val & 0x80) >> 7; | |
packet.header.res1 = (val & 0x40) >> 6; | |
packet.header.res2 = (val & 0x20) >> 5; | |
packet.header.res3 = (val & 0x10) >> 4; | |
packet.header.rcode = (val & 0xF); | |
packet.question = new Array(msg.readUInt16BE()); | |
packet.answer = new Array(msg.readUInt16BE()); | |
packet.authority = new Array(msg.readUInt16BE()); | |
packet.additional = new Array(msg.readUInt16BE()); | |
return PARSE_QUESTION; | |
} | |
function parseQuestion(msg, packet) { | |
var val = {}; | |
val.name = nameUnpack(msg); | |
val.type = msg.readUInt16BE(); | |
val.class = msg.readUInt16BE(); | |
packet.question[0] = val; | |
assert(packet.question.length === 1); | |
// TODO handle qdcount > 1 in practice no one sends this | |
return PARSE_RESOURCE_RECORD; | |
} | |
function parseRR(msg, val, rdata) { | |
val.name = nameUnpack(msg); | |
val.type = msg.readUInt16BE(); | |
val.class = msg.readUInt16BE(); | |
val.ttl = msg.readUInt32BE(); | |
rdata.len = msg.readUInt16BE(); | |
return val.type; | |
} | |
function parseA(val, msg) { | |
var address = '' + | |
msg.readUInt8() + | |
'.' + msg.readUInt8() + | |
'.' + msg.readUInt8() + | |
'.' + msg.readUInt8(); | |
val.address = address; | |
return PARSE_RESOURCE_DONE; | |
} | |
function parseAAAA(val, msg) { | |
var address = ''; | |
var compressed = false; | |
for (var i = 0; i < 8; i++) { | |
if (i > 0) address += ':'; | |
// TODO zero compression | |
address += msg.readUInt16BE().toString(16); | |
} | |
val.address = address; | |
return PARSE_RESOURCE_DONE; | |
} | |
function parseCname(val, msg) { | |
val.data = nameUnpack(msg); | |
return PARSE_RESOURCE_DONE; | |
} | |
function parseTxt(val, msg, rdata) { | |
val.data = []; | |
var end = msg.tell() + rdata.len; | |
while (msg.tell() != end) { | |
var len = msg.readUInt8(); | |
val.data.push(msg.toString('utf8', len)); | |
} | |
return PARSE_RESOURCE_DONE; | |
} | |
function parseMx(val, msg, rdata) { | |
val.priority = msg.readUInt16BE(); | |
val.exchange = nameUnpack(msg); | |
return PARSE_RESOURCE_DONE; | |
} | |
// TODO: SRV fixture failing for '_xmpp-server._tcp.gmail.com.srv.js' | |
// https://tools.ietf.org/html/rfc2782 | |
function parseSrv(val, msg) { | |
val.priority = msg.readUInt16BE(); | |
val.weight = msg.readUInt16BE(); | |
val.port = msg.readUInt16BE(); | |
val.target = nameUnpack(msg); | |
return PARSE_RESOURCE_DONE; | |
} | |
function parseSoa(val, msg) { | |
val.primary = nameUnpack(msg); | |
val.admin = nameUnpack(msg); | |
val.serial = msg.readUInt32BE(); | |
val.refresh = msg.readInt32BE(); | |
val.retry = msg.readInt32BE(); | |
val.expiration = msg.readInt32BE(); | |
val.minimum = msg.readInt32BE(); | |
return PARSE_RESOURCE_DONE; | |
} | |
// http://tools.ietf.org/html/rfc3403#section-4.1 | |
function parseNaptr(val, msg) { | |
val.order = msg.readUInt16BE(); | |
val.preference = msg.readUInt16BE(); | |
var len = msg.readUInt8(); | |
val.flags = msg.toString('ascii', len); | |
len = msg.readUInt8(); | |
val.service = msg.toString('ascii', len); | |
len = msg.readUInt8(); | |
val.regexp = msg.toString('ascii', len); | |
val.replacement = nameUnpack(msg); | |
return PARSE_RESOURCE_DONE; | |
} | |
function parseTlsa(val, msg, rdata) { | |
val.usage = msg.readUInt8(); | |
val.selector = msg.readUInt8(); | |
val.matchingtype = msg.readUInt8(); | |
val.buff = msg.slice(rdata.len - 3).buffer; // 3 because of the 3 UInt8s above. | |
return PARSE_RESOURCE_DONE; | |
} | |
// https://tools.ietf.org/html/rfc6891#section-6.1.2 | |
// https://tools.ietf.org/html/rfc2671#section-4.4 | |
// - [payload size selection](https://tools.ietf.org/html/rfc6891#section-6.2.5) | |
function parseOpt(val, msg, rdata, packet) { | |
// assert first entry in additional | |
rdata.buf = msg.slice(rdata.len); | |
val.rcode = ((val.ttl & 0xFF000000) >> 20) + packet.header.rcode; | |
val.version = (val.ttl >> 16) & 0xFF; | |
val.do = (val.ttl >> 15) & 1; | |
val.z = val.ttl & 0x7F; | |
val.options = []; | |
packet.edns = val; | |
packet.edns_version = val.version; // TODO: return BADVERS for unsupported version! (Section 6.1.3) | |
// !! BEGIN DEPRECATION NOTICE !! | |
// THESE FIELDS MAY BE REMOVED IN THE FUTURE! | |
packet.edns_options = val.options; | |
packet.payload = val.class; | |
// !! END DEPRECATION NOTICE !! | |
while (!rdata.buf.eof()) { | |
val.options.push({ | |
code: rdata.buf.readUInt16BE(), | |
data: rdata.buf.slice(rdata.buf.readUInt16BE()).buffer | |
}); | |
} | |
return PARSE_RESOURCE_DONE; | |
} | |
var | |
PARSE_HEADER = 100000, | |
PARSE_QUESTION = 100001, | |
PARSE_RESOURCE_RECORD = 100002, | |
PARSE_RR_UNPACK = 100003, | |
PARSE_RESOURCE_DONE = 100004, | |
PARSE_END = 100005, | |
PARSE_A = consts.NAME_TO_QTYPE.A, | |
PARSE_NS = consts.NAME_TO_QTYPE.NS, | |
PARSE_CNAME = consts.NAME_TO_QTYPE.CNAME, | |
PARSE_SOA = consts.NAME_TO_QTYPE.SOA, | |
PARSE_PTR = consts.NAME_TO_QTYPE.PTR, | |
PARSE_MX = consts.NAME_TO_QTYPE.MX, | |
PARSE_TXT = consts.NAME_TO_QTYPE.TXT, | |
PARSE_AAAA = consts.NAME_TO_QTYPE.AAAA, | |
PARSE_SRV = consts.NAME_TO_QTYPE.SRV, | |
PARSE_NAPTR = consts.NAME_TO_QTYPE.NAPTR, | |
PARSE_OPT = consts.NAME_TO_QTYPE.OPT, | |
PARSE_SPF = consts.NAME_TO_QTYPE.SPF, | |
PARSE_TLSA = consts.NAME_TO_QTYPE.TLSA; | |
Packet.parse = function(msg) { | |
var state, | |
pos, | |
val, | |
rdata, | |
section, | |
count; | |
var packet = new Packet(); | |
pos = 0; | |
state = PARSE_HEADER; | |
msg = new BufferCursor(msg); | |
while (true) { | |
switch (state) { | |
case PARSE_HEADER: | |
state = parseHeader(msg, packet); | |
break; | |
case PARSE_QUESTION: | |
state = parseQuestion(msg, packet); | |
section = 'answer'; | |
count = 0; | |
break; | |
case PARSE_RESOURCE_RECORD: | |
// console.log('PARSE_RESOURCE_RECORD: count = %d, %s.len = %d', count, section, packet[section].length); | |
if (count === packet[section].length) { | |
switch (section) { | |
case 'answer': | |
section = 'authority'; | |
count = 0; | |
break; | |
case 'authority': | |
section = 'additional'; | |
count = 0; | |
break; | |
case 'additional': | |
state = PARSE_END; | |
break; | |
} | |
} else { | |
state = PARSE_RR_UNPACK; | |
} | |
break; | |
case PARSE_RR_UNPACK: | |
val = {}; | |
rdata = {}; | |
state = parseRR(msg, val, rdata); | |
break; | |
case PARSE_RESOURCE_DONE: | |
packet[section][count++] = val; | |
state = PARSE_RESOURCE_RECORD; | |
break; | |
case PARSE_A: | |
state = parseA(val, msg); | |
break; | |
case PARSE_AAAA: | |
state = parseAAAA(val, msg); | |
break; | |
case PARSE_NS: | |
case PARSE_CNAME: | |
case PARSE_PTR: | |
state = parseCname(val, msg); | |
break; | |
case PARSE_SPF: | |
case PARSE_TXT: | |
state = parseTxt(val, msg, rdata); | |
break; | |
case PARSE_MX: | |
state = parseMx(val, msg); | |
break; | |
case PARSE_SRV: | |
state = parseSrv(val, msg); | |
break; | |
case PARSE_SOA: | |
state = parseSoa(val, msg); | |
break; | |
case PARSE_OPT: | |
state = parseOpt(val, msg, rdata, packet); | |
break; | |
case PARSE_NAPTR: | |
state = parseNaptr(val, msg); | |
break; | |
case PARSE_TLSA: | |
state = parseTlsa(val, msg, rdata); | |
break; | |
case PARSE_END: | |
return packet; | |
default: | |
//console.log(state, val); | |
val.data = msg.slice(rdata.len); | |
state = PARSE_RESOURCE_DONE; | |
break; | |
} | |
} | |
}; | |
}).call(this,require("buffer").Buffer) | |
},{"./consts":29,"assert":3,"buffer":4,"buffercursor":31,"ipaddr.js":23,"util":15}]},{},[1]); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment