Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fails for large ( >1 MB) images #257

Closed
nickanna42 opened this issue Oct 18, 2019 · 3 comments
Closed

Fails for large ( >1 MB) images #257

nickanna42 opened this issue Oct 18, 2019 · 3 comments

Comments

@nickanna42
Copy link

nickanna42 commented Oct 18, 2019

I am using serverless express in a lambda that sits behind an application load balancer. It is setup as recommended here.
The lambda funciton is serving up files from an S3 bucket and returning a default file, if the requested file is not found. (The reason I am doing it this way is that I need to have my static files and api calls served from the same host over SSL).

It has no problem with text files, small png and jpg files, or js files. The issue comes when I attempt to serve a particular image file that is ~ 1.5MB. This causes the application load balancer to 502, even though no errors are being reported by the lambda function

Node: 10.x
Express: 4.17.1,
aws-sdk: 2.552.0,
aws-serverless-express: 3.3.6

index.js

'use strict';

const serverlessExpress = require('aws-serverless-express');
const app = require('express')();

require('./routing')(app);

const binaryMimeTypes = [
  'application/javascript',
  'application/json',
  'application/octet-stream',
  'application/xml',
  'font/eot',
  'font/opentype',
  'font/otf',
  'image/jpeg',
  'image/png',
  'image/svg+xml',
  'text/comma-separated-values',
  'text/css',
  'text/html',
  'text/javascript',
  'text/plain',
  'text/text',
  'text/xml'
];

const server = serverlessExpress.createServer(app, null, binaryMimeTypes);

exports.handler = (event, context) => {
  // this is the home for our parsed query data.
  const query = {};

  // merge the raw query into one object.
  // it can come from different sources depending on API Gateway or Application Load Balancer.
  const raw_query = {
  	...(event.query || {}),
  	...(event.queryStringParameters || {}),
  };

  // decode everything back into utf-8 text.
  for (const key in raw_query) {
  	const formatted_key = decodeURIComponent(key);

  	query[formatted_key] = decodeURIComponent(raw_query[key]);
  }

  // set the parsed query back onto the event.
  event.query = query;
  event.queryStringParameters = query;

  console.log(serverlessExpress.proxy(server, event, context));
};

routing/index.js

'use strict';
const promisify = require('util').promisify;
const AWS = require('aws-sdk');

const s3 = new AWS.S3()
s3.getObject = promisify(s3.getObject);

const bucketName = 'kms-react-components';

module.exports = (app) => {

  app.use((req, res) => {
    const fileKey = req.path.slice(1);

    s3.getObject({
      Bucket: bucketName,
      Key: fileKey,
    })
    .then(s3Data => {
      res.set({
        'Content-Type': s3Data.ContentType,
        'ETag' : s3Data.ETag,
      });
      console.log('sending original res');
      res.send(s3Data.Body);
    })
    .catch((err) => {
      console.log('error');
      console.log(err);
      s3.getObject({
        Bucket: bucketName,
        Key: 'index.html',
      })
      .then(indexData => {
        res.set({
          'Content-Type': indexData.ContentType,
          'ETag': indexData.ETag,
        });
        res.send(indexData.Body);
      })
    })
  });
};
@chengjia080787
Copy link

ALB has a limitation on the size of the response (< 1MB)

@nickanna42
Copy link
Author

Thank you. That is handy info. Any idea where the error logs for this would pop up?

@chengjia080787
Copy link

chengjia080787 commented Nov 27, 2019

Thank you. That is handy info. Any idea where the error logs for this would pop up?

Not sure mate, my suggestion is go for Lambda Edge instead of using ALB for the frontend project.

I am not quite good at both but actually did some researches, hope it can help.

Another way is to put all the static files on S3 instead.

To be honest I don't think it's a good idea to use ALB for frontend project. Because most of the static files will be larger than 1MB.

On opposite, the backend project would be fine because most of the rest call would be small than 1MB otherwise it's a bad practise.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants