francismeynard / lambda-multipart-parser

This nodejs module will parse the multipart-form containing files and fields from the AWS lambda event object. It works very well parsing binary and text files.
MIT License
67 stars 25 forks source link

Issue in uploading images / pdf / binary #3

Closed maniadel closed 3 years ago

maniadel commented 4 years ago

Hello, I am facing issue when I try to upload an image or pdf. Please find here may sample:

handler.js

'use strict';

const parser = require('lambda-multipart-parser');
const AWS = require('aws-sdk')

module.exports.hello = async event => {

  const result = await parser.parse(event);
  console.log(result.files);

  const { content, filename, contentType } = result.files[0];

  let params = {
    Bucket: "myBucker",
    Key: filename,
    Body:  content,
    ACL: 'public-read',
    ContentType: contentType,
    ContentDisposition: `attachment; filename="${filename}";`  

  };

  const s3 = new AWS.S3();
  return s3.upload(params).promise().then( data => {
    console.log('Successfully uploaded data' + data.Location);

    return {
      statusCode: 200,
      body: JSON.stringify({ message: 'File successfully uploaded !', input: data.Location}, null,2)
    };

  }).catch(err => {
    console.log('ERROR MSG: ', err);
    return {
      statusCode: 509,
      body: JSON.stringify({ message: 'Error ' },  null, 2)
    };

  })

};

Serverless


  iamRoleStatements:
    - Effect: "Allow"
      Action:
        - "s3:*"
      Resource: "arn:aws:s3:::${self:custom.myBucker}/*" 

functions:
  hello:
    handler: handler.hello
    events:
      - http:
          path: file/uploader
          method: post

You can use postman or this html code :

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>

    <h2> Multipart upload  </h2>

    <form 
        action="https://xxxxxxxxxxx.execute-api.eu-west-1.amazonaws.com/dev/file/uploader" 
        enctype="multipart/form-data" method="post">
      <div>Text field title: <input type="text" name="title" /></div>
      <div>File: <input type="file" name="multipleFiles" multiple="multiple" /></div>
      <input type="submit" value="Upload" />
    </form>

</body>
</html>
francismeynard commented 4 years ago

Hi there, have you turned on the Lambda proxy integration by any change in your api method?

From docs/readme - "Important: Please make sure to enable the "Use Lambda Proxy integration" in API Gateway method Integration request."

maniadel commented 4 years ago

Hi @francismeynard,

The lambda integration is on. as showed in the screenshot below:

image

Thank you in advance for your help.

francismeynard commented 4 years ago

Will you be able to provide more details about the error you are getting?

maniadel commented 4 years ago

The problem I am facing is: Traying to upload to S3 image :

aws-logo

When I go to s3, the file is created but can not read it (malformed I think), Here the uploaded file :

aws-logo- copied-to s3

maniadel commented 4 years ago

As additional information, when I upload txt, csv, css, ... the file are uploaded correctly. But when I try to upload pdf, png, jpg the file is imported (size same, ..) but I can not read it (image borken, pdf the same)

IvanVokhmin commented 3 years ago

I had same issue.

Managed to solve it by adding multipart/form-data and application/octet-stream to Binary Media Types in AWS API Gateway settings. image

Or you may also add more specific MIME types too, and they will be interpreted properly. application/octet-stream is browser-default, but theoretically browser can be more specific lile image/jpeg

IvanVokhmin commented 3 years ago

After having this tested on few API Gatway setups, only multipart/form-data needs to be added to make this work

francismeynard commented 3 years ago

Closing this issue now. Refer to the last comment by @IvanVokhmin for resolution. Thanks