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

Commit a17253e

Browse files
chancehudsonAlan Shaw
authored andcommitted
feat: support _dnslink subdomain specified dnslinks (#1843)
1 parent 2df45d7 commit a17253e

File tree

2 files changed

+49
-11
lines changed

2 files changed

+49
-11
lines changed

src/core/runtime/dns-nodejs.js

Lines changed: 41 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,51 @@
11
'use strict'
22

33
const dns = require('dns')
4+
const _ = require('lodash')
5+
const errcode = require('err-code')
46

57
module.exports = (domain, opts, callback) => {
6-
dns.resolveTxt(domain, (err, records) => {
7-
if (err) {
8-
return callback(err, null)
9-
}
8+
resolveDnslink(domain)
9+
.catch(err => {
10+
// If the code is not ENOTFOUND or ERR_DNSLINK_NOT_FOUND then throw the error
11+
if (err.code !== 'ENOTFOUND' && err.code !== 'ERR_DNSLINK_NOT_FOUND') throw err
1012

11-
// TODO: implement recursive option
12-
13-
for (const record of records) {
14-
if (record[0].startsWith('dnslink=')) {
15-
return callback(null, record[0].substr(8, record[0].length - 1))
13+
if (domain.startsWith('_dnslink.')) {
14+
// The supplied domain contains a _dnslink component
15+
// Check the non-_dnslink domain
16+
const rootDomain = domain.replace('_dnslink.', '')
17+
return resolveDnslink(rootDomain)
1618
}
17-
}
19+
// Check the _dnslink subdomain
20+
const _dnslinkDomain = `_dnslink.${domain}`
21+
// If this throws then we propagate the error
22+
return resolveDnslink(_dnslinkDomain)
23+
})
24+
.then(dnslinkRecord => {
25+
callback(null, dnslinkRecord.replace('dnslink=', ''))
26+
})
27+
.catch(callback)
28+
}
1829

19-
callback(new Error('domain does not have a txt dnslink entry'))
30+
function resolveDnslink (domain) {
31+
const DNSLINK_REGEX = /^dnslink=.+$/
32+
return new Promise((resolve, reject) => {
33+
dns.resolveTxt(domain, (err, records) => {
34+
if (err) return reject(err)
35+
resolve(records)
36+
})
2037
})
38+
.then(records => {
39+
return _.chain(records).flatten().filter(record => {
40+
return DNSLINK_REGEX.test(record)
41+
}).value()
42+
})
43+
.then(dnslinkRecords => {
44+
// we now have dns text entries as an array of strings
45+
// only records passing the DNSLINK_REGEX text are included
46+
if (dnslinkRecords.length === 0) {
47+
throw errcode(`No dnslink records found for domain: ${domain}`, 'ERR_DNSLINK_NOT_FOUND')
48+
}
49+
return dnslinkRecords[0]
50+
})
2151
}

test/cli/dns.js

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,4 +19,12 @@ describe('dns', () => runOnAndOff((thing) => {
1919
expect(res.substr(0, 6)).to.eql('/ipns/')
2020
})
2121
})
22+
23+
it('resolve _dnslink.ipfs.io dns', function () {
24+
this.timeout(60 * 1000)
25+
26+
return ipfs('dns _dnslink.ipfs.io').then((res) => {
27+
expect(res.substr(0, 6)).to.eql('/ipns/')
28+
})
29+
})
2230
}))

0 commit comments

Comments
 (0)