programing

AWS Lambda API 게이트웨이 오류 "잘못된 Lambda 프록시 응답"

nasanasas 2020. 12. 10. 20:30
반응형

AWS Lambda API 게이트웨이 오류 "잘못된 Lambda 프록시 응답"


AWS lambda를 사용하여 hello world 예제를 설정하고 api 게이트웨이를 통해 제공하려고합니다. "Create a Lambda Function"을 클릭하여 api gatway를 설정하고 Blank Function 옵션을 선택했습니다. AWS 게이트웨이 시작 안내서 에있는 람다 함수를 추가 했습니다 .

exports.handler = function(event, context, callback) {
  callback(null, {"Hello":"World"});  // SUCCESS with message
};

문제는 GET 요청을 할 때 502 응답을 반환한다는 것 { "message": "Internal server error" }입니다. 그리고 로그에 "구성 오류로 인해 실행 실패 : 잘못된 Lambda 프록시 응답"이라고 표시됩니다.


일반적 Malformed Lambda proxy response으로이 표시되면 Lambda 함수의 응답이 다음과 같이 API Gateway가 예상하는 형식과 일치하지 않음을 의미합니다.

{
    "isBase64Encoded": true|false,
    "statusCode": httpStatusCode,
    "headers": { "headerName": "headerValue", ... },
    "body": "..."
}

Lambda 프록시 통합을 사용하지 않는 경우 API Gateway 콘솔에 로그인하고 Lambda 프록시 통합 확인란을 선택 취소 할 수 있습니다.

또한 intermittent Malformed Lambda proxy response가 표시되는 경우 Lambda 함수에 대한 요청이 Lambda에 의해 조절되었음을 의미 할 수 있으며 Lambda 함수에 대한 동시 실행 제한 증가를 요청해야합니다.


람다가 프록시로 사용되는 경우 응답 형식은

{
"isBase64Encoded": true|false,
"statusCode": httpStatusCode,
"headers": { "headerName": "headerValue", ... },
"body": "..."
}

참고 : 본문은 문자열이어야합니다.


예, 저는 이것이 실제로 적절한 http 응답을 반환하지 않기 때문에 오류가 발생한다고 생각합니다.

개인적으로 나는 다음과 같은 기능을 사용합니다.

    module.exports = {
        success: (result) => {
            return {
                statusCode: 200,
                headers: {
                    "Access-Control-Allow-Origin" : "*", // Required for CORS support to work
                    "Access-Control-Allow-Credentials" : true // Required for cookies, authorization headers with HTTPS
                },
                body: JSON.stringify(result),
            }
        },
        internalServerError: (msg) => {
            return {
                statusCode: 500,
                headers: {
                    "Access-Control-Allow-Origin" : "*", // Required for CORS support to work
                    "Access-Control-Allow-Credentials" : true // Required for cookies, authorization headers with HTTPS
                },
                body: JSON.stringify({
                    statusCode: 500,
                    error: 'Internal Server Error',
                    internalError: JSON.stringify(msg),
                }),
            }
        }
} // add more responses here.

그런 다음 간단히 다음을 수행합니다.

var responder = require('responder')

// some code

callback(null, responder.success({ message: 'hello world'}))

로부터 AWS의 문서

Node.js의 Lambda 함수에서 성공적인 응답을 반환하려면 callback (null, { "statusCode": 200, "body": "results"})를 호출하십시오. 예외를 발생 시키려면 callback (new Error ( 'internal server error'))를 호출하십시오. 클라이언트 측 오류 (예 : 필수 매개 변수가 누락 된 경우)의 경우 callback (null, { "statusCode": 400, "body": "Missing parameters of ..."})을 호출하여 오류를 발생시키지 않고 오류를 반환 할 수 있습니다. 예외.


매우 특별한 경우, 헤더를 직접 전달하면 다음과 같은 헤더가있을 가능성이 있습니다.

"set-cookie": [ "........" ]

