おぎろぐはてブロ

なんだかんだエンジニアになって10年以上

awscli s3apiでの日本語を含むオブジェクト操作

日本語などnon-ascii文字列を含むオブジェクト操作のメモ

"nonあascii" (unicode: \u3042) というオブジェクト名を想定します。

aws s3 rm

ふつうに日本語で実行できる。 (おそらく実行環境に依る)

# Key does not exist
aws s3 rm "s3://bucket/non\u3042ascii"

# delete successful
aws s3 rm "s3://bucket/nonあascii"

s3api delete-object

こちらも同様。 ただ、s3コマンドと違ってファイルの存在を確認しないため、バージョニングが有効だと存在しないファイルにデリートマーカをつくる。

# successful
aws s3api delete-object --bucket "bucket" --key "nonあascii"

# fail (create delete marker to non\\u3042ascii)
aws s3api delete-object --bucket "bucket" --key "non\u3042ascii"

s3api delete-objects

複数指定したい場合は、delete-objects。

以下は失敗パターン。 defaultencoding=asciiの環境だと 'ascii' codec can't encode character u'\u3042' in position 24: ordinal not in range(128) のエラーが出る。

aws s3api delete-objects --bucket "bucket" \
--delete '{"Objects":[{"Key":"non\u3042ascii"}],"Quiet":false}'

aws s3api delete-objects --bucket "bucket" \
--delete '{"Objects":[{"Key":"nonあascii"}],"Quiet":false}'

sitecustomize.pyでデフォルトエンコーディングをUTF-8に変更するとどちらもXML不正エラーが出る。

A client error (MalformedXML) occurred when calling the DeleteObjects operation: The XML you provided was not well-formed or did not validate against our published schema

何が起きているかというと、XMLがおかしい。

0x0000:  4500 0074 8db1 4000 4006 10a5 ac1f 18d5  E..t..@.@.......
0x0010:  36e7 a052 bab8 0050 ddd0 5f96 019d f618  6..R...P.._.....
0x0020:  5018 0073 9c94 0000 3c44 656c 6574 653e  P..s....<Delete>
0x0030:  3c4f 626a 6563 743e 3c4b 6579 3e6e 6f6e  <Object><Key>non
0x0040:  e381 8261 7363 6969 3c2f 4b65 793e 3c2f  ...ascii</Key></
0x0050:  4f62 6a65 6374 3e3c 5175 6965 743e 6661  Object><Quiet>fa
0x0060:  6c73 653c 2f51 7569 6574 3e3c 2f44 656c  lse</Quiet></Del
0x0070:  6574 653e                                ete>

ということで、XML実体参照で送る。

aws s3api delete-objects --bucket "bucket" \
--delete '{"Objects":[{"Key":"non&#x3042;ascii"}],"Quiet":false}'

まとめ

  • s3apiの引数でJSONを指定する場合、non-asciiな文字列はXML実体参照で入れる

JSONとXMLの変換の闇でした。