2017-10-13 78 views
0

我將文件從JS前端上傳到Amazon S3。對Ruby使用aws-sdk-s3我嘗試將對象移動到不同的存儲桶中。我正在使用Aws::S3::Client#copy_object未找到Amazon S3 copy_object密鑰 - 編碼問題?

出於測試目的,我上傳了一個名爲{}?^°!#*äÄÜ?=)(;:- &%$§%2! |<>.jpg的文件。雖然一切都適用於沒有特殊字符的文件,但移動此文件會導致出現Aws::S3::Errors::InvalidArgument Exception: Unsupported copy source parameter錯誤。

我驗證了該文件存在於我名下的S3-Bucket中。以各種方式對對象鍵進行編碼(CGI.escape,URI.escape,URI.encode)沒有幫助。

的片段看起來是這樣的:

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

沒有人有一個想法,爲什麼複製源文件未找到?密鑰中是否包含禁止使用的字符,還是必須對它們進行不同的編碼?

+0

我必須同意一件事。這是給我見過的S3對象最難聽的名字:-D。 –

+0

錯誤沒有說源對象沒有找到。它說這個論點是「無效的」和「不受支持的」。您是否驗證了錯誤響應將使用不存在的簡單(僅字母數字ASCII)源對象密鑰? –

+0

哦,你說得對。 NoSuchKey是不存在的鍵的錯誤。 – Stephan

回答

0

我建議你在發送到S3之前替換所有特殊字符。

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

第一行是沒有文件擴展名(.jpg)的source_key名稱。第二行將任何特殊字符轉換爲沒有口音的最近字符(à - > a,é - > e等)。第三行轉換成'_'任何不在[a-zA-Z]範圍內的字符。最後一行添加文件擴展名。

0

音譯沒有把戲。我最終發現了它自己: 有兩個問題:對於表單提交文件名被編碼,所以特殊字符如?,%+被轉義。我必須在密鑰上執行URI.decode,然後使用aws-sdk-ruby的Aws::Sigv4::Signer.uri_escape(string)對其進行重新編碼。亞馬遜編碼不同,這是事情搞砸了的原因。看看uri_escape的來源:

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