Error handling binary files with an express app deployed to AWS lambda

Hello,

I’m porting an old existing Express app to AWS Lambda. The app just contains 1 endpoint, and the operation is really simple:

  1. Receives a docx file via POST request
  2. Manipulates the content of the file
  3. Sends a modified copy of the docx file to the sender.

That’s it. It works as a standalone app in a VPS. But it fails when deployed to lambda AWS using serverless. The received file is corrupt.

This is a simplified version of the app.js file

var express = require('serverless-express/express');
var formidable = require('formidable');
var fs = require('fs');
var JSZip = require('JSZip');
var Docxtemplater = require('docxtemplater');
var handler = require('serverless-express/handler');

// Instance express
var app = express();

app.post('/', function (req, res, next) {

    var form = new formidable.IncomingForm();

    // Callback to answer inconming POST request
    form.parse(req, function (err, fields, files) {
        // File sent
        uploaded_path = files.file.path;
        
        fs.readFile(uploaded_path, function (err, data) {

           // Create zip file with the data. It fails here in AWS Lambda!
           var zip = new JSZip(data);
           
           // Pass the zip file to Docxtemplater to do stuff...
           var doc = new Docxtemplater();
           doc.loadZip(zip);

           // More stuff here... whatever
        }
    }
}

module.exports.handler = handler(app);

And here the serverless.yml file

service: myservice

plugins:
  - serverless-apigw-binary
  - serverless-offline
  - serverless-express

custom:
  apigwBinary:
    types:
      - 'application/vnd.openxmlformats-officedocument.wordprocessingml.document'

provider:
  name: aws
  runtime: nodejs8.10
  stage: dev
  region: eu-west-3
  role: myrole
functions:
  app:
    handler: app.handler
    events:
      - http: GET /
      - http: POST /
      - http: 'ANY {proxy+}'

The app works just fine as standalone app, as said. The file sent via POST is properly read and passed to Docxtemplater library. But in AWS Lambda, the file is always corrupt. Not only with docx files. Any file sent is detected as corrupt.

This is the error message when calling new JSZip(data)

End of data reached (data length = 403921, asked index = 70664704). Corrupted zip ?

My guess: the file is not being sent as binary. But I don’t know how to configure serverless to tell lambda to do it.

Hi, have you checked if serverless-apigw-binary added necessary binary types? I would recommend to open your gateway console and take a look. https://take.ms/OXzz7

can be useful as well https://docs.aws.amazon.com/apigateway/latest/developerguide/api-gateway-payload-encodings.html

Hi,

Yes. Checked. There was missing binary types. Specifically: application/x-www-form-urlencoded

Now it seems to work. Thanks!