web-dev-qa-db-fra.com

AWS API Gateway base64Decode produit un fichier binaire tronqué?

J'essaie de renvoyer un gif 1px à partir d'une méthode AWS API Gateway.

Les données binaires étant désormais prises en charge, je retourne une image/gif en utilisant le mappage 'Integration Response' suivant:

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

Cependant, lorsque je regarde ceci dans Chrome, je vois le binaire suivant être renvoyé:

 enter image description here

Au lieu de:

 enter image description here

Quelqu'un pourrait-il m'aider à comprendre pourquoi c'est tronqué et de la mauvaise longueur? Ou ce que je pourrais faire pour retourner le binaire correct? Y at-il autre chose que je pourrais toujours renvoyer ce gif 1px sans utiliser la fonction base64Decode?

Merci beaucoup d'avance, cela m'a causé beaucoup de douleur!

MODIFIER

Celui-ci devient étranger. Il semble que le problème ne soit pas lié à base64Decode, mais au traitement général des fichiers binaires. J'ai ajouté un serveur Lambda (auparavant, j'utilisais Firehose) après cet article de blog et cela Stack Overflow question . J'ai défini les images comme binaryMediaType selon cette page de documentation .

Cela m’a permis de transmettre le pixel image/bmp suivant de Lambda via l’API de la passerelle, et cela fonctionne correctement:

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 });

};

Cependant, les images suivantes représentant une image/png ou une image/gif sont tronquées lorsqu'elles sont transmises:

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 });

};

Cela semble être le même problème que une autre question de débordement de pile , mais j'espérais que ce problème serait résolu avec le support binaire de l'API Gateway. Malheureusement, image/bmp ne fonctionne pas pour mon cas d'utilisation car il ne peut pas être transparent ...

Au cas où cela aiderait quelqu'un, cela a été un bon outil pour convertir entre base64 et hex.

12
rjmurt

Il semble qu'il s'agisse d'un problème connu précédemment: https://forums.aws.Amazon.com/thread.jspa?messageID=668306&#668306

Mais il devrait être possible maintenant qu’ils ont ajouté le support pour les données binaires: http://docs.aws.Amazon.com/apigateway/latest/developerguide/api-gateway-payload-encodings.html

Il semble que ce soit le bit dont nous avons besoin: "Définissez la propriété contentHandling de la ressource IntegrationResponse sur CONVERT_TO_BINARY pour que le contenu de la réponse soit converti d'une chaîne codée en Base64 en son blob binaire". Alors nous ne devrions pas avoir besoin de la fonction base64Decode().

Travailler sur un test maintenant pour voir si cela fonctionne.

EDIT: J'ai finalement réussi à faire fonctionner cela. Vous pouvez voir l'image binaire ici: https://chtskiuz10.execute-api.us-east-1.amazonaws.com/prod/rest/image

Voici ma fonction Lambda qui renvoie le fichier PNG codé en base64 sous forme de chaîne: https://Gist.github.com/davemaple/73ce3c2c69d5310331395a0210069263

J'ai mis à jour la réponse de la méthode comme suit:  api gateway binary method response

J'ai mis à jour la réponse d'intégration pour inclure un en-tête image/png codé en dur:  api gateway binary integration response

La dernière étape était délicate: définir la propriété contentHandling sur "CONVERT_TO_BINARY". Je n'arrivais pas à comprendre comment faire dans la console AWS. Pour ce faire, j'ai dû utiliser l'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"}]'

J'espère que ça aide.

9
Dave Maple

À toute autre personne ayant des problèmes avec ceci: je me frappais aussi la tête contre le mur en essayant de récupérer une image binaire sur API Gateway proxy integration à partir de lambda, mais j’ai alors remarqué que cela Section Support binaire de la console Lambda:

API Gateway examinera les en-têtes HTTP Content-Type et Accept pour décider de la gestion du corps.

J'ai donc ajouté Accept: image/png aux en-têtes de requête et cela a fonctionné. Oh la joie et la joie! Pas besoin de changer manuellement la gestion du contenu en CONVERT_TO_BINARY ou de bouger avec la cli. Bien sûr, cela exclut d'utiliser, par exemple, <img src= directement (impossible de définir les en-têtes).

Donc, pour obtenir un fichier binaire sur API Gateway de lambda avec intégration de proxy:

  • Répertoriez tous les types de contenu binaire pris en charge dans la console lambda (et déployez-les)
  • L'en-tête d'acceptation de la demande doit inclure l'en-tête Content-Type renvoyé par l'expression lambda.
  • Le corps retourné doit être encodé en base64
  • La propriété isBase64Encoded doit également être définie sur true pour l'objet de résultat. 

Code:

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

Découvrez cette réponse . Cela m'a aidé à exposer le fichier PDF au téléchargement via une requête GET sans en-têtes supplémentaires.

0
MEGApixel23