AR ホームベーカリー

オイラのアウトプット用ホームベーカリー!

URI.encode した日本語ファイルへのアクセスで ActionController::RoutingError が発生する

タイトルがすべてって感じです (しろめ) 。

日本語ファイルにアクセスすると死ぬ

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 とか使うべきとのことです。 はいぃ……。

docs.ruby-lang.org