Qiita Teams that are logged in
You are not logged in to any team

Log in to Qiita Team
Community
OrganizationAdvent CalendarQiitadon (β)
Service
Qiita JobsQiita ZineQiita Blog
Help us understand the problem. What is going on with this article?

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

More than 3 years have passed since last update.

概要

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

Esfahan
WEB系出身。現在はビッグデータの基盤構築、ETLなどがメイン。 / YouTubeで料理チャンネルやってます → https://www.youtube.com/channel/UCDnYBh2TtUAfQ0Z-tl0jTyw
https://www.youtube.com/channel/UCDnYBh2TtUAfQ0Z-tl0jTyw
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away