diff --git a/.jshintrc b/.jshintrc new file mode 100644 index 0000000..bfabd7f --- /dev/null +++ b/.jshintrc @@ -0,0 +1,155 @@ +{ + // Whether the scan should stop on first error. + "passfail": false, + // Maximum errors before stopping. + "maxerr": 100, + + + // Predefined globals + + // Whether the standard browser globals should be predefined. + "browser": false, + // Whether the Node.js environment globals should be predefined. + "node": true, + // Whether the Rhino environment globals should be predefined. + "rhino": false, + // Whether CouchDB globals should be predefined. + "couch": false, + // Whether the Windows Scripting Host environment globals should be predefined. + "wsh": false, + + // Whether jQuery globals should be predefined. + "jquery": false, + // Whether Prototype and Scriptaculous globals should be predefined. + "prototypejs": false, + // Whether MooTools globals should be predefined. + "mootools": false, + // Whether Dojo Toolkit globals should be predefined. + "dojo": false, + + // Custom predefined globals. + "predef": [ + "describe", "it", "before", "after" + ], + + // Development + + // Whether debugger statements should be allowed. + "debug": false, + // Whether logging globals should be predefined (console, alert, etc.). + "devel": false, + + + // ECMAScript 5 + + // Whether the "use strict"; pragma should be required. + "strict": true, + // Whether global "use strict"; should be allowed (also enables strict). + "globalstrict": true, + + + // The Good Parts + + // Whether automatic semicolon insertion should be allowed. + "asi": false, + // Whether line breaks should not be checked, e.g. `return [\n] x`. + "laxbreak": false, + // Whether bitwise operators (&, |, ^, etc.) should be forbidden. + "bitwise": false, + // Whether assignments inside `if`, `for` and `while` should be allowed. Usually + // conditions and loops are for comparison, not assignments. + "boss": true, + // Whether curly braces around all blocks should be required. + "curly": true, + // Whether `===` and `!==` should be required (instead of `==` and `!=`). + "eqeqeq": true, + // Whether `== null` comparisons should be allowed, even if `eqeqeq` is `true`. + "eqnull": false, + // Whether `eval` should be allowed. + "evil": false, + // Whether ExpressionStatement should be allowed as Programs. + "expr": true, + // Whether `for in` loops must filter with `hasOwnPrototype`. + "forin": false, + // Whether immediate invocations must be wrapped in parens, e.g. + // `( function(){}() );`. + "immed": true, + // Whether use before define should be forbidden. + "latedef": false, + // Whether functions should be allowed to be defined within loops. + "loopfunc": false, + // Whether arguments.caller and arguments.callee should be forbidden. + "noarg": false, + // Whether `.` should be forbidden in regexp literals. + "regexp": false, + // Whether unescaped first/last dash (-) inside brackets in regexps should be allowed. + "regexdash": false, + // Whether script-targeted URLs should be allowed. + "scripturl": false, + // Whether variable shadowing should be allowed. + "shadow": false, + // Whether `new function () { ... };` and `new Object;` should be allowed. + "supernew": false, + // Whether variables must be declared before used. + "undef": true, + // Whether `this` inside a non-constructor function should be allowed. + "validthis": false, + // Whether smarttabs should be allowed + // (http://www.emacswiki.org/emacs/SmartTabs). + "smarttabs": true, + // Whether the `__proto__` property should be allowed. + "proto": false, + // Whether one-case switch statements should be allowed. + "onecase": false, + // Whether non-standard (but widely adopted) globals should be predefined. + "nonstandard": false, + // Allow multiline strings. + "multistr": false, + // Whether line breaks should not be checked around commas. + "laxcomma": false, + // Whether semicolons may be ommitted for the trailing statements inside of a + // one-line blocks. + "lastsemic": false, + // Whether the `__iterator__` property should be allowed. + "iterator": false, + // Whether only function scope should be used for scope tests. + "funcscope": false, + // Whether es.next specific syntax should be allowed. + "esnext": false, + + + // Style preferences + + // Whether constructor names must be capitalized. + "newcap": false, + // Whether empty blocks should be forbidden. + "noempty": false, + // Whether using `new` for side-effects should be forbidden. + "nonew": false, + // Whether names should be checked for leading or trailing underscores + // (object._attribute would be forbidden). + "nomen": false, + // Whether only one var statement per function should be allowed. + "onevar": false, + // Whether increment and decrement (`++` and `--`) should be forbidden. + "plusplus": false, + // Whether all forms of subscript notation are allowed. + "sub": false, + // Whether trailing whitespace rules apply. + "trailing": false, + // Specify indentation. + "indent": 4, + // Whether strict whitespace rules apply. + "white": true, + + // Complexity + + // Maximum number of function parameters. + "maxparams": 6, + // Maximum block nesting depth. + "maxdepth": 3, + // Maximum number of statements per function. + "maxstatements": 25, + // Maximum cyclomatic complexity. + "maxcomplexity": 10 +} \ No newline at end of file diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 0000000..f714fc0 --- /dev/null +++ b/.travis.yml @@ -0,0 +1,4 @@ +language: node_js + +node_js: + - "0.10" \ No newline at end of file diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..5726f0c --- /dev/null +++ b/Makefile @@ -0,0 +1,16 @@ +REPORTER = spec +BASE = . +JSHINT = ./node_modules/.bin/jshint + +all: lint test + +test: + @NODE_ENV=test ./node_modules/.bin/mocha \ + --reporter $(REPORTER) + +lint: + $(JSHINT) index.js --config $(BASE)/.jshintrc && \ + $(JSHINT) ./lib --config $(BASE)/.jshintrc && \ + $(JSHINT) ./test --config $(BASE)/.jshintrc + +.PHONY: test docs \ No newline at end of file diff --git a/README.md b/README.md index 5460ef5..6c7aba0 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,15 @@ node-dns-sync ============= + +[![Build Status](https://travis-ci.org/skoranga/node-dns-sync.png)](https://travis-ci.org/skoranga/node-dns-sync) + +Sync/Blocking DNS resolve. Main usecase is in node server startup. + +### How to Use +```javascript +var dnsSync = require('dns-sync'); + +console.log(dnsSync.resolve('www.paypal.com')); //should return the IP address +console.log(dnsSync.resolve('www.yahoo.com')); +console.log(dnsSync.resolve('www.non-host.something')); //should return null +``` \ No newline at end of file diff --git a/index.js b/index.js new file mode 100644 index 0000000..204a98a --- /dev/null +++ b/index.js @@ -0,0 +1 @@ +exports = module.exports = require('./lib/dns-sync'); \ No newline at end of file diff --git a/lib/dns-sync.js b/lib/dns-sync.js new file mode 100644 index 0000000..5f63607 --- /dev/null +++ b/lib/dns-sync.js @@ -0,0 +1,31 @@ +'use strict'; + +var net = require('net'), + util = require('util'), + path = require('path'), + shell = require('shelljs'), + debug = require('debug')('dns-sync'); + +/** + * Resolve hostname to IP address, + * returns null in case of error + */ +module.exports = { + resolve: function resolve(hostname) { + var output, + nodeBinary = process.execPath, + scriptPath = path.join(__dirname, "../scripts/dns-lookup-script"), + response, + cmd = util.format('"%s" "%s" %s', nodeBinary, scriptPath, hostname); + + response = shell.exec(cmd, {silent: true}); + if (response && response.code === 0) { + output = response.output; + if (output && net.isIP(output)) { + return output; + } + } + debug('hostname', "fail to resolve hostname " + hostname); + return null; + } +}; \ No newline at end of file diff --git a/package.json b/package.json new file mode 100644 index 0000000..105bb6d --- /dev/null +++ b/package.json @@ -0,0 +1,30 @@ +{ + "name": "dns-sync", + "version": "0.1.0", + "description": "dns-sync", + "main": "index.js", + "scripts": { + "test": "make test" + }, + "homepage": "https://github.com/skoranga/node-dns-sync", + "repository": { + "type": "git", + "url": "git@github.com:skoranga/node-dns-sync.git" + }, + "keywords": [ + "dns sync", + "server startup", + "nodejs" + ], + "author": "Sanjeev Koranga", + "license": "MIT", + "readmeFilename": "README.md", + "dependencies": { + "debug" : "~0.7", + "shelljs": "~0.2" + }, + "devDependencies": { + "mocha" : "~1", + "jshint" : "*" + } +} diff --git a/scripts/dns-lookup-script.js b/scripts/dns-lookup-script.js new file mode 100644 index 0000000..9fc28fc --- /dev/null +++ b/scripts/dns-lookup-script.js @@ -0,0 +1,15 @@ +'use strict'; + +var dns = require('dns'), + name = process.argv[2], + debug = require('debug')('dns-sync'); + +dns.lookup(name, function (err, ip) { + if (err) { + process.exit(1); + debug(err); + } else { + debug(name, 'resolved to', ip); + process.stdout.write(ip); + } +}); diff --git a/test/test.js b/test/test.js new file mode 100644 index 0000000..7a0a815 --- /dev/null +++ b/test/test.js @@ -0,0 +1,19 @@ +'use strict'; + +var assert = require('assert'), + dnsSync = require('../index'); + +describe('dns sync', function () { + + it('should resolve dns', function () { + assert.ok(dnsSync.resolve('www.paypal.com')); + assert.ok(dnsSync.resolve('www.google.com')); + assert.ok(dnsSync.resolve('www.yahoo.com')); + }); + + it('should fail to resolve dns', function () { + assert.ok(!dnsSync.resolve('www.paypal.con')); + assert.ok(!dnsSync.resolve('www.not-google.first')); + assert.ok(!dnsSync.resolve('www.hello-yahoo.next')); + }); +});