aws-lambda-fastify icon indicating copy to clipboard operation
aws-lambda-fastify copied to clipboard

Support binary option for multipart/form-data type

Open 6unpk opened this issue 3 years ago • 0 comments

Prerequisites

  • [X] I have written a descriptive issue title
  • [X] I have searched existing issues to ensure the feature has not already been requested

🚀 Feature Proposal

Hello! I'm using this module with @fastify/multipart. recently i found that when request type is multipart/form-data, it must be decoded with binary options like Buffer.from(data, 'binary') But, now it seems this module doesn't support binary options. So could i add binary option?

Motivation

When i send this request

curl --location --request POST 'http://localhost:3000/upload/templates' \
--form 'thumbnail=@"/Users/junwoopark/Downloads/24939410.png"' \
--form 'template="{}"' \
--form 'ratio="1"' \
--form 'categories=""'

lambda handler is (test with serverless-offline)

const ffy = require('fastify');
const fs = require('fs');
const fastify = ffy();

const opts = {
  attachFieldsToBody: true,
};

fastify.register(require('@fastify/multipart'), opts)

fastify.post('/upload/templates', async function (req, reply) {
  const data = await req.body;
  console.log(data);
  fs.writeFileSync('./image.png', data.thumbnail._buf);
  reply.send('done');
})

export const main = awsLambdaFastify(fastify);

buffer result must be

 thumbnail: {
    fieldname: 'thumbnail',
    filename: '24939410.png',
    encoding: '7bit',
    mimetype: 'image/png',
    file: FileStream {
      _readableState: [ReadableState],
      _events: [Object: null prototype],
      _eventsCount: 5,
      _maxListeners: undefined,
      bytesRead: 5062,
      truncated: false,
      _read: [Function (anonymous)],
      [Symbol(kCapture)]: false
    },
    fields: [Circular *1],
    _buf: <Buffer 89 50 4e 47 0d 0a 1a 0a 00 00 00 0d 49 48 44 52 00 00 00 c8 00 00 00 c8 08 02 00 00 00 22 3a 39 c9 00 00 13 8d 49 44 41 54 78 9c ec dd 79 50 53 e7 fe ... 5012 more bytes>,
    toBuffer: [AsyncFunction: toBuffer]
  },

but actual result of this version is

thumbnail: {
    fieldname: 'thumbnail',
    filename: '24939410.png',
    encoding: '7bit',
    mimetype: 'image/png',
    file: FileStream {
      _readableState: [ReadableState],
      _events: [Object: null prototype],
      _eventsCount: 5,
      _maxListeners: undefined,
      bytesRead: 7603,
      truncated: false,
      _read: [Function (anonymous)],
      [Symbol(kCapture)]: false
    },
    fields: [Circular *1],
    _buf: <Buffer c2 89 50 4e 47 0d 0a 1a 0a 00 00 00 0d 49 48 44 52 00 00 00 c3 88 00 00 00 c3 88 08 02 00 00 00 22 3a 39 c3 89 00 00 13 c2 8d 49 44 41 54 78 c2 9c c3 ... 7553 more bytes>,
    toBuffer: [AsyncFunction: toBuffer]
  },

Example

I think new option enforceBinaryOption should be added

property description default value
enforceBinaryOption false
module.exports = () => {
    options.enforceBinaryOption = options.enforceBinaryOption ?? false
     ...

    //  multipart/form-data only works if encoding is binary 
    // const payload = Buffer.from(event.body, 'binary')
    // const payload = Buffer.from(event.body, event.isBase64Encoded ? 'base64' : 'utf8')
   const payload = Buffer.from(event.body, options.enforceBinaryOption ?  'binary' :  (event.isBase64Encoded ? 'base64' : 'utf8'))
}

6unpk avatar Oct 05 '22 03:10 6unpk