如何列出和复制具有非字母数字字符的s3键?

I have code which lists keys using ListObjectsPages->Contents->Key and copies those keys using CopyObject. This works in general but for some keys it's complaining NoSuchKey: The specified key does not exist. The set of keys it's complaining about include keys with +.

Oddly, if I use the CLI: aws s3 cp on "foo+bar", the copy works. But I can't use the CLI. I need to use the sdk.

I'm using v1.8.11

As Rayfen mentioned, the plus characters could be the result of space replacement.

Update: Everything was hashed out here https://github.com/aws/aws-sdk-go/issues/1438. Rayfen was right about needing to QueryEscape. I'm going to award the only current answer with the bounty since it adds useful information, but not select it as correct.

This details what was happening: https://github.com/aws/aws-sdk-go/issues/1438

  1. The main issue was that CopySource needs to be url-encoded and not the Key field, which was surprising to me. (I was url-encoding both.)
  2. The other issue was that I was using path.Join which strips out trailing \. This is a problem because s3 keys can have trailing \ - which represents a sort of folder.

The object key and metadata document is clear:

The following character sets are generally safe for use in key names:

  • Alphanumeric characters [0-9a-zA-Z]
  • Special characters !, -, _, ., *, ', (, and )

Not only + would be converted into space with, but, from the section "Characters That Might Require Special Handling" of the same page, ':' should also be converted back from space, which QueryUnescape does not do (it only convert space back to +).

Check if your keys include other special characters to be handled with care, like : (also replaced by space), @ or = (replaced by ;), or , and ?.

Check in particular if the key obtained from QueryUnescape has a + instead of a ':' in the original key: that could be a space incorrectly "unescaped".