概要
railsのrequest.url
で使われるHTTPヘッダを調べたので、そのメモ。
環境
- Rails 5.0.1
- ruby 2.3.3
urlクラス
vendor/bundle/ruby/2.3.0/gems/actionpack-5.0.0.1/lib/action_dispatch/http/url.rb
このクラスが request.url
を作っている。
以下は関連個所のみの抜粋、これだけ調べれば全容は分かりそう。
def url
protocol + host_with_port + fullpath
end
def host_with_port
"#{host}#{port_string}"
end
def port_string
standard_port? ? '' : ":#{port}"
end
def protocol
@protocol ||= ssl? ? 'https://' : 'http://'
end
url
は、 protocol + host_with_port + fullpath
なので、この3つを追う。
その他も同じように、メソッド内で呼ばれているものを更に追う。
メソッド | 呼ばれているもの |
---|---|
url | protocol, host_with_port, fullpath |
host_with_port | host, port_string |
port_string | port |
protocol | ssl |
requestクラス
url
メソッドの fullpath
を調べようと思いrequestクラスを見たところ、 super
を呼んでいるので、
このクラスはスルーし親クラスを探ることにする。
vendor/bundle/ruby/2.3.0/gems/actionpack-5.0.0.1/lib/action_dispatch/http/request.rb
関連個所のみ抜粋
# Returns the +String+ full path including params of the last URL requested.
#
# # get "/articles"
# request.fullpath # => "/articles"
#
# # get "/articles?page=2"
# request.fullpath # => "/articles?page=2"
def fullpath
@fullpath ||= super
end
request親クラス
vendor/bundle/ruby/2.3.0/gems/rack-2.0.1/lib/rack/request.rb
関連個所のみ抜粋
def script_name; get_header(SCRIPT_NAME).to_s end
def path_info; get_header(PATH_INFO).to_s end
def query_string; get_header(QUERY_STRING).to_s end
def path
script_name + path_info
end
def fullpath
query_string.empty? ? path : "#{path}?#{query_string}"
end
def host
# Remove port number.
host_with_port.to_s.sub(/:\d+\z/, '')
end
def host_with_port
if forwarded = get_header(HTTP_X_FORWARDED_HOST)
forwarded.split(/,\s?/).last
else
get_header(HTTP_HOST) || "#{get_header(SERVER_NAME) || get_header(SERVER_ADDR)}:#{get_header(SERVER_PORT)}"
end
end
def port
if port = host_with_port.split(/:/)[1]
port.to_i
elsif port = get_header(HTTP_X_FORWARDED_PORT)
port.to_i
elsif has_header?(HTTP_X_FORWARDED_HOST)
DEFAULT_PORTS[scheme]
elsif has_header?(HTTP_X_FORWARDED_PROTO)
DEFAULT_PORTS[get_header(HTTP_X_FORWARDED_PROTO).split(',')[0]]
else
get_header(SERVER_PORT).to_i
end
end
def ssl?
scheme == 'https'
end
メソッド | 呼ばれているもの |
---|---|
fullpath | path, query_string |
path | script_name, path_info |
host | host_with_port |
と追っていくと、最終的に、下記のHTTPヘッダが使われていることが分かる。
メソッド | ヘッダ |
---|---|
script_name | SCRIPT_NAME |
path_info | PATH_INFO |
query_string | QUERY_STRING |
host_with_port | HTTP_HOST, SERVER_NAME, SERVER_ADDR, SERVER_PORT |
port | HTTP_X_FORWARDED_PORT, HTTP_X_FORWARDED_HOST, HTTP_X_FORWARDED_PROTO, SERVER_PORT |
結論
ということで、 request.url
で使われるHTTPヘッダは以下となる。
- HTTP_HOST
- QUERY_STRING
- PATH_INFO
- SCRIPT_NAME
- HTTP_X_FORWARDED_HOST
- SERVER_NAME
- SERVER_ADDR
- SERVER_PORT
- HTTP_X_FORWARDED_PORT
- HTTP_X_FORWARDED_HOST
- HTTP_X_FORWARDED_PROTO
以上
参考
[Rails3] 現在のURLを取得(request オブジェクト)
Railsでrequest.urlとrequest.original_urlの違い