You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

93 lines
2.2 KiB

'use strict'
const test = require('tap').test
const FormData = require('form-data')
const Fastify = require('fastify')
const multipart = require('..')
const http = require('http')
const stream = require('readable-stream')
const Readable = stream.Readable
const pump = stream.pipeline
const crypto = require('crypto')
const sendToWormhole = require('stream-wormhole')
// skipping on Github Actions because it takes too long
test('should upload a big file in constant memory', { skip: process.env.CI }, function (t) {
t.plan(9)
const fastify = Fastify()
const hashInput = crypto.createHash('sha256')
t.teardown(fastify.close.bind(fastify))
fastify.register(multipart)
fastify.post('/', async function (req, reply) {
t.ok(req.isMultipart())
for await (const part of req.parts()) {
if (part.file) {
t.equal(part.fieldname, 'upload')
t.equal(part.filename, 'random-data')
t.equal(part.encoding, '7bit')
t.equal(part.mimetype, 'binary/octet-stream')
await sendToWormhole(part.file)
}
}
const memory = process.memoryUsage()
t.ok(memory.rss < 400 * 1024 * 1024) // 200MB
t.ok(memory.heapTotal < 400 * 1024 * 1024) // 200MB
reply.send()
})
fastify.listen({ port: 0 }, function () {
const knownLength = 1024 * 1024 * 1024
let total = knownLength
const form = new FormData({ maxDataSize: total })
const rs = new Readable({
read (n) {
if (n > total) {
n = total
}
const buf = Buffer.alloc(n).fill('x')
hashInput.update(buf)
this.push(buf)
total -= n
if (total === 0) {
t.pass('finished generating')
hashInput.end()
this.push(null)
}
}
})
form.append('upload', rs, {
filename: 'random-data',
contentType: 'binary/octet-stream',
knownLength
})
const opts = {
protocol: 'http:',
hostname: 'localhost',
port: fastify.server.address().port,
path: '/',
headers: form.getHeaders(),
method: 'POST'
}
const req = http.request(opts, () => { fastify.close(noop) })
pump(form, req, function (err) {
t.error(err, 'client pump: no err')
})
})
})
function noop () { }