question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Missing data when using busboy inside Lambda?

See original GitHub issue

Hi,

First off, thank you for writing this library. I’m hoping to use it in my current project. I am trying to use busboy on a lambda function to process a post request which is supposed to upload an image file. This is what I have in my client code:

const formData = new FormData();
formData.append("file", params.file, params.file.name);

const request = new XMLHttpRequest();
request.open("POST", "https://myapi/uploadphoto");
request.setRequestHeader('Authorization', this.props.idToken);
request.send(formData);

and in my lambda function I have this method to get the file contents:

function getFile(event) {
   const busboy = new Busboy({headers: event.headers});
   const result = {};

   return new Promise((resolve, reject) => {
      busboy.on('file', (fieldname, file, filename, encoding, mimetype) => {
         file.on('data', data => {
            result.content = data;
            console.log("got data... " + data.length + ' bytes');
         });

         file.on('end', () => {
            result.filename = filename;
            result.contentType = mimetype;
            resolve(result);
         });
      });

      busboy.on('error', error => reject(error));
      busboy.write(event.body, event.isBase64Encoded ? 'base64' : 'binary');
      busboy.end();
   });
}

When trying with an example photo, I notice that the “got data” console log is showing me that I am not receiving the whole file. The file I am using is 229707 bytes but the console log says that it received 217351 bytes.

I tried changing the call to busboy.write to just use ‘base64’ since it looks like the file arrives in binary, but that didn’t work either.

I am wondering if I am using busboy wrong or if this is some quirk of lambda + api gateway. Any ideas or help troubleshooting is much appreciated. Thank you!

Issue Analytics

  • State:closed
  • Created 4 years ago
  • Reactions:5
  • Comments:13 (5 by maintainers)

github_iconTop GitHub Comments

21reactions
Smoodlecommented, Jun 25, 2019

Hey sorry for the late response, had the same issue and finally got it working. In my case i use AWS Lambdas so anyone still looking for a solution this is how i did it.

This is not a busboy issue, you just need to enable binary support in API Gateway (https://docs.aws.amazon.com/apigateway/latest/developerguide/api-gateway-payload-encodings-configure-with-console.html)

All your initial code is correct, this is my code:

module.exports.parseFormData = (event) => new Promise((resolve, reject) => {
	const busboy = new Busboy({
		headers: event.headers
	});

	let result = {
		files: []
	};

	busboy.on('file', (fieldname, file, filename, encoding, mimetype) => {
		file.on('data', data => {
			result.files.push({
				file: data,
				fileName: filename,
				contentType: mimetype
			});
		});
	});

	busboy.on('field', (fieldname, value) => {
		try {
			result[fieldname] = JSON.parse(value);
		} catch (err) {
			result[fieldname] = value;
		}
	});

	busboy.on('error', error => reject(`Parse error: ${error}`));
	busboy.on('finish', () => {
		event.body = result;
		resolve(event);
	});

	busboy.write(event.body, event.isBase64Encoded ? 'base64' : 'binary');
	busboy.end();
});

If you use serverless framework to manage your lambdas you just need to add this to provider setting

provider:
    apiGateway:
    binaryMediaTypes:
            - '*/*'

Hope this helps.

11reactions
FaridSaficommented, May 8, 2020

Thank you @Smoodle, you saved me a lot of time. Here my version with little improvements.

const Busboy = require("busboy");
const parseFormData = (event) => {
  return new Promise((resolve, reject) => {
    const busboy = new Busboy({
      headers: {
        ...event.headers,
        "content-type":
          event.headers["Content-Type"] || event.headers["content-type"],
      },
    });
    const result = {
      files: [],
    };

    busboy.on("file", (fieldname, file, filename, encoding, mimetype) => {
      file.on("data", (data) => {
        result.files.push({
          file: data,
          fileName: filename,
          contentType: mimetype,
        });
      });
    });
    busboy.on("field", (fieldname, value) => {
      try {
        result[fieldname] = JSON.parse(value);
      } catch (err) {
        result[fieldname] = value;
      }
    });
    busboy.on("error", (error) => reject(`Parse error: ${error}`));
    busboy.on("finish", () => {
      event.body = result;
      resolve(event);
    });
    busboy.write(event.body, event.isBase64Encoded ? "base64" : "binary");
    busboy.end();
  });
};
Read more comments on GitHub >

github_iconTop Results From Across the Web

Missing data when using busboy library to upload file inside of ...
I was able to solve the problem by adding multipart/form-data as a binary media type inside the settings of API Gateway.
Read more >
Choose between Formidable, Busboy, Multer and Multiparty ...
NAVIGATION Breakdown of most popular packages Use Formidable or Multer for proof of concepts and low volume Use Busboy for high-volume production-grade ...
Read more >
How to Build a serverless backend AWS Lambda function to ...
Let's create the form-data parser. We are going to use busboy to handle the streaming data. Busboy is a streaming parser for HTML...
Read more >
Upload and Stream Multipart Content with Nodejs In 5 minutes
One thing you want to keep in mind is when using Busboy it only parses application/x-www-form-urlencoded and multipart/form-data requests.
Read more >
AWS Lambda function errors in Node.js
This page describes how to view Lambda function invocation errors for the Node.js runtime using the Lambda console and the AWS CLI.
Read more >

github_iconTop Related Medium Post

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found