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

Lambda functions decode event.payload as utf8 strings for requests with Content-type application/octet-stream #1775

Open
amperioromano opened this issue Apr 6, 2024 · 0 comments

Comments

@amperioromano
Copy link

Bug Report

If we have a lambda function that has content type application/octet-stream, the eventpayload received in the lambda function is a string that comes from decoding the payload buffer with encoding utf8. That makes is impossible to convert it back to binary.

Current Behavior

Sample Code

  • file: serverless.yml
service: my-service

plugins:
  - serverless-offline

provider:
  runtime: nodejs18.x
  stage: dev

functions:
  hello:
    events:
      - http:
          method: post
          path: hello
          request:
            contentHandling: CONVERT_TO_TEXT
    handler: handler.hello
  • file: handler.js
"use strict"

const { stringify } = JSON

exports.hello = async function hello(event) {

  // event.payload should be a string decoded with binary encoding when the content-type is application/octet-stream
  return {
    body: stringify({ foo: "bar" }),
    statusCode: 200,
  }
}

Expected behavior/code

event.payload should be a string decoded with binary encoding when the content-type is application/octet-stream, but it looks it is utf8.

Environment

  • serverless version: v3.38.0
  • serverless-offline version: v13.3.3
  • node.js version: v18.3.0
  • OS: Ubuntu 20.04

Possible Solution

I think the error is in the HttpServer

request.payload = request.payload && request.payload.toString(encoding)
where it always encodes the payload like this

       // Payload processing
      const encoding = detectEncoding(request)

      request.payload = request.payload && request.payload.toString(encoding)

detectEncoding implementation is like

export function detectEncoding(request) {

// Detect the toString encoding from the request headers content-type
// enhance if further content types need to be non utf8 encoded.
export function detectEncoding(request) {
  const contentType = request.headers["content-type"]

  return typeof contentType === "string" &&
    contentType.includes("multipart/form-data")
    ? "binary"
    : "utf8"
}

It should consider the application/octet-stream in the same way as multipart/form-data, as it is not possible to convert back the string to the original binary otherwise.

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

1 participant