From 97d03fca03fe698721552847cdf9b36cad3bce4b Mon Sep 17 00:00:00 2001 From: Marcin Rataj Date: Mon, 6 May 2019 12:11:19 +0200 Subject: [PATCH] feat: support /ipns/ at HTTP Gateway It requires below to PRs to land first: https://github.com/ipfs/js-ipfs/pull/2002 https://github.com/ipfs/js-ipfs-http-response/pull/19 https://github.com/ipfs/js-ipfs-mfs/pull/48 License: MIT Signed-off-by: Marcin Rataj --- package.json | 4 +-- src/http/api/routes/webui.js | 4 +-- src/http/gateway/resources/gateway.js | 29 +++++++++++++---- src/http/gateway/routes/gateway.js | 46 +++++++++++++++++++-------- src/http/gateway/routes/index.js | 2 +- 5 files changed, 60 insertions(+), 25 deletions(-) diff --git a/package.json b/package.json index ad8413336d..8ba905f84a 100644 --- a/package.json +++ b/package.json @@ -94,8 +94,8 @@ "ipfs-block": "~0.8.1", "ipfs-block-service": "~0.15.1", "ipfs-http-client": "^32.0.1", - "ipfs-http-response": "~0.3.0", - "ipfs-mfs": "~0.11.4", + "ipfs-http-response": "~0.3.1", + "ipfs-mfs": "~0.11.5", "ipfs-multipart": "~0.1.0", "ipfs-repo": "~0.26.6", "ipfs-unixfs": "~0.1.16", diff --git a/src/http/api/routes/webui.js b/src/http/api/routes/webui.js index e97c469bd0..05f170a25e 100644 --- a/src/http/api/routes/webui.js +++ b/src/http/api/routes/webui.js @@ -5,10 +5,10 @@ const resources = require('../../gateway/resources') module.exports = [ { method: '*', - path: '/ipfs/{cid*}', + path: '/ipfs/{immutableId*}', options: { pre: [ - { method: resources.gateway.checkCID, assign: 'args' } + { method: resources.gateway.checkImmutableId, assign: 'args' } ] }, handler: resources.gateway.handler diff --git a/src/http/gateway/resources/gateway.js b/src/http/gateway/resources/gateway.js index 8f538aa22c..8c47afdc8f 100644 --- a/src/http/gateway/resources/gateway.js +++ b/src/http/gateway/resources/gateway.js @@ -30,6 +30,12 @@ function detectContentType (ref, chunk) { return mime.contentType(mimeType) } +async function resolveIpns (ref, ipfs) { + const [ root ] = PathUtils.splitPath(ref) + const immutableRoot = await ipfs.name.resolve(root, { recursive: true }) + return ref.replace(`/ipns/${root}`, PathUtils.removeTrailingSlash(immutableRoot)) +} + // Enable streaming of compressed payload // https://github.com/hapijs/hapi/issues/3599 class ResponseStream extends PassThrough { @@ -45,21 +51,32 @@ class ResponseStream extends PassThrough { } module.exports = { - checkCID (request, h) { - if (!request.params.cid) { + checkImmutableId (request, h) { + if (!request.params.immutableId) { throw Boom.badRequest('Path Resolve error: path must contain at least one component') } - - return { ref: `/ipfs/${request.params.cid}` } + return { ref: `/ipfs/${request.params.immutableId}` } + }, + checkMutableId (request, h) { + if (!request.params.mutableId) { + throw Boom.badRequest('Path Resolve error: path must contain at least one component') + } + return { ref: `/ipns/${request.params.mutableId}` } }, async handler (request, h) { const { ref } = request.pre.args const { ipfs } = request.server.app + // The resolver from ipfs-http-response supports only immutable /ipfs/ for now, + // so we convert /ipns/ to /ipfs/ before passing it to the resolver ¯\_(ツ)_/¯ + // This can be removed if a solution proposed in + // https://github.com/ipfs/js-ipfs-http-response/issues/22 lands upstream + const immutableRef = ref.startsWith('/ipns/') ? await resolveIpns(ref, ipfs) : ref + let data try { - data = await resolver.cid(ipfs, ref) + data = await resolver.cid(ipfs, immutableRef) } catch (err) { const errorToString = err.toString() log.error('err: ', errorToString, ' fileName: ', err.fileName) @@ -67,7 +84,7 @@ module.exports = { // switch case with true feels so wrong. switch (true) { case (errorToString === 'Error: This dag node is a directory'): - data = await resolver.directory(ipfs, ref, err.cid) + data = await resolver.directory(ipfs, immutableRef, err.cid) if (typeof data === 'string') { // no index file found diff --git a/src/http/gateway/routes/gateway.js b/src/http/gateway/routes/gateway.js index 4fe5d640b0..94989bd473 100644 --- a/src/http/gateway/routes/gateway.js +++ b/src/http/gateway/routes/gateway.js @@ -2,19 +2,37 @@ const resources = require('../resources') -module.exports = { - method: '*', - path: '/ipfs/{cid*}', - options: { - handler: resources.gateway.handler, - pre: [ - { method: resources.gateway.checkCID, assign: 'args' } - ], - response: { - ranges: false // disable built-in support, we do it manually - }, - ext: { - onPostHandler: { method: resources.gateway.afterHandler } +module.exports = [ + { + method: '*', + path: '/ipfs/{immutableId*}', + options: { + handler: resources.gateway.handler, + pre: [ + { method: resources.gateway.checkImmutableId, assign: 'args' } + ], + response: { + ranges: false // disable built-in support, we do it manually + }, + ext: { + onPostHandler: { method: resources.gateway.afterHandler } + } + } + }, + { + method: '*', + path: '/ipns/{mutableId*}', + options: { + handler: resources.gateway.handler, + pre: [ + { method: resources.gateway.checkMutableId, assign: 'args' } + ], + response: { + ranges: false // disable built-in support, we do it manually + }, + ext: { + onPostHandler: { method: resources.gateway.afterHandler } + } } } -} +] diff --git a/src/http/gateway/routes/index.js b/src/http/gateway/routes/index.js index 2cbf163b04..8f796ab609 100644 --- a/src/http/gateway/routes/index.js +++ b/src/http/gateway/routes/index.js @@ -1,3 +1,3 @@ 'use strict' -module.exports = [require('./gateway')] +module.exports = [...require('./gateway')]