LoginSignup
19
16

More than 5 years have passed since last update.

Railsのrequest.urlで使われるHTTPヘッダを調べる

Last updated at Posted at 2017-03-31

概要

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の違い

19
16
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
19
16