こんにちは!kossyです!
今回は、ActionDispatch::Http::URLのsubdomainメソッドのソースコードを読む機会があったので、備忘録としてブログに残してみたいと思います。
subdomainメソッド
ソースコードの位置はこちらです。
# Returns all the \subdomains as a string, so <tt>"dev.www"</tt> would be # returned for "dev.www.rubyonrails.org". You can specify a different <tt>tld_length</tt>, # such as 2 to catch <tt>"www"</tt> instead of <tt>"www.rubyonrails"</tt> # in "www.rubyonrails.co.uk". def subdomain(tld_length = @@tld_length) ActionDispatch::Http::URL.extract_subdomain(host, tld_length) end
コメントアウト部分を訳してみます。
Returns all the \subdomains as a string, so "dev.www" would be returned for "dev.www.rubyonrails.org". You can specify a different tld_length, such as 2 to catch "www" instead of "www.rubyonrails" in "www.rubyonrails.co.uk".
すべての\ subdomainsを文字列として返すため、「dev.www.rubyonrails.org」に対して "dev.www" が返されます。 「www.rubyonrails.co.uk」の中で、「www.rubyonrails」の代わりに「www」をキャッチするために、2などの別の tld_length を指定できます。
出典: https://github.com/rails/rails/blob/6-1-stable/actionpack/lib/action_dispatch/http/url.rb#L341
引数でキャッチするサブドメインの階層を指定できるようです。
例えば、https://www.dev.sample.comがRequestのurlの場合、
$ request.subdomain => "www.dev" $ request.subdomain(2) => "www" $ request.subdomain(3) => ""
の返り値を得られます。(存在しないサブドメインの階層が指定されても例外上がらないのか、、、)
実際にサブドメインを算出する処理は、ActionDispatch::Http::URL.extract_subdomainで行っているようなので、見に行ってみます。
# Returns the subdomains of a host as a String given the domain level. # # # Top-level domain example # extract_subdomain('www.example.com', 1) # => "www" # # Second-level domain example # extract_subdomain('dev.www.example.co.uk', 2) # => "dev.www" def extract_subdomain(host, tld_length) extract_subdomains(host, tld_length).join(".") end # Returns the subdomains of a host as an Array given the domain level. # # # Top-level domain example # extract_subdomains('www.example.com', 1) # => ["www"] # # Second-level domain example # extract_subdomains('dev.www.example.co.uk', 2) # => ["dev", "www"] def extract_subdomains(host, tld_length) if named_host?(host) extract_subdomains_from(host, tld_length) else [] end end # 実際にサブドメインを算出する処理 def extract_subdomains_from(host, tld_length) parts = host.split(".") parts[0..-(tld_length + 2)] end
extract_subdomains_fromのコードをコンソールから試してみましょう。
# 適当なコントローラーでbinding.pryで処理を止める $ host = request.host => "www.dev.sample.com" $ parts = host.split(".") => ["www", "dev", "sample", "com"] $ tld_length = 1 $ parts[0..-(tld_length + 2)] => ["www", "dev"] $ tld_length = 2 $ parts[0..-(tld_length + 2)] => ["www"]
subdomainsメソッド
ついでにsubdomainsメソッドも読んでみます。
# Returns all the \subdomains as an array, so <tt>["dev", "www"]</tt> would be # returned for "dev.www.rubyonrails.org". You can specify a different <tt>tld_length</tt>, # such as 2 to catch <tt>["www"]</tt> instead of <tt>["www", "rubyonrails"]</tt> # in "www.rubyonrails.co.uk". def subdomains(tld_length = @@tld_length) ActionDispatch::Http::URL.extract_subdomains(host, tld_length) end
コメントアウト部分を訳してみます。
Returns all the \subdomains as an array, so ["dev", "www"] would be returned for "dev.www.rubyonrails.org". You can specify a different tld_length, such as 2 to catch ["www"] instead of ["www", "rubyonrails"] in "www.rubyonrails.co.uk".
すべての\ subdomainsを配列として返すため、「dev.www.rubyonrails.org」に対して ["dev"、 "www"] が返されます。 ["www"、 "rubyonrails"] の代わりに ["www"] をキャッチするために2などの別の tld_length を指定できます。 「www.rubyonrails.co.uk」。
出典: https://github.com/rails/rails/blob/6-1-stable/actionpack/lib/action_dispatch/http/url.rb#L333
こちらもコンソールで試してみます。
$ request.subdomains => ["www", "dev"] $ request.subdomains(1) => ["www", "dev"] $ request.subdomains(2) => ["www"]
サブドメインが配列で返ることがわかりました。
@tld_lengthが追加された経緯
取得するサブドメインの階層を指定できるtld_lengthですが、どういった経緯で追加されたのでしょうか。
該当のコミットはこちらでした。
Pull Requestは私の調査力不足で見つけられなかったのですが、1で固定だったのをconfigファイルで設定できるように修正したようです。
ちなみに、tldは「Top Level Domain」の略のようです。