WEB上のPDFファイルが見れない
なぜかアップロードしたPDFファイルがリンク切れになっていたので
その調査内容を記録します。
ユーザ環境
- MacBook
- Chrome
アプリケーション環境
- AWS EC2
- AWS S3
- ruby 2.6.5
- Rails 5.0.7.2
- refile (0.6.2)
- refile-s3 (0.2.0)
見れないファイルのパターン
チルダ「~」がファイル名に含まれているファイルはリンク切れになってしまう。
ファイルリンクを作成するコード
li
= link_to attachment_url(file, :file), target: '_balnk'
b-icon(icon="attachment")
span.file__name = file.file_filename
実際に生成されるhtml
<a target="_balnk" href="/attachments/xxxxxxx/store/xxxxxx/2020.3%7E2020.4%E3%83%86%E3%82%B9%E3%83%88.pdf">
<span class="file__name">2020.3~2020.4テスト.pdf</span>
</a>
日本語もちゃんとURLエンコードされているし、問題なさそう。
URL規約を調べてみた
URLで使用できる文字は規約で定められていて
いくつかの規約がありましたが、以下2つについてしらべてみました。
- RFC3986
- RFC1738
RFC1738
Unsafe:
Characters can be unsafe for a number of reasons. The space
character is unsafe because significant spaces may disappear and
insignificant spaces may be introduced when URLs are transcribed or
typeset or subjected to the treatment of word-processing programs.
The characters "<" and ">" are unsafe because they are used as the
delimiters around URLs in free text; the quote mark (""") is used to
delimit URLs in some systems. The character "#" is unsafe and should
always be encoded because it is used in World Wide Web and in other
systems to delimit a URL from a fragment/anchor identifier that might
follow it. The character "%" is unsafe because it is used for
encodings of other characters. Other characters are unsafe because
gateways and other transport agents are known to sometimes modify
such characters. These characters are "{", "}", "|", "", "^", "~",
"[", "]", and "`".
All unsafe characters must always be encoded within a URL
チルダは使用するなら必ずエンコードして使わないといけないと明記されていました。
RFC3986
2.3. Unreserved Characters
Characters that are allowed in a URI but do not have a reserved
purpose are called unreserved. These include uppercase and lowercase
letters, decimal digits, hyphen, period, underscore, and tilde.
unreserved = ALPHA / DIGIT / "-" / "." / "_" / "~"
チルダの扱いが「非予約文字」になっていてエンコードなしで使えそうです。
Amazon CloudFrontはどの規約に準拠しているのか?
URL規約を調べたところで
WEBアプリケーションの動作しているAWS環境を調べてみました。
ユーザからRequestをうけるAmazonCloudFrontのドキュメントを見てたら
https://docs.aws.amazon.com/ja_jp/AmazonCloudFront/latest/DeveloperGuide/Invalidation.html
パスに ASCII 以外の文字が含まれるか、RFC 1783 に規定された安全でない文字が含まれる場合、その文字を URL エンコードします
という記述がありました。
なんで見れなかったのか?
上記、調査内容からするとチルダのエンコードで何かしら問題あったということになりますが、、
Rails link_to
で作成されたhtmlリンクは正しくエンコードされている。。
<a target="_balnk" href="/attachments/xxxxxxx/store/xxxxxx/2020.3%7E2020.4%E3%83%86%E3%82%B9%E3%83%88.pdf">
<span class="file__name">2020.3~2020.4テスト.pdf</span>
</a>
ブラウザの問題?
Chrome と Safariで試したところ、SafariからはPDFファイルが見れた!!
Chrome アドレスバーの表示
https://xxxxxx/2020.3~2020.4テスト.pdf
Safari アドレスバーの表示
https://xxxxxx/2020.3%7E2020.4テスト.pdf
エンコードされたリンクを開く際、ブラウザで日本語にデコードしてくれるようだが、
そのデコードによる問題かな。。と推測。
- 参考資料