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

Embracing web native FormData / File where possible #3029

Closed
@Gozala

Description

@Gozala

As discussed at #2838 (comment) mainstream browsers today do not yet support passingReadableStream as request body. To workaround this limitation currently JS-IPFS encodes stream of content (on ipfs.add / ipfs.write) into multipart/form-data by buffering it:

const res = await api.post('add', {
searchParams: toUrlSearchParams({
'stream-channels': true,
...options,
progress: Boolean(progressFn)
}),
timeout: options.timeout,
signal: options.signal,
...(
await multipartRequest(input, options.headers)
)

return {
headers: merge(headers, {
'Content-Type': `multipart/form-data; boundary=${boundary}`
}),
body: await toStream(streamFiles(source))
}
}

async function * bufferise (source) {
for await (const chunk of source) {
if (Buffer.isBuffer(chunk)) {
yield chunk
} else {
yield Buffer.from(chunk)
}
}
}
return toBuffer(bufferise(it))

This is problematic for webui for instance as some files may not fit into memory or exceed browser quota.


Modern browsers do have native FormData and File / Blob primitives that if used carefully can facilitate streaming. It appears that in the past browser loaded all of the FormData / File / Blob content during fetch despite not reading it. However that evidently had being fixed and modern browsers (Tested with Firefox, Chrome, Safari) no longer exhibit that problem.

Following example was used to verify this behavior
https://ipfs.io/ipfs/QmWVrTAeA1FqRSK3owpCfvB69wsz2Dbr2THK6ehn5uEKbp

On my Mac I do not observe visible increase memory when I uploading 5 Gig file (across mentioned browsers). I also observe streaming behavior as as file size change in WebUI is changing during upload:

Screen Shot 2020-05-08 at 3 33 55 PM

Screen Shot 2020-05-08 at 3 36 54 PM


This investigation suggests that there is an opportunity to avoid buffering overhead in browsers. It also appears that doing it for ipfs.files.write should be fairly straight forward since it always writes a single file.

For ipfs.add things appear more complicated, as headers need to be added to each multipart part (E.g. unix mode & mtime). Some investigation is required to see how visible that is with native FormData. There are also some concerns about supporting directory structures.

Metadata

Metadata

Assignees

Labels

P1High: Likely tackled by core team if no one steps upenv:browserexp/wizardExtensive knowledge (implications, ramifications) requiredkind/maintenanceWork required to avoid breaking changes or harm to project's status quotopic/perfPerformance

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions