タイトルがすべてって感じです (しろめ) 。
日本語ファイルにアクセスすると死ぬ
public 以下に配置した /doc/テスト2017.pdf
みたいな日本語ファイルにアクセスすると ActionController::RoutingError
が発生して死ぬ。
該当部の実装
こんな感じ、日本語ファイルへのリンク扱ってるのこの部分だけなので、直接 URI.encode
書いてるんだと思われる。
推測なのは、開発した人全員居なくなったか別プロジェクト行ったので、流れで引き継いだ感じで「(実装時の意図が) だいたい全然わからねえ」状態になりつつあるためです。
やべぇよやべぇよ。
= link_to "/doc/#{URI.encode("テスト2017.pdf")}", target: "_blank" do
どうなる?
以下のようにログへエラー出力されます。 public 以下でルーティングエラーなんて吐くんじゃないよこっちが困るだろう、というお気持ち。
I, [2020-10-12T21:26:03.399294 #24628] INFO -- : [aaaaaaaa-bbbb-cccc-dddd-123456789abc] Started GET "/doc/%E3%83%86%E3%82%B9%E3%83%882017.pdf" for 169.254.169.254 at 2020-10-12 21:26:03 +0900 F, [2020-10-12T21:26:03.399956 #24628] FATAL -- : [aaaaaaaa-bbbb-cccc-dddd-123456789abc] F, [2020-10-12T21:26:03.400007 #24628] FATAL -- : [aaaaaaaa-bbbb-cccc-dddd-123456789abc] ActionController::RoutingError (No route matches [GET] "/doc/%E3%83%86%E3%82%B9%E3%83%882017.pdf"): F, [2020-10-12T21:26:03.400043 #24628] FATAL -- : [aaaaaaaa-bbbb-cccc-dddd-123456789abc] F, [2020-10-12T21:26:03.400074 #24628] FATAL -- : [aaaaaaaa-bbbb-cccc-dddd-123456789abc] actionpack (5.1.7) lib/action_dispatch/middleware/debug_exceptions.rb:63:in `call' [aaaaaaaa-bbbb-cccc-dddd-123456789abc] actionpack (5.1.7) lib/action_dispatch/middleware/show_exceptions.rb:31:in `call' [aaaaaaaa-bbbb-cccc-dddd-123456789abc] railties (5.1.7) lib/rails/rack/logger.rb:36:in `call_app' [aaaaaaaa-bbbb-cccc-dddd-123456789abc] railties (5.1.7) lib/rails/rack/logger.rb:24:in `block in call' [aaaaaaaa-bbbb-cccc-dddd-123456789abc] activesupport (5.1.7) lib/active_support/tagged_logging.rb:69:in `block in tagged' [aaaaaaaa-bbbb-cccc-dddd-123456789abc] activesupport (5.1.7) lib/active_support/tagged_logging.rb:26:in `tagged' [aaaaaaaa-bbbb-cccc-dddd-123456789abc] activesupport (5.1.7) lib/active_support/tagged_logging.rb:69:in `tagged' [aaaaaaaa-bbbb-cccc-dddd-123456789abc] railties (5.1.7) lib/rails/rack/logger.rb:24:in `call' [aaaaaaaa-bbbb-cccc-dddd-123456789abc] actionpack (5.1.7) lib/action_dispatch/middleware/remote_ip.rb:79:in `call' [aaaaaaaa-bbbb-cccc-dddd-123456789abc] request_store (1.4.0) lib/request_store/middleware.rb:19:in `call' [aaaaaaaa-bbbb-cccc-dddd-123456789abc] actionpack (5.1.7) lib/action_dispatch/middleware/request_id.rb:25:in `call' [aaaaaaaa-bbbb-cccc-dddd-123456789abc] rack (2.2.3) lib/rack/method_override.rb:24:in `call' [aaaaaaaa-bbbb-cccc-dddd-123456789abc] rack (2.2.3) lib/rack/runtime.rb:22:in `call' [aaaaaaaa-bbbb-cccc-dddd-123456789abc] activesupport (5.1.7) lib/active_support/cache/strategy/local_cache_middleware.rb:27:in `call' [aaaaaaaa-bbbb-cccc-dddd-123456789abc] actionpack (5.1.7) lib/action_dispatch/middleware/executor.rb:12:in `call' [aaaaaaaa-bbbb-cccc-dddd-123456789abc] rack (2.2.3) lib/rack/sendfile.rb:110:in `call' [aaaaaaaa-bbbb-cccc-dddd-123456789abc] railties (5.1.7) lib/rails/engine.rb:522:in `call' [aaaaaaaa-bbbb-cccc-dddd-123456789abc] passenger (5.2.3) src/ruby_supportlib/phusion_passenger/rack/thread_handler_extension.rb:97:in `process_request' [aaaaaaaa-bbbb-cccc-dddd-123456789abc] passenger (5.2.3) src/ruby_supportlib/phusion_passenger/request_handler/thread_handler.rb:152:in `accept_and_process_next_request' [aaaaaaaa-bbbb-cccc-dddd-123456789abc] passenger (5.2.3) src/ruby_supportlib/phusion_passenger/request_handler/thread_handler.rb:113:in `main_loop' [aaaaaaaa-bbbb-cccc-dddd-123456789abc] passenger (5.2.3) src/ruby_supportlib/phusion_passenger/request_handler.rb:416:in `block (3 levels) in start_threads' [aaaaaaaa-bbbb-cccc-dddd-123456789abc] passenger (5.2.3) src/ruby_supportlib/phusion_passenger/utils.rb:113:in `block in create_thread_and_abort_on_exception'
どうした
日本語ファイルをやめました。
ロケーションバーに直接 http://localhost/doc/テスト2017.pdf
と入力するとアクセスできるのですが、 link_to で生成されたリンクを踏んで開いたロケーションバーからコピペしてアクセスすると、一瞬 URI.encode された文字列が見えてから日本語ファイル名で表示されます。
また、 /doc/test2017.pdf
など設置して link_to 向き先を変更した所、問題なく表示することが出来たため「やはりファイル名はアルファベットであるな」となりもうした。
今これ書いてる最中にログ見てて気づいたんですが、もしや Passenger 側が悪いのか?
rails_serve_static_files
周りの問題かと思ってたのですが、Nginx+Puma だと問題再現しなかったのでそんな気がしてきた。
もし解決しないといけなくなったら調べよう。
ちなみに
URI.encode
は obsolate なので、 CGI.escape
とか使うべきとのことです。
はいぃ……。