2017-10-13 12 views
0

J'ai téléchargé des fichiers à partir d'un JS-Frontend vers Amazon S3. En utilisant aws-sdk-s3 pour Ruby, j'essaie de déplacer des objets dans un autre seau. J'utilise Aws::S3::Client#copy_object pour cela.Amazon S3 copy_object clé non trouvée - problèmes d'encodage?

À des fins de test, j'ai téléchargé un fichier nommé {}?^°!#*äÄÜ?=)(;:- &%$§%2! |<>.jpg. Alors que tout fonctionne pour les fichiers sans caractères spéciaux, le déplacement de ce fichier entraîne une erreur Aws::S3::Errors::InvalidArgument Exception: Unsupported copy source parameter.

J'ai vérifié que le fichier existe dans mon S3-Bucket sous ce nom. Encoder la clé d'objet de diverses manières (CGI.escape, URI.escape, URI.encode) n'a pas aidé.

L'extrait ressemble à ceci:

s3 = Aws::S3::Client.new(region: ENV['AWS_REGION']) 
    source_key = "{}?^°!#*äÄÜ?=)(;:- &%$§%2! |<>.jpg" 
    s3.copy_object({ copy_source: 'mybucket1/' + source_key, 
        bucket:  'mybucket2', 
        key:   'new_file_name.jpg' }) 

Est-ce que quelqu'un a une idée, pourquoi la source de copie ne se trouve pas? La clé inclut-elle des caractères interdits ou dois-je les encoder différemment?

+0

Je suis d'accord sur une chose. C'est le nom le plus étrange donné à un objet s3 que j'ai même vu :-D. –

+0

L'erreur ne dit pas que l'objet source n'a pas été trouvé. Il dit que l'argument est "invalide" et "non pris en charge". Avez-vous vérifié quelle serait la réponse d'erreur avec une clé d'objet source simple (c'est-à-dire uniquement ASCII alphanumérique) qui n'existe pas? –

+0

Oh, vous avez raison. NoSuchKey est l'erreur pour une clé non existante. – Stephan

Répondre

0

Je vous suggère de remplacer tous les caractères spéciaux avant d'envoyer à S3.

source_key = "{}?^°!#*äÄÜ?=)(;:- &%$§%2! |<>" 
source_key = I18n.transliterate(source_key) 
source_key.gsub! /\W/, '_' 
source_key += '.jpg' 

La première ligne est le nom source_key sans extension de fichier (.jpg). La deuxième ligne transforme n'importe quel caractère spécial en son caractère le plus proche sans accent (à -> a, é -> e, etc.). La troisième ligne transforme en '_' tout caractère qui n'est pas dans la plage [a-zA-Z]. La dernière ligne ajoute l'extension de fichier.

0

La translittération n'a pas fait l'affaire. J'ai finalement compris par moi-même: Il y avait deux problèmes: Pour la soumission de formulaire le nom de fichier a été codé, donc des caractères spéciaux comme ?, % et ont été échappés. Je devais faire un URI.decode sur la clé, puis ré-encoder en utilisant Aws::Sigv4::Signer.uri_escape(string) de aws-sdk-ruby. Amazon ne codage pas différemment, ce qui était la raison pour laquelle les choses ont mal tourné. Jetez un oeil à la source de uri_escape:

def uri_escape(string) 
    CGI.escape(string.encode('UTF-8')).gsub('+', '%20').gsub('%7E', '~') 
end