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

Commit 6524f28

Browse files
committed
fix(gateway): remove buffer-peek-stream
This removes buffer-peek-stream which caused uncaught errors inside of Hapijs and replaces it with much simpler approach to set content-type header in Gateway responses. Closes libp2p/js-libp2p#374 Closes libp2p/pull-mplex#13 License: MIT Signed-off-by: Marcin Rataj <[email protected]>
1 parent 8519886 commit 6524f28

File tree

2 files changed

+18
-20
lines changed

2 files changed

+18
-20
lines changed

package.json

-1
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,6 @@
7171
"bl": "^3.0.0",
7272
"boom": "^7.2.0",
7373
"bs58": "^4.0.1",
74-
"buffer-peek-stream": "^1.0.1",
7574
"byteman": "^1.3.5",
7675
"callbackify": "^1.1.0",
7776
"cid-tool": "~0.3.0",

src/http/gateway/resources/gateway.js

+18-19
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@ const mime = require('mime-types')
99
const { PassThrough } = require('readable-stream')
1010
const Boom = require('boom')
1111
const Ammo = require('@hapi/ammo') // HTTP Range processing utilities
12-
const peek = require('buffer-peek-stream')
1312

1413
const multibase = require('multibase')
1514
const { resolver } = require('ipfs-http-response')
@@ -32,9 +31,9 @@ function detectContentType (path, chunk) {
3231
return mime.contentType(mimeType)
3332
}
3433

35-
// Enable streaming of compressed payload
34+
// Thin stream Transform wrapper to enable streaming of compressed payload
3635
// https://github.com/hapijs/hapi/issues/3599
37-
class ResponseStream extends PassThrough {
36+
class HttpResponseStream extends PassThrough {
3837
_read (size) {
3938
super._read(size)
4039
if (this._compressor) {
@@ -148,24 +147,24 @@ module.exports = {
148147
}
149148
}
150149

151-
const rawStream = ipfs.catReadableStream(data.cid, catOptions)
152-
const responseStream = new ResponseStream()
153-
154-
// Pass-through Content-Type sniffing over initial bytes
155-
const { peekedStream, contentType } = await new Promise((resolve, reject) => {
156-
const peekBytes = fileType.minimumBytes
157-
peek(rawStream, peekBytes, (err, streamHead, peekedStream) => {
158-
if (err) {
159-
log.error(err)
160-
return reject(err)
161-
}
162-
resolve({ peekedStream, contentType: detectContentType(ipfsPath, streamHead) })
150+
// Set/Sniff Content-Type
151+
let contentType
152+
if (request.headers.range && catOptions.length) {
153+
// Range request always returns opaque byte stream
154+
contentType = 'application/octet-stream'
155+
} else {
156+
// When returning full file we analyze the file head to tell its content-type
157+
const fileHead = await ipfs.cat(data.cid, {
158+
offset: 0,
159+
length: fileType.minimumBytes
163160
})
164-
})
165-
166-
peekedStream.pipe(responseStream)
161+
contentType = detectContentType(ipfsPath, fileHead)
162+
}
167163

168-
const res = h.response(responseStream).code(rangeResponse ? 206 : 200)
164+
// We pass a compressable httpStream to Hapijs to enable streaming responses
165+
const rawStream = ipfs.catReadableStream(data.cid, catOptions)
166+
const httpStream = rawStream.pipe(new HttpResponseStream())
167+
const res = h.response(httpStream).code(rangeResponse ? 206 : 200)
169168

170169
// Etag maps directly to an identifier for a specific version of a resource
171170
// and enables smart client-side caching thanks to If-None-Match

0 commit comments

Comments
 (0)