開発中にハマったのでメモ
状況
以下のようにアプリとS3のファイルを同一ドメインで見られるようにしたかったのでnginxで制御しました。
- /images/* ならS3のバケット内を参照
- 上記以外ならアプリを参照
nginx.conf
(省略)
location / {
proxy_pass http://127.0.0.1:3000; # 通常パスはアプリを見る
}
location ~ ^/images/(.+)$ { # 画像パスはS3を見る
resolver 8.8.8.8;
set $s3_path "s3のバケット名.s3.amazonaws.com";
proxy_pass http://$s3_path/images/$1;
}
(省略)
これでうまく表示できていたのですが、/images/日本語.jpg
といったようなマルチバイト文字を含むファイル名に対して、
http://domain/images/%E6%97%A5%E6%9C%AC%E8%AA%9E.jpg
というようなパスでアクセスしてもS3の403が帰ってきました。
解決法
以下のようにファイルパスを一度変数にして向き先を指定
nginx.conf
(省略)
location / {
proxy_pass http://127.0.0.1:3000; # 通常パスはアプリを見る
}
location ~ ^/images/(.+)$ { # 画像パスはS3を見る
resolver 8.8.8.8;
set $s3_path "s3のバケット名.s3.amazonaws.com";
set $file $1; # マッチしたパスを変数に格納
proxy_pass http://$s3_path/images/$file; # 変数化したパスを指定
}
(省略)
これで表示できるようになりました。
ただ、なぜこれでうまくいくようになったのかが分からず…