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

Commit a499fc9

Browse files
committed
chore: update pr after review
1 parent 6111234 commit a499fc9

File tree

4 files changed

+497
-173
lines changed

4 files changed

+497
-173
lines changed

src/http/api/resources/dag.js

Lines changed: 102 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -3,15 +3,19 @@
33
const promisify = require('promisify-es6')
44
const CID = require('cids')
55
const multipart = require('ipfs-multipart')
6+
const mh = require('multihashes')
67
const Joi = require('joi')
78
const multibase = require('multibase')
89
const Boom = require('boom')
910
const debug = require('debug')
11+
const {
12+
cidToString
13+
} = require('../../../utils/cid')
1014
const log = debug('ipfs:http-api:dag')
1115
log.error = debug('ipfs:http-api:dag:error')
1216

1317
// common pre request handler that parses the args and returns `key` which is assigned to `request.pre.args`
14-
exports.parseKey = (request, h) => {
18+
exports.parseKey = (request) => {
1519
if (!request.query.arg) {
1620
throw Boom.badRequest("Argument 'key' is required")
1721
}
@@ -30,7 +34,7 @@ exports.parseKey = (request, h) => {
3034
path = `${parts.join('/')}`
3135
}
3236

33-
if (path.endsWith('/')) {
37+
if (path && path.endsWith('/')) {
3438
path = path.substring(0, path.length - 1)
3539
}
3640

@@ -45,10 +49,34 @@ exports.parseKey = (request, h) => {
4549
}
4650
}
4751

52+
const encodeBufferKeys = (obj, encoding) => {
53+
if (!obj) {
54+
return obj
55+
}
56+
57+
if (Buffer.isBuffer(obj)) {
58+
return obj.toString(encoding)
59+
}
60+
61+
Object.keys(obj).forEach(key => {
62+
if (Buffer.isBuffer(obj)) {
63+
obj[key] = obj[key].toString(encoding)
64+
65+
return
66+
}
67+
68+
if (typeof obj[key] === 'object') {
69+
obj[key] = encodeBufferKeys(obj[key], encoding)
70+
}
71+
})
72+
73+
return obj
74+
}
75+
4876
exports.get = {
4977
validate: {
5078
query: Joi.object().keys({
51-
'data-encoding': Joi.string().valid(['text', 'base64']).default('base64'),
79+
'data-encoding': Joi.string().valid(['text', 'base64', 'hex']).default('text'),
5280
'cid-base': Joi.string().valid(multibase.names)
5381
}).unknown()
5482
},
@@ -64,22 +92,24 @@ exports.get = {
6492
} = request.pre.args
6593
const { ipfs } = request.server.app
6694

95+
let dataEncoding = request.query['data-encoding']
96+
97+
if (dataEncoding === 'text') {
98+
dataEncoding = 'utf8'
99+
}
100+
67101
let result
68102

69103
try {
70104
result = await ipfs.dag.get(key, path)
71105
} catch (err) {
72-
throw Boom.boomify(err, { message: 'Failed to get dag node' })
106+
throw Boom.badRequest(err)
73107
}
74108

75-
if (key.codec === 'dag-pb' && result.value) {
76-
if (typeof result.value.toJSON === 'function') {
77-
result.value = result.value.toJSON()
78-
}
79-
80-
if (Buffer.isBuffer(result.value.data)) {
81-
result.value.data = result.value.data.toString(request.query.dataencoding)
82-
}
109+
try {
110+
result.value = encodeBufferKeys(result.value, dataEncoding)
111+
} catch (err) {
112+
throw Boom.boomify(err)
83113
}
84114

85115
return h.response(result.value)
@@ -89,11 +119,10 @@ exports.get = {
89119
exports.put = {
90120
validate: {
91121
query: Joi.object().keys({
92-
// TODO validate format, & hash
93-
format: Joi.string(),
94-
'input-enc': Joi.string().valid('dag-cbor', 'dag-pb', 'raw'),
122+
format: Joi.string().default('cbor'),
123+
'input-enc': Joi.string().default('json'),
95124
pin: Joi.boolean(),
96-
hash: Joi.string(),
125+
hash: Joi.string().valid(mh.names).default('sha2-256'),
97126
'cid-base': Joi.string().valid(multibase.names).default('base58btc')
98127
}).unknown()
99128
},
@@ -102,78 +131,89 @@ exports.put = {
102131
// which is assigned to `request.pre.args`
103132
async parseArgs (request, h) {
104133
if (!request.payload) {
105-
throw Boom.badRequest("File argument 'data' is required")
134+
throw Boom.badRequest("File argument 'object data' is required")
106135
}
107136

108-
const enc = request.query.inputenc
137+
const enc = request.query['input-enc']
138+
139+
if (!request.headers['content-type']) {
140+
throw Boom.badRequest("File argument 'object data' is required")
141+
}
109142

110143
const fileStream = await new Promise((resolve, reject) => {
111144
multipart.reqParser(request.payload)
112145
.on('file', (name, stream) => resolve(stream))
113-
.on('end', () => reject(Boom.badRequest("File argument 'data' is required")))
146+
.on('end', () => reject(Boom.badRequest("File argument 'object data' is required")))
114147
})
115148

116149
let data = await new Promise((resolve, reject) => {
117150
fileStream
118151
.on('data', data => resolve(data))
119-
.on('end', () => reject(Boom.badRequest("File argument 'data' is required")))
152+
.on('end', () => reject(Boom.badRequest("File argument 'object data' is required")))
120153
})
121154

122-
if (enc === 'json') {
155+
let format = request.query.format
156+
157+
if (format === 'cbor') {
158+
format = 'dag-cbor'
159+
}
160+
161+
let node
162+
163+
if (format === 'raw') {
164+
node = data
165+
} else if (enc === 'json') {
123166
try {
124-
data = JSON.parse(data.toString())
167+
node = JSON.parse(data.toString())
125168
} catch (err) {
126169
throw Boom.badRequest('Failed to parse the JSON: ' + err)
127170
}
128-
}
171+
} else {
172+
const { ipfs } = request.server.app
173+
const codec = ipfs._ipld.resolvers[format]
129174

130-
try {
131-
return {
132-
buffer: data
175+
if (!codec) {
176+
throw Boom.badRequest(`Missing IPLD format "${request.query.format}"`)
133177
}
134-
} catch (err) {
135-
throw Boom.badRequest('Failed to create DAG node: ' + err)
178+
179+
const deserialize = promisify(codec.util.deserialize)
180+
181+
node = await deserialize(data)
182+
}
183+
184+
return {
185+
node,
186+
format,
187+
hashAlg: request.query.hash
136188
}
137189
},
138190

139191
// main route handler which is called after the above `parseArgs`, but only if the args were valid
140192
async handler (request, h) {
141193
const { ipfs } = request.server.app
142-
const { buffer } = request.pre.args
194+
const { node, format, hashAlg } = request.pre.args
143195

144196
let cid
145197

146-
return new Promise((resolve, reject) => {
147-
const format = ipfs._ipld.resolvers[request.query.format]
148-
149-
if (!format) {
150-
return reject(Boom.badRequest(`Missing IPLD format "${request.query.format}"`))
151-
}
152-
153-
format.util.deserialize(buffer, async (err, node) => {
154-
if (err) {
155-
return reject(err)
156-
}
157-
158-
try {
159-
cid = await ipfs.dag.put(node, {
160-
format: request.query.format,
161-
hashAlg: request.query.hash
162-
})
163-
} catch (err) {
164-
throw Boom.boomify(err, { message: 'Failed to put node' })
165-
}
198+
try {
199+
cid = await ipfs.dag.put(node, {
200+
format: format,
201+
hashAlg: hashAlg
202+
})
203+
} catch (err) {
204+
throw Boom.boomify(err, { message: 'Failed to put node' })
205+
}
166206

167-
if (request.query.pin) {
168-
await ipfs.pin.add(cid)
169-
}
207+
if (request.query.pin) {
208+
await ipfs.pin.add(cid)
209+
}
170210

171-
resolve(h.response({
172-
Cid: {
173-
'/': cid.toBaseEncodedString(request.query.cidbase)
174-
}
175-
}))
176-
})
211+
return h.response({
212+
Cid: {
213+
'/': cidToString(cid, {
214+
base: request.query['cid-base']
215+
})
216+
}
177217
})
178218
}
179219
}
@@ -191,7 +231,6 @@ exports.resolve = {
191231
// main route handler which is called after the above `parseArgs`, but only if the args were valid
192232
async handler (request, h) {
193233
let { key, path } = request.pre.args
194-
const cidBase = request.query['cid-base']
195234
const { ipfs } = request.server.app
196235

197236
// to be consistent with go we need to return the CID to the last node we've traversed
@@ -226,9 +265,11 @@ exports.resolve = {
226265

227266
return h.response({
228267
Cid: {
229-
'/': lastCid.toBaseEncodedString(cidBase)
268+
'/': cidToString(lastCid, {
269+
base: request.query['cid-base']
270+
})
230271
},
231-
RemPath: lastRemainderPath
272+
RemPath: lastRemainderPath || ''
232273
})
233274
} catch (err) {
234275
throw Boom.boomify(err)

test/http-api/dag.js

Lines changed: 0 additions & 111 deletions
This file was deleted.

test/http-api/index.js

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@
33
require('./block')
44
require('./bootstrap')
55
require('./config')
6-
require('./dag')
76
require('./dns')
87
require('./id')
98
require('./routes')

0 commit comments

Comments
 (0)