2

BackEnd: I am using using AWS Lambda Project .NET Core C#

In the backend, I am returning code something like this:

var response = new APIGatewayProxyResponse
{
      StatusCode = (int)HttpStatusCode.OK,
      Body = Convert.ToBase64String(fooByteArray),
      IsBase64Encoded = true,
      Headers = new Dictionary<string, string> { { "Content-Type", 'application/pdf' }, { "Access-Control-Allow-Origin", "*" } },
};

return response;

When I test in the Mock Lambda Test Tool, the value that it is returning is correct (I can literally copy paste the string in the front end and it will return the correct PDF values).

However, when I deploy this in AWS lambda, the response value changed (is lesser) and has some weird data in the PDF (for example, value is suppose to be $12.00, it now returns $12.000)

I tried everything, such as what I usually use:

Body = JsonConvert.SerializeObject(fooBytesWrappedInModelClass, new JsonSerializerSettings() { ReferenceLoopHandling = ReferenceLoopHandling.Ignore }),

In the end, it always returns that weird $12.000. I don't want a hack fix on the front end to handle the extra zeroes as the PDF is a huge file and there may be other texts missing.

ADDITIONAL NOTES: I tried the following

  • Direct convert of byte array to Json serialize object
  • Converting byte array into hex (lambda still has missing response values)
  • The problem is on Lambda itself (since the value there is already different) and not in Api Gateway yet
  • PDF byte array response has a range of 200K to 320K
  • Amount of response missing from 320K one was 12K characters
MilkTea027
  • 301
  • 1
  • 5
  • 24
  • 2
    Where does the `fooByteArray` come from? Is it created by your application? Have you considered that the code running within the AWS Lambda may observe a different culture than what you have locally? I find it highly impropable that the network elements along the way would modify the request contents such as PDF in base-64 to change formatting of currency data. – Zdeněk Jelínek Jun 01 '20 at 07:45
  • 1
    Aye culture was my immediate thought. I had a good bit of fun with that, developing and testing in windows, then deploying on linux. – Tony Hopkinson Jun 01 '20 at 07:52
  • 1
    As an experiment, you may produce a hash of the byte array's values and log it pripor to returning the response (note: do not use `Array.GetHashCode` directly, [it does not consider the array's contents](https://stackoverflow.com/a/7244729/3593970)). I would expect you to see different hashes in the AWS Lambda versus your development environment, showing that the actual PDFs differ before you send them. – Zdeněk Jelínek Jun 01 '20 at 07:56
  • I am using a 3rd party library in my backend to generate PDF bytes, so it may be the 3rd party library converting the decimals into 3 places.. I just focused on why 320K character count lacked 12K characters as a response, and didn't really think of the culture... I will be trying to see if I can set the culture (my AWS is pointed in singapore region) – MilkTea027 Jun 01 '20 at 08:24
  • @ZdeněkJelínek spot on with the culture issue! Can you please create an answer so I can credit it to you and close this question up :) – MilkTea027 Jun 01 '20 at 11:49
  • 1
    I'm not entirely sure how to generalize the answer for this question so that it may help someone else but I tried something. Anyway, glad I could help you. – Zdeněk Jelínek Jun 01 '20 at 12:57

2 Answers2

1

Given that the problem surfaced as formatting issues, the root cause is most probably related to the culture within the AWS Lambda instance you are running.

This is a very common culprit when it comes to cloud deployment, as the emulation tools used on your machine use the machine's local culture which often differs from the cloud environment. There may also be cultural disparities between platforms based on their capaibilities, e.g. list separators differ between Windows and Unix for Russian.

One should always diagnose the outputs of their application within the given environment before continuing the investigation of either the environment or the application.

For large sets of data such as byte arrays, comparing individual bytes may be infeasible, but it may be worthwhile to produce hashes and see if those differ between the environments.

Zdeněk Jelínek
  • 2,611
  • 1
  • 17
  • 23
0

By default API Gateway, which is calling the Lambda function, doesn't handle binary data returned from Lambda. You will need to configure API Gateway to pass along the content as binary. Here is the docs about binary content for API Gateway https://docs.aws.amazon.com/apigateway/latest/developerguide/api-gateway-payload-encodings.html

Norm Johanson
  • 2,964
  • 14
  • 13