web-dev-qa-db-fra.com

AWS: comment corriger l'événement S3 en remplaçant l'espace par le signe '+' dans les noms de clé d'objet dans json

J'ai une fonction lamba pour copier des objets du bucket 'A' vers le bucket 'B', et tout fonctionnait bien, jusqu'à ce qu'un objet avec le nom 'New Text Document.txt' soit créé dans le bucket 'A', le json qui est construit dans l'événement S3, saisissez "clé": "Nouveau + Texte + Document.txt".

les espaces ont été remplacés par "+". Je sais que c'est un problème connu en recherchant sur le Web. Mais je ne sais pas comment résoudre ce problème et le json entrant lui-même a un "+" et "+" peut être en fait dans le nom du fichier. comme 'Nouveau + Document Texte.txt'.

Je ne peux donc pas avoir aveuglément une logique pour espacer '+' par '' dans ma fonction lambda.

En raison de ce problème, lorsque le code essaie de trouver le fichier dans le compartiment, il ne le trouve pas.

Veuillez suggérer.

18
ViS

Ce que j'ai fait pour résoudre ce problème,

Java.net.URLDecoder.decode(b.getS3().getObject().getKey(), "UTF-8")


{
    "Records": [
        {
            "s3": {
                "object": {
                    "key": "New+Text+Document.txt"
                }
            }
        }
    ]
}

Alors maintenant, la valeur JSon, "Nouveau + Texte + Document.txt" est correctement convertie en Nouveau Texte Document.txt.

Cela a résolu mon problème, veuillez suggérer s'il s'agit d'une solution très correcte. Y aura-t-il un cas de coin qui pourrait casser ma mise en œuvre.

7
ViS

Je suis tombé sur cette recherche d'une solution pour un lambda écrit en python au lieu de Java; "urllib.parse.unquote_plus" a fonctionné pour moi, il a correctement géré un fichier avec les deux espaces et les signes +:

from urllib.parse import unquote_plus
import boto3


bucket = 'testBucket1234'
# uploaded file with name 'foo + bar.txt' for test, s3 Put event passes following encoded object_key
object_key = 'foo %2B bar.txt'
print(object_key)
object_key = unquote_plus(object_key)
print(object_key)

client = boto3.client('s3')
client.get_object(Bucket=bucket, Key=object_key)
14
kinzleb

D'accord avec Scott. pour moi, créer un objet objet ajoutait% 3 pour le point-virgule: je dois le remplacer deux fois pour obtenir l'URL s3 correcte

python

def lambda_handler(event, context):
logger.info('Event: %s' % json.dumps(event))
source_bucket = event['Records'][0]['s3']['bucket']['name']
key_old = event['Records'][0]['s3']['object']['key']
key_new = key_old.replace('%3',':')
key = key_new.replace(':A',':')
logger.info('key value')
logger.info(key)
0
Hitesh

Je pense que vous devriez utiliser:

getS3().getObject().getUrlDecodedKey()

méthode qui retourne la clé décodée, au lieu de

getS3().getObject().getKey()
0
MeetJoeBlack