diff --git a/packages/ipfs-http-server/package.json b/packages/ipfs-http-server/package.json index 4cb4115209..3b5cb073a7 100644 --- a/packages/ipfs-http-server/package.json +++ b/packages/ipfs-http-server/package.json @@ -43,6 +43,7 @@ "ipfs-core-utils": "^0.7.2", "ipfs-http-gateway": "^0.3.2", "ipfs-unixfs": "^4.0.3", + "ipld-block": "^0.11.1", "ipld-dag-pb": "^0.22.1", "it-all": "^1.0.4", "it-drain": "^1.0.3", diff --git a/packages/ipfs-http-server/src/api/resources/dag.js b/packages/ipfs-http-server/src/api/resources/dag.js index 2e313c3c47..0fe44cddf7 100644 --- a/packages/ipfs-http-server/src/api/resources/dag.js +++ b/packages/ipfs-http-server/src/api/resources/dag.js @@ -1,7 +1,8 @@ 'use strict' const multipart = require('../../utils/multipart-request-parser') -const mh = require('multihashing-async').multihash +const mha = require('multihashing-async') +const mh = mha.multihash const Joi = require('../../utils/joi') const Boom = require('@hapi/boom') const { @@ -9,6 +10,8 @@ const { } = require('ipfs-core-utils/src/cid') const all = require('it-all') const uint8ArrayToString = require('uint8arrays/to-string') +const Block = require('ipld-block') +const CID = require('cids') /** * @param {undefined | Uint8Array | Record} obj @@ -169,14 +172,17 @@ exports.put = { } } else { // the node is an uncommon format which the client should have - // serialized so deserialize it before continuing - const ipldFormat = await request.server.app.ipfs.ipld.getFormat(format) + // serialized so add it to the block store and fetch it deserialized + // before continuing + const hash = await mha(data, request.query.hash) + const cid = new CID(request.query.cidVersion, format, hash) - if (!ipldFormat) { - throw new Error(`Missing IPLD format "${format}"`) - } + await request.server.app.ipfs.block.put(new Block(data, cid)) - node = await ipldFormat.util.deserialize(data) + const { + value + } = await request.server.app.ipfs.dag.get(cid) + node = value } return { @@ -197,6 +203,7 @@ exports.put = { pin: Joi.boolean().default(false), hash: Joi.string().valid(...Object.keys(mh.names)).default('sha2-256'), cidBase: Joi.cidBase(), + cidVersion: Joi.number().integer().valid(0, 1).default(1), timeout: Joi.timeout() }) .rename('input-enc', 'inputEncoding', { @@ -207,6 +214,10 @@ exports.put = { override: true, ignoreUndefined: true }) + .rename('cid-version', 'cidVersion', { + override: true, + ignoreUndefined: true + }) } }, diff --git a/packages/ipfs-http-server/src/index.js b/packages/ipfs-http-server/src/index.js index fb0d99f8c7..50c03b90e5 100644 --- a/packages/ipfs-http-server/src/index.js +++ b/packages/ipfs-http-server/src/index.js @@ -17,7 +17,6 @@ const LOG_ERROR = 'ipfs:http-api:error' * @typedef {import('./types').Server} Server * @typedef {import('ipld')} IPLD * @typedef {import('libp2p')} libp2p - * @typedef {IPFS & { ipld: IPLD, libp2p: libp2p }} JSIPFS */ /** @@ -38,8 +37,8 @@ function hapiInfoToMultiaddr (info) { /** * @param {string | string[]} serverAddrs - * @param {(host: string, port: string, ipfs: JSIPFS, cors: Record) => Promise} createServer - * @param {JSIPFS} ipfs + * @param {(host: string, port: string, ipfs: IPFS, cors: Record) => Promise} createServer + * @param {IPFS} ipfs * @param {Record} cors */ async function serverCreator (serverAddrs, createServer, ipfs, cors) { @@ -61,7 +60,7 @@ async function serverCreator (serverAddrs, createServer, ipfs, cors) { class HttpApi { /** - * @param {JSIPFS} ipfs + * @param {IPFS} ipfs */ constructor (ipfs) { this._ipfs = ipfs @@ -98,7 +97,7 @@ class HttpApi { /** * @param {string} host * @param {string} port - * @param {JSIPFS} ipfs + * @param {IPFS} ipfs * @param {Record} cors */ async _createApiServer (host, port, ipfs, cors) { diff --git a/packages/ipfs-http-server/src/types.d.ts b/packages/ipfs-http-server/src/types.d.ts index 8f09c2394f..fbe0d52f75 100644 --- a/packages/ipfs-http-server/src/types.d.ts +++ b/packages/ipfs-http-server/src/types.d.ts @@ -7,7 +7,7 @@ import libp2p from 'libp2p' declare module '@hapi/hapi' { interface ServerApplicationState { - ipfs: IPFS & { ipld: IPLD, libp2p: libp2p } + ipfs: IPFS } interface RequestApplicationState { signal: AbortSignal diff --git a/packages/ipfs-http-server/test/inject/dag.js b/packages/ipfs-http-server/test/inject/dag.js index ab1a273d48..c25b2d94d2 100644 --- a/packages/ipfs-http-server/test/inject/dag.js +++ b/packages/ipfs-http-server/test/inject/dag.js @@ -38,8 +38,8 @@ describe('/dag', () => { put: sinon.stub(), resolve: sinon.stub() }, - ipld: { - getFormat: sinon.stub() + block: { + put: sinon.stub() } } }) @@ -295,16 +295,14 @@ describe('/dag', () => { expect(res).to.have.deep.nested.property('result.Cid', { '/': cid.toString() }) }) - it('should attempt to load an unsupported format', async () => { + it('adds a node with an esoteric format', async () => { + const cid = new CID('baf4beiata6mq425fzikf5m26temcvg7mizjrxrkn35swuybmpah2ajan5y') const data = Buffer.from('some data') const codec = 'git-raw' - const format = { - util: { - deserialize: (buf) => buf - } - } - ipfs.ipld.getFormat.withArgs(codec).returns(format) + ipfs.dag.get.withArgs(cid).returns({ + value: data + }) ipfs.dag.put.withArgs(data, { ...defaultOptions, format: codec @@ -316,7 +314,7 @@ describe('/dag', () => { ...await toHeadersAndPayload(data) }, { ipfs }) - expect(ipfs.ipld.getFormat.calledWith(codec)).to.be.true() + expect(ipfs.block.put.called).to.be.true() expect(res).to.have.property('statusCode', 200) expect(res).to.have.deep.nested.property('result.Cid', { '/': cid.toString() }) })