Подтвердить что ты не робот

AWS API Gateway base64Decode производит искаженный двоичный файл?

Я пытаюсь вернуть 1px gif из метода AWS API Gateway.

Поскольку двоичные данные теперь поддерживаются, я возвращаю изображение /gif, используя следующее сопоставление "Интеграция ответа":

$util.base64Decode("R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7")

Однако, когда я смотрю на это в Chrome, я вижу возвращение следующего двоичного файла:

enter image description here

Вместо:

enter image description here

Может ли кто-нибудь помочь мне понять, почему это искажено и неправильной длины? Или что я могу сделать, чтобы вернуть правильный двоичный файл? Есть ли еще что-то, что я всегда мог бы вернуть 1px gif без использования функции base64Decode?

Большое спасибо заранее, это причиняет мне много боли!

РЕДАКТИРОВАТЬ

Это становится страннее. Похоже, проблема связана не с base64Decode, а с общей обработкой двоичного кода. Я добавил бэкэнд Lambda (ранее я использовал Firehose) после этого сообщения в блоге и этого вопроса о переполнении стека. Я установил изображения как binaryMediaType в соответствии с этой страницей документации.

Это позволило мне передать следующий пиксель изображения /bmp из Lambda через API шлюза, и он работает правильно:

exports.handler = function(event, context) {

  var imageHex = "\x42\x4d\x3c\x00\x00\x00\x00\x00\x00\x00\x36\x00\x00\x00\x28\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x01\x00\x18\x00\x00\x00\x00\x00\x06\x00\x00\x00\x27\x00\x00\x00\x27\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xff\xff\xff\xff\x00\x00";
  context.done(null, { "body":imageHex });

};

Однако следующие изображения, представляющие изображение /png или изображение /gif, искажаются при прохождении через:

exports.handler = function(event, context) {

//var imageHex = "\x47\x49\x46\x38\x39\x61\x01\x00\x01\x00\x80\x00\x00\x00\x00\x00\xff\xff\xff\x21\xf9\x04\x01\x00\x00\x00\x00\x2c\x00\x00\x00\x00\x01\x00\x01\x00\x00\x02\x01\x44\x00\x3b";
//var imageHex = "\x47\x49\x46\x38\x39\x61\x01\x00\x01\x00\x80\x00\x00\xff\xff\xff\x00\x00\x00\x21\xf9\x04\x01\x00\x00\x00\x00\x2c\x00\x00\x00\x00\x01\x00\x01\x00\x00\x02\x02\x44\x01\x00\x3b";
  var imageHex = "\x47\x49\x46\x38\x39\x61\x01\x00\x01\x00\x80\x00\x00\x00\x00\x00\x00\x00\x00\x21\xf9\x04\x01\x00\x00\x00\x00\x2c\x00\x00\x00\x00\x01\x00\x01\x00\x00\x02\x02\x44\x01\x00\x3b\x0a"
  context.done(null, { "body":imageHex });

};

Это, похоже, та же проблема, что и вопрос о переполнении стека, но я надеялся, что это будет исправлено с помощью двоичной поддержки Gateway API. К сожалению, image/bmp не работает для моего использования, поскольку он не может быть прозрачным...

В случае, если это помогает кому-то, это был хороший инструмент для преобразования base64 и hex.

4b9b3361

Ответ 1

Похоже, что ранее это была известная проблема: https://forums.aws.amazon.com/thread.jspa?messageID=668306&#668306

Но теперь должно быть возможно, что они добавили поддержку двоичных данных: http://docs.aws.amazon.com/apigateway/latest/developerguide/api-gateway-payload-encodings.html

Похоже, это бит, который нам нужен: "Установите для свойства contentHandling ресурса IntegrationResponse значение CONVERT_TO_BINARY, чтобы получить полезную нагрузку ответа, преобразованную из строки с кодировкой Base64, в ее двоичный код". Тогда нам не нужна функция base64Decode().

Теперь работаем над тестом, чтобы узнать, работает ли это.

РЕДАКТИРОВАТЬ: наконец, я смог получить эту работу. Вы можете увидеть двоичное изображение здесь: https://chtskiuz10.execute-api.us-east-1.amazonaws.com/prod/rest/image

Здесь моя функция Lambda, которая возвращает PNG в кодировке base64 в виде строки: https://gist.github.com/davemaple/73ce3c2c69d5310331395a0210069263

Я обновил ответ метода следующим образом: ответ двоичного метода шлюза api

Я обновил ответ интеграции, включив заголовок с жестким кодированием /png: ответ двоичной интеграции шлюза api

Последний шаг был сложным: установка свойства contentHandling в значение "CONVERT_TO_BINARY". Я не мог понять, как это сделать в консоли AWS. Я должен был использовать API CLI для выполнения этого:

aws apigateway update-integration-response \
    --profile davemaple \
    --rest-api-id chtskiuzxx \
    --resource-id ki1lxx \
    --http-method GET \
    --status-code 200 \
    --patch-operations '[{"op" : "replace", "path" : "/contentHandling", "value" : "CONVERT_TO_BINARY"}]'

Надеюсь, это поможет.

Ответ 2

У кого-нибудь еще есть проблемы с этим: я также ударился головой о стену, пытаясь получить двоичное изображение через API-интерфейс прокси-сервера , но затем Я заметил, что он говорит прямо в разделе Binary Support в Lambda Console:

API Gateway будет искать заголовки Content-Type и Accept, чтобы решить, как обращаться с телом.

Итак, я добавил Accept: image/png в заголовки запроса, и он сработал. О, радость и радость! Не нужно вручную изменять обработку содержимого в CONVERT_TO_BINARY или гадать с кли. Конечно, это исключает использование, например, <img src= напрямую (не может устанавливать заголовки).

Итак, чтобы получить двоичный файл через API-шлюз от лямбда с интеграцией прокси:

  • Список всех поддерживаемых типов двоичного содержимого в консоли лямбды (и развертывании)
  • Заголовок Accept должен содержать заголовок Content-Type, возвращаемый из выражения lambda
  • Возвращаемое тело должно быть закодировано в base64
  • Объект результата должен также иметь свойство isBase64Encoded, установленное в true

код:

callback(null, {
    statusCode: 200,
    headers: { 'Content-Type': 'image/png' },
    body: buffer.toString('base64'),
    isBase64Encoded: true
}

Ответ 3

Отметьте этот ответ. Это помогло мне разоблачить PDF файл для загрузки через GET-запрос без каких-либо дополнительных заголовков.