Sinatra で正規表現を使ったルートを使う場合に注意すること
Sinatra ではルートの設定に正規表現を使うことができる。例えば以下のような感じで。
get %r{/hello/([\w]+)} do |c| "Hello, #{c}!" endhttp://www.sinatrarb.com/intro.html
問題
上記の例は公式のページに載っているのだけれど、これをそのまま使おうとしたらハマった。正規表現のルートは暗黙的に 先頭から末尾まで という条件を付加してはくれない、ということ。"^" や、"$" は自分で付加しなければならない。なので例のままだと次のようになる。
% ruby app.rb == Sinatra/1.2.6 has taken the stage on 4567 for development with backup from Thin >> Thin web server (v1.2.11 codename Bat-Shit Crazy) >> Maximum connections set to 1024 >> Listening on 0.0.0.0:4567, CTRL+C to stop 192.168.0.1 - - [07/Aug/2011 08:54:04] "GET /hello/sinatra HTTP/1.1" 200 15 0.0019 # 200 Ok 期待通り 192.168.0.1 - - [07/Aug/2011 08:54:19] "GET /aaa/hello/sinatra HTTP/1.1" 200 15 0.0011 # 404 を期待してるのに... 192.168.0.1 - - [07/Aug/2011 08:54:35] "GET /hello/sinatra/zzz HTTP/1.1" 200 15 0.0021 # 同上 192.168.0.1 - - [07/Aug/2011 08:54:52] "GET /aaa/hello/sinatra/zzz HTTP/1.1" 200 15 0.0019 # 同上
ルートにマッチして欲しくないリクエストまでマッチしてしまっている。
解決
適宜 "^" や "$" を付ける。
get %r{^/hello/([\w]+)$} do |c| "Hello, #{c}!" end
% ruby app.rb == Sinatra/1.2.6 has taken the stage on 4567 for development with backup from Thin >> Thin web server (v1.2.11 codename Bat-Shit Crazy) >> Maximum connections set to 1024 >> Listening on 0.0.0.0:4567, CTRL+C to stop 192.168.0.1 - - [07/Aug/2011 09:17:43] "GET /hello/sinatra HTTP/1.1" 200 15 0.0018 # 200 Ok 192.168.0.1 - - [07/Aug/2011 09:17:50] "GET /aaa/hello/sinatra HTTP/1.1" 404 457 0.0013 # 404 期待通り 192.168.0.1 - - [07/Aug/2011 09:17:58] "GET /hello/sinatra/zzz HTTP/1.1" 404 457 0.0013 # 同上 192.168.0.1 - - [07/Aug/2011 09:18:03] "GET /aaa/hello/sinatra/zzz HTTP/1.1" 404 461 0.0003 # 同上