Skip to content

Commit

Permalink
Partly closes #496: add missing type (#502)
Browse files Browse the repository at this point in the history
  • Loading branch information
hash0000 authored Jan 1, 2024
1 parent fb63d80 commit 2430619
Show file tree
Hide file tree
Showing 3 changed files with 246 additions and 6 deletions.
221 changes: 221 additions & 0 deletions test/multipart-update-options-type.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,221 @@
'use strict'

const test = require('tap').test
const FormData = require('form-data')
const Fastify = require('fastify')
const multipart = require('..')
const http = require('node:http')
const EventEmitter = require('node:events')
const { once } = EventEmitter

test('Should throw RequestFileTooLargeError when throwFileSizeLimit: true for file())', async function (t) {
t.plan(3)

const fastify = Fastify()
t.teardown(fastify.close.bind(fastify))

fastify.register(multipart)

fastify.post('/', async function (req, reply) {
t.ok(req.isMultipart())

try {
const file = await req.file({ limits: { fileSize: 1 }, throwFileSizeLimit: true })
await file.toBuffer()
t.fail('should throw')
reply.code(200).send()
} catch (error) {
t.ok(error instanceof fastify.multipartErrors.RequestFileTooLargeError)
reply.code(500).send()
}
})

await fastify.listen({ port: 0 })
// request
const form = new FormData()
const opts = {
protocol: 'http:',
hostname: '127.0.0.1',
port: fastify.server.address().port,
path: '/',
headers: form.getHeaders(),
method: 'POST'
}

const randomFileBuffer = Buffer.alloc(1 * 1024 * 1024)

const req = http.request(opts)

form.append('upload', randomFileBuffer)

form.pipe(req)

try {
const [res] = await once(req, 'response')
t.equal(res.statusCode, 500)
res.resume()
await once(res, 'end')
} catch (error) {
t.error(error, 'request')
}
})

test('Should NOT throw RequestFileTooLargeError when throwFileSizeLimit: false for file())', async function (t) {
t.plan(3)

const fastify = Fastify()
t.teardown(fastify.close.bind(fastify))

fastify.register(multipart)

fastify.post('/', async function (req, reply) {
t.ok(req.isMultipart())

try {
const file = await req.file({ limits: { fileSize: 1 }, throwFileSizeLimit: false })
await file.toBuffer()
t.pass('OK')
reply.code(200).send()
} catch (error) {
t.fail('Should not throw')
reply.code(500).send()
}
})

await fastify.listen({ port: 0 })
// request
const form = new FormData()
const opts = {
protocol: 'http:',
hostname: '127.0.0.1',
port: fastify.server.address().port,
path: '/',
headers: form.getHeaders(),
method: 'POST'
}

const randomFileBuffer = Buffer.alloc(1 * 1024 * 1024)

const req = http.request(opts)

form.append('upload', randomFileBuffer)

form.pipe(req)

try {
const [res] = await once(req, 'response')
t.equal(res.statusCode, 200)
res.resume()
await once(res, 'end')
} catch (error) {
t.error(error, 'request')
}
})

test('Should throw RequestFileTooLargeError when throwFileSizeLimit: true for files())', async function (t) {
t.plan(3)

const fastify = Fastify()
t.teardown(fastify.close.bind(fastify))

fastify.register(multipart)

fastify.post('/', async function (req, reply) {
t.ok(req.isMultipart())

try {
const files = req.files({ limits: { fileSize: 1 }, throwFileSizeLimit: true })
for await (const file of files) {
await file.toBuffer()
}
t.fail('Should throw')
reply.code(200).send()
} catch (error) {
t.ok(error instanceof fastify.multipartErrors.RequestFileTooLargeError)
reply.code(500).send()
}
})

await fastify.listen({ port: 0 })
// request
const form = new FormData()
const opts = {
protocol: 'http:',
hostname: '127.0.0.1',
port: fastify.server.address().port,
path: '/',
headers: form.getHeaders(),
method: 'POST'
}

const randomFileBuffer = Buffer.alloc(1 * 1024 * 1024)

const req = http.request(opts)

form.append('upload', randomFileBuffer)

form.pipe(req)

try {
const [res] = await once(req, 'response')
t.equal(res.statusCode, 500)
res.resume()
await once(res, 'end')
} catch (error) {
t.error(error, 'request')
}
})