그러나 Amazon에는 다음이 필요합니다.

"set-cookie": "[ \\"........\\" ]"


응답이 타당 해 보일 때 어려움을 겪는 다른 사람을 위해. 작동하지 않습니다.

callback(null,JSON.stringify( {
  isBase64Encoded: false,
  statusCode: 200,
  headers: { 'headerName': 'headerValue' },
  body: 'hello world'
})

그러나 이것은 :

callback(null,JSON.stringify( {
  'isBase64Encoded': false,
  'statusCode': 200,
  'headers': { 'headerName': 'headerValue' },
  'body': 'hello world'
})

또한 응답 개체에 추가 키가 허용되지 않는 것으로 보입니다.


https://github.com/aws/aws-lambda-go 와 함께 Go 를 사용하는 경우 events.APIGatewayProxyResponse.

func hello(ctx context.Context, event ImageEditorEvent) (events.APIGatewayProxyResponse, error) {
    return events.APIGatewayProxyResponse{
        IsBase64Encoded: false,
        StatusCode:      200,
        Headers:         headers,
        Body:            body,
    }, nil
}

CloudFormation AWS :: Serverless :: Api 리소스에서 실수로 ServerlessExpressLambdaFunctionName 변수를 제거했기 때문에이 오류가 발생했습니다. 여기의 컨텍스트는 https://github.com/awslabs/aws-serverless-express "AWS Lambda 및 Amazon API Gateway를 기반으로 기존 Node.js 애플리케이션 프레임 워크를 사용하여 서버리스 애플리케이션 및 REST API 실행"입니다.


위의 제안을 모두 시도했지만 body가치가없는 동안 작동 하지 않습니다.String

return {
    statusCode: 200,
    headers: {
        "Content-Type": "application/json",
        "Access-Control-Allow-Origin": "*"
    },
    body: JSON.stringify({
        success: true
    }),
    isBase64Encoded: false
};

위의 내용이 누구에게도 작동하지 않는 경우 응답 변수를 올바르게 설정 했음에도 불구하고이 오류가 발생했습니다.

I was making a call to an RDS database in my function. It turned out that what was causing the problem was the security group rules (inbound) on that database.

You'll probably want to restrict the IP addresses that can access the API, but if you want to get it working quick / dirty to test out if that change fixes it you can set it to accept all like so (you can also set the range on the ports to accept all ports too, but I didn't do that in this example):

enter image description here


For Python3:

import json

def lambda_handler(event, context):
    return {
        'statusCode': 200,
        'headers': {
            'Content-Type': 'application/json',
            'Access-Control-Allow-Origin': '*'
        },
        'body': json.dumps({
            'success': True
        }),
        "isBase64Encoded": False
    }

Note the body isn't required to be set, it can just be empty:

        'body': ''

A common cause of the "Malformed Lambda proxy response" error is headers that are not {String: String, ...} key/values pairs.

Since set-cookie headers can and do appear in multiples, they are represented in http.request.callback.response as the set-cookie key having an Array of Strings value instead of a single String. While this works for developers, AWS API Gateway doesn't understand it and throws a "Malformed Lambda proxy response" error.

My solution is to do something like this:

function createHeaders(headers) {
  const singleValueHeaders = {}
  const multiValueHeaders = {}
  Object.entries(headers).forEach(([key, value]) => {
    const targetHeaders = Array.isArray(value) ? multiValueHeaders : singleValueHeaders
    Object.assign(targetHeaders, { [key]: value })
  })

  return {
    headers: singleValueHeaders,
    multiValueHeaders,
  }
}

var output = {
  ...{
    "statusCode": response.statusCode,
    "body": responseString
  },
  ...createHeaders(response.headers)
}

Note that the ... above does not mean Yada Yada Yada. It's the ES6 spread operator.

참고URL : https://stackoverflow.com/questions/43708017/aws-lambda-api-gateway-error-malformed-lambda-proxy-response

반응형