Introduction

RDB に画像データを保存していたのを S3 に保存し、テーブルには画像データへのパス、つまり S3 でいうところのオブジェクトキーを保存する機能を追加していたところ、奇妙が現象に気づいたのでメモ。

What happend?

開発中なのでわざわざ S3 の環境を用意するのも面倒なのとお金の無駄なので、S3 互換の RustFS を使ってテストをしていた。
言語は C++、C#、Python。
ストレージに C++ のアプリからオブジェクトをプッシュし、C# アプリからオブジェクトを取得しようと思ったら、

The request signature we calculated does not match the signature you provided. Check your key and signing method.

というエラーが出てしまい原因究明に時間がかかった次第。
当然、S3 互換ストレージなので、オブジェクトの URL の発行形式を Virtual にしていのだが、Python アプリからはテーブルに格納したオブジェクトキーで動いていたのに、C# 側では上記のエラーが出たのである。

結論から言うと、オブジェクトキーの先頭に / があるかどうかで、AWS S3 と RustFSに対する、各言語に対応した AWS の公式 SDK の挙動が異なっているのである。

各言語の SDK は

となる。

挙動をまとめると下記になる。

SDK / から始まるかどうか AWS S3 RustFS
AWS SDK for C++ Yes OK OK
No OK OK
AWS SDK for .NET Yes エラー
The specified key does not exist.
エラー
The request signature we calculated does not match the signature you provided. Check your key and signing method.
No OK OK
Boto3 Yes エラー
The specified key does not exist.
OK
No OK OK

AWS S3 の公式の仕様としては先頭の / は含めないのが正解であるが…SDK によって対応が違うと思えば、ストレージ側でも対応が違っており、何が正解なのか…

とりあえず、オブジェクトキーの先頭に / は含めないほうが確実なのは間違いない。
それが公式の仕様だしね。