test('Should NOT throw RequestFileTooLargeError when throwFileSizeLimit: false for files())', async function (t) {
t.plan(3)

const fastify = Fastify()
t.teardown(fastify.close.bind(fastify))

fastify.register(multipart)

fastify.post('/', async function (req, reply) {
t.ok(req.isMultipart())

try {
const files = req.files({ limits: { fileSize: 1 }, throwFileSizeLimit: false })
for await (const file of files) {
await file.toBuffer()
}
t.pass('OK')
reply.code(200).send()
} catch (error) {
t.fail('Should not throw')
reply.code(500).send()
}
})

await fastify.listen({ port: 0 })
// request
const form = new FormData()
const opts = {
protocol: 'http:',
hostname: '127.0.0.1',
port: fastify.server.address().port,
path: '/',
headers: form.getHeaders(),
method: 'POST'
}

const randomFileBuffer = Buffer.alloc(1 * 1024 * 1024)

const req = http.request(opts)

form.append('upload', randomFileBuffer)

form.pipe(req)

try {
const [res] = await once(req, 'response')
t.equal(res.statusCode, 200)
res.resume()
await once(res, 'end')
} catch (error) {
t.error(error, 'request')
}
})
4 changes: 2 additions & 2 deletions types/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,10 @@ declare module 'fastify' {

// Stream mode
file: (
options?: Omit<BusboyConfig, 'headers'>
options?: Omit<BusboyConfig, 'headers'> | fastifyMultipart.FastifyMultipartBaseOptions
) => Promise<fastifyMultipart.MultipartFile | undefined>;
files: (
options?: Omit<BusboyConfig, 'headers'>
options?: Omit<BusboyConfig, 'headers'> | fastifyMultipart.FastifyMultipartBaseOptions
) => AsyncIterableIterator<fastifyMultipart.MultipartFile>;

// Disk mode
Expand Down
27 changes: 23 additions & 4 deletions types/index.test-d.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import fastify from 'fastify'
import fastifyMultipart, { MultipartValue, MultipartFields, MultipartFile } from '..'
import fastifyMultipart, { MultipartValue, MultipartFields, MultipartFile, FastifyMultipartBaseOptions } from '..'
import * as util from 'util'
import { pipeline } from 'stream'
import * as fs from 'fs'
Expand Down Expand Up @@ -76,16 +76,35 @@ const runServer = async () => {

// busboy
app.post('/', async function (req, reply) {
const options: Partial<BusboyConfig> = { limits: { fileSize: 1000, parts: 500 } }
const data = await req.file(options)
const data = await req.file({
limits: { fileSize: 1000, parts: 500 },
throwFileSizeLimit: true,
sharedSchemaId: 'schemaId',
isPartAFile: (fieldName, contentType, fileName) => {
expectType<string | undefined>(fieldName)
expectType<string | undefined>(contentType)
expectType<string | undefined>(fileName)
return true
}
})
if (!data) throw new Error('missing file')
await pump(data.file, fs.createWriteStream(data.filename))
reply.send()
})

// handle multiple file streams
app.post('/', async (req, reply) => {
const parts = req.files()
const parts = req.files({
limits: { fileSize: 1000, parts: 500 },
throwFileSizeLimit: true,
sharedSchemaId: 'schemaId',
isPartAFile: (fieldName, contentType, fileName) => {
expectType<string | undefined>(fieldName)
expectType<string | undefined>(contentType)
expectType<string | undefined>(fileName)
return true
}
})
for await (const part of parts) {
await pump(part.file, fs.createWriteStream(part.filename))
}
Expand Down

0 comments on commit 2430619

Please sign in to comment.