Skip to content
This repository has been archived by the owner on Jan 7, 2022. It is now read-only.

Commit

Permalink
Merge pull request #4 from millette/more-tests
Browse files Browse the repository at this point in the history
 Large change to resolve URLs with paths or versions.
  • Loading branch information
joehand authored Dec 12, 2017
2 parents fa48f9b + 0de355b commit 4b376e1
Show file tree
Hide file tree
Showing 3 changed files with 86 additions and 38 deletions.
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ resolve urls, links to a dat key using common methods
* URLs with keys in them (`datproject.org/6161616161616161616161616161616161616161616161616161616161616161`)
* `hyperdrive-key` or `dat-key` headers
* Url to JSON http request that returns `{key: <dat-key>}`
* Dat-DNS resolution ([details](https://github.com/beakerbrowser/beaker/wiki/Authenticated-Dat-URLs-and-HTTPS-to-Dat-Discovery))

## Install

Expand Down Expand Up @@ -40,6 +41,7 @@ Resolution order:
1. Validate buffers or any strings with 64 character hashes in them via [dat-encoding](https://github.com/juliangruber/dat-encoding)
2. Check headers in http request
3. Check JSON request response for `key`
4. Dat-DNS resolution via [dat-dns](https://github.com/datprotocol/dat-dns)

## Contributing

Expand Down
72 changes: 35 additions & 37 deletions index.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
var assert = require('assert')
var url = require('url')
var stringKey = require('dat-encoding').toStr
var nets = require('nets')
var datDns = require('dat-dns')()
Expand All @@ -19,46 +18,45 @@ function resolve (link, cb) {
key = stringKey(link)
cb(null, key)
} catch (e) {
return lookup()
lookup()
}

function lookup () {
debug('lookup', link)
var parsed = url.parse(link)

// parsed.host check b/c url.parse('beakerbrowser.com') returns parsed.pathname = 'beakerbrowser.com'
if (parsed.host && parsed.path && parsed.path !== '/') return resolveKey()

// If no path, check .well-known first
datDns.resolveName(link, function (err, key) {
if (key) return cb(null, key)
if (err) debug('datDns.resolveName() error', err)
resolveKey()
})

function resolveKey () {
var urlLink = link.indexOf('http') > -1 ? link : 'http://' + link
nets({ url: urlLink, json: true }, function (err, resp, body) {
if (err) return cb(err)
if (resp.statusCode !== 200) return cb(body.message)

// first check if key is in header response
key = resp.headers['hyperdrive-key'] || resp.headers['dat-key']
if (key) {
debug('Received key from http header:', key)
return cb(null, key)
}

// else fall back to parsing the body
try {
key = stringKey(body.url)
debug('Received key via json:', key)
if (key) return cb(null, key)
} catch (e) {
cb(new Error(e))
}
cb(new Error('Unable to lookup key from http link.'))
// if it starts with http or dat: use as is, otherwise prepend http://
var urlLink = (link.indexOf('http') && link.indexOf('dat:')) ? ('http://' + link) : link

function resolveName () {
datDns.resolveName(urlLink, function (err, key) {
debug('resolveName', urlLink, err, key)
if (key) return cb(null, key)
if (err) debug('datDns.resolveName() error')
cb(err)
})
}

debug('resolveKey', link, urlLink)
nets({ url: urlLink, json: true }, function (err, resp, body) {
// no ressource at given URL
if (err || resp.statusCode !== 200) {
return resolveName()
}

// first check if key is in header response
key = resp.headers['hyperdrive-key'] || resp.headers['dat-key']
if (key) {
debug('Received key from http header:', key)
return cb(null, key)
}

// else fall back to parsing the body
try {
key = stringKey(body.url)
debug('Received key via json:', key, typeof body, body && typeof body.url)
if (key) return cb(null, key)
} catch (e) {
// fall back to datDns
resolveName()
}
})
}
}
50 changes: 49 additions & 1 deletion test/index.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
var test = require('tape')
var enc = require('dat-encoding')
var datResolve = require('..')
var enc = require('dat-encoding')

// Strings that do not require lookup
var stringKeys = [
Expand All @@ -18,6 +18,54 @@ var stringBadKeys = [
{type: 'invalid', key: '61616161616161616161616161616161616161616161616161616161616161612'}
]

test('resolve key with path', function (t) {
t.plan(2)
datResolve('87ed2e3b160f261a032af03921a3bd09227d0a4cde73466c17114816cae43336/path', function (err, newKey) {
t.notOk(err, 'not expected error')
t.ok(newKey, 'is a key')
})
})

test('resolve https hostname with path', function (t) {
t.plan(2)
datResolve('https://beakerbrowser.com/path', function (err, newKey) {
t.notOk(err, 'not expected error')
t.ok(newKey, 'is a key')
})
})

test('resolve dat hostname with path', function (t) {
t.plan(2)
datResolve('dat://beakerbrowser.com/path', function (err, newKey) {
t.notOk(err, 'not expected error')
t.ok(newKey, 'is a key')
})
})

test('resolve hostname with path', function (t) {
t.plan(2)
datResolve('beakerbrowser.com/path', function (err, newKey) {
t.notOk(err, 'not expected error')
t.ok(newKey, 'is a key')
})
})

test('resolve key with version', function (t) {
t.plan(2)
datResolve('87ed2e3b160f261a032af03921a3bd09227d0a4cde73466c17114816cae43336+5', function (err, newKey) {
t.notOk(err, 'not expected error')
t.ok(newKey, 'is a key')
})
})

test('resolve hostname with version', function (t) {
t.plan(2)
datResolve('beakerbrowser.com+5', function (err, newKey) {
t.notOk(err, 'not expected error')
t.ok(newKey, 'is a key')
})
})

test('resolve bad key without http', function (t) {
t.plan(2 * stringBadKeys.length) // 2 tests for 2 keys
stringBadKeys.forEach(function (key) {
Expand Down

0 comments on commit 4b376e1

Please sign in to comment.