Skip to content
This repository has been archived by the owner on Feb 12, 2024. It is now read-only.

Commit

Permalink
feat: /api/v0/dns
Browse files Browse the repository at this point in the history
  • Loading branch information
hacdias committed Jan 9, 2018
1 parent 624cb47 commit 8645c3e
Show file tree
Hide file tree
Showing 16 changed files with 199 additions and 1 deletion.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -40,3 +40,4 @@ test/test-data/go-ipfs-repo/LOG.old

# while testing npm5
package-lock.json
yarn.lock
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
"./src/core/runtime/config-nodejs.json": "./src/core/runtime/config-browser.json",
"./src/core/runtime/libp2p-nodejs.js": "./src/core/runtime/libp2p-browser.js",
"./src/core/runtime/repo-nodejs.js": "./src/core/runtime/repo-browser.js",
"./src/core/runtime/dns-nodejs.js": "./src/core/runtime/dns-browser.js",
"./test/utils/create-repo-nodejs.js": "./test/utils/create-repo-browser.js",
"stream": "readable-stream"
},
Expand Down
24 changes: 24 additions & 0 deletions src/cli/commands/dns.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
'use strict'
const print = require('../utils').print

module.exports = {
command: 'dns <domain>',

describe: 'Resolve DNS links',

builder: {
format: {
type: 'string'
}
},

handler (argv) {
argv.ipfs.dns(argv['domain'], (err, path) => {
if (err) {
throw err
}

print(path)
})
}
}
20 changes: 20 additions & 0 deletions src/core/components/dns.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
'use strict'

// dns-nodejs gets replaced by dns-browser when webpacked/browserified
const dns = require('../runtime/dns-nodejs')
const promisify = require('promisify-es6')

module.exports = () => {
return promisify((domain, opts, callback) => {
if (typeof domain !== 'string') {
return callback(new Error('Invalid arguments, domain must be a string'))
}

if (typeof opts === 'function') {
callback = opts
opts = {}
}

dns(domain, opts, callback)
})
}
1 change: 1 addition & 0 deletions src/core/components/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,3 +20,4 @@ exports.files = require('./files')
exports.bitswap = require('./bitswap')
exports.pubsub = require('./pubsub')
exports.dht = require('./dht')
exports.dns = require('./dns')
1 change: 1 addition & 0 deletions src/core/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,7 @@ class IPFS extends EventEmitter {
this.ping = components.ping(this)
this.pubsub = components.pubsub(this)
this.dht = components.dht(this)
this.dns = components.dns(this)

if (this._options.EXPERIMENTAL.pubsub) {
this.log('EXPERIMENTAL pubsub is enabled')
Expand Down
25 changes: 25 additions & 0 deletions src/core/runtime/dns-browser.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
'use strict'

module.exports = (domain, opts, callback) => {
domain = encodeURIComponent(domain)
let url = `https://ipfs.io/api/v0/dns?arg=${domain}`

for (const prop in opts) {
url += `&${prop}=${opts[prop]}`
}

window.fetch(url, {mode: 'cors'})
.then((response) => {
return response.json()
})
.then((response) => {
if (response.Path) {
return callback(null, response.Path)
} else {
return callback(new Error(response.Message))
}
})
.catch((error) => {
callback(error)
})
}
21 changes: 21 additions & 0 deletions src/core/runtime/dns-nodejs.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
'use strict'

const dns = require('dns')

module.exports = (domain, opts, callback) => {
dns.resolveTxt(domain, (err, records) => {
if (err) {
return callback(err, null)
}

// TODO: implement recursive option

for (const record of records) {
if (record[0].startsWith('dnslink=')) {
return callback(null, record[0].substr(8, record[0].length - 1))
}
}

callback(new Error('domain does not have a txt dnslink entry'))
})
}
24 changes: 24 additions & 0 deletions src/http/api/resources/dns.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
'use strict'

const boom = require('boom')

exports = module.exports

exports.get = (request, reply) => {
if (!request.query.arg) {
return reply({
Message: "Argument 'domain' is required",
Code: 0
}).code(400).takeover()
}

request.server.app.ipfs.dns(request.query.arg, (err, path) => {
if (err) {
return reply(boom.badRequest(err))
}

return reply({
Path: path
})
})
}
1 change: 1 addition & 0 deletions src/http/api/resources/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,3 +12,4 @@ exports.bitswap = require('./bitswap')
exports.file = require('./file')
exports.files = require('./files')
exports.pubsub = require('./pubsub')
exports.dns = require('./dns')
13 changes: 13 additions & 0 deletions src/http/api/routes/dns.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
'use strict'

const resources = require('./../resources')

module.exports = (server) => {
const api = server.select('API')

api.route({
method: '*',
path: '/api/v0/dns',
handler: resources.dns.get
})
}
1 change: 1 addition & 0 deletions src/http/api/routes/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,4 +15,5 @@ module.exports = (server) => {
require('./pubsub')(server)
require('./debug')(server)
require('./webui')(server)
require('./dns')(server)
}
2 changes: 1 addition & 1 deletion test/cli/commands.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
const expect = require('chai').expect
const runOnAndOff = require('../utils/on-and-off')

const commandCount = 59
const commandCount = 60

describe('commands', () => runOnAndOff((thing) => {
let ipfs
Expand Down
22 changes: 22 additions & 0 deletions test/cli/dns.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
/* eslint-env mocha */
'use strict'

const expect = require('chai').expect
const runOnAndOff = require('../utils/on-and-off')

describe('dns', () => runOnAndOff((thing) => {
let ipfs

before(function () {
this.timeout(60 * 1000)
ipfs = thing.ipfs
})

it('dns record for ipfs.io', function () {
this.timeout(60 * 1000)

return ipfs('ipfs.io').then((res) => {
expect(res.substr(0, 6)).to.eql('/ipfs/')
})
})
}))
19 changes: 19 additions & 0 deletions test/http-api/extra/dns.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
/* eslint-env mocha */
'use strict'

const chai = require('chai')
const dirtyChai = require('dirty-chai')
const expect = chai.expect
chai.use(dirtyChai)

module.exports = (ctl) => {
describe('.dns', () => {
it('get dns for ipfs.io', (done) => {
ctl.dns('ipfs.io', (err, result) => {
expect(err).to.not.exist()
expect(result).to.exist()
done()
})
})
})
}
24 changes: 24 additions & 0 deletions test/http-api/spec/dns.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
/* eslint-env mocha */
'use strict'

const expect = require('chai').expect

module.exports = (http) => {
describe('/dns', () => {
let api

before(() => {
api = http.api.server.select('API')
})

it('get the id', (done) => {
api.inject({
method: 'GET',
url: '/api/v0/dns?arg=ipfs.io'
}, (res) => {
expect(res).to.have.property('Path')
done()
})
})
})
}

0 comments on commit 8645c3e

Please sign in to comment.