Class: Magellan::Rails::Request

Inherits:
Object
  • Object
show all
Defined in:
lib/magellan/rails/request.rb

Constant Summary collapse

RACK_HEADER =
Set.new ['CONTENT_LENGTH', 'CONTENT_TYPE', 'GATEWAY_INTERFACE',
'Path-Info', 'Query-String', "Method", "Server-Name", "Server-Port"]
VALID_ENCODING =
%w(plain base64)

Instance Attribute Summary collapse

Instance Method Summary collapse

Instance Attribute Details

#bodyObject (readonly)

Returns the value of attribute body.



7
8
9
# File 'lib/magellan/rails/request.rb', line 7

def body
  @body
end

#body_encodingObject (readonly)

Returns the value of attribute body_encoding.



7
8
9
# File 'lib/magellan/rails/request.rb', line 7

def body_encoding
  @body_encoding
end

#headersObject (readonly)

Returns the value of attribute headers.



7
8
9
# File 'lib/magellan/rails/request.rb', line 7

def headers
  @headers
end

#optionsObject (readonly)

Returns the value of attribute options.



7
8
9
# File 'lib/magellan/rails/request.rb', line 7

def options
  @options
end

Instance Method Details

#decode_body(body, encoding) ⇒ Object

現在対応しているencodingは以下。

  • base64: Base64デコードする

  • plain: デコードせずそのままの値を返す

Parameters:

  • body (String)

    リクエストボディ

  • encoding (String)

    エンコード形式



124
125
126
127
128
129
130
131
# File 'lib/magellan/rails/request.rb', line 124

def decode_body(body, encoding)
  case encoding.to_sym
  when :base64 then
    Base64.decode64(body)
  else
    body
  end
end

#option(key) ⇒ Object



14
15
16
# File 'lib/magellan/rails/request.rb', line 14

def option(key)
  options[key]
end

#parse_message(request_message) ⇒ Object



24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
# File 'lib/magellan/rails/request.rb', line 24

def parse_message(request_message)
  # v2 からリクエストオブジェクトに "v": 2 のようにバージョンが追加されるようになりました。
  @version = request_message["v"] || 1
  @options = request_message['options']
  # TRから送られるメッセージのoptionsの型が本来はHash型なのですが、
  # 過去に配列型になってしまっていたバージョンがあったためクラスもチェックします
  unless @options.is_a?(Hash)
    @options = {}
  end
  @env = request_message["env"] || {}
  @headers = request_message['headers'].each_with_object({}){|(k, v), tbl| tbl[k.downcase] = v }
  @body_encoding = request_message['body_encoding']
  @body_encoding = (@body_encoding.present? and VALID_ENCODING.include?(@body_encoding)) ? @body_encoding.to_sym : :plain
  @body          = decode_body(request_message['body'], @body_encoding)
end

#reply_ttlObject



18
19
20
21
22
# File 'lib/magellan/rails/request.rb', line 18

def reply_ttl
  # TRからのメッセージにワーカー処理結果の送信時に指定するttlが含まれていない場合, 1秒を設定します
  ttl = options['reply_ttl'] || 1000
  ttl.to_i
end

#to_rack_envObject



40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
# File 'lib/magellan/rails/request.rb', line 40

def to_rack_env
  env = Hash.new

  case @version
  when 1
    http_method = @headers["method"]
    path_info = @headers["path-info"]
    query_string = @headers["query-string"]
    server_name = @headers["server-name"]
    server_port = @headers['server-port'].to_s
  when 2
    http_method = @env["METHOD"]
    path_info = @env["PATH_INFO"]
    query_string = @env["QUERY_STRING"]
    server_name = @env["SERVER_NAME"]
    server_port = @env['SERVER_PORT'].to_s
  else
    raise "Unsupported request format version: #{@version}. Please update magellan-rails."
  end

  scripe_name  = path_info[path_info.rindex('/') + 1..-1]

  # Rackにクエリーストリングを渡す時は
  query_string.slice!(0) if (query_string[0] == '?')

  ct = @headers["content-type"]

  env["CONTENT_LENGTH"]    = @body.bytesize
  env["CONTENT_TYPE"]      = ct.dup if ct
  env["GATEWAY_INTERFACE"] = "CGI/1.1"
  env["PATH_INFO"]         = path_info    # "/hello/index",
  env["QUERY_STRING"]      = query_string #

  # TRから送られてきていないので一旦コメントアウト
  # env["REMOTE_ADDR"]       = @peeraddr[3]
  # env["REMOTE_HOST"]       = @peeraddr[2]
  # env["REMOTE_USER"]       = @user

  env["REQUEST_METHOD"]    = http_method      # GET, PUT, DELETE...
  env["REQUEST_URI"]       = "#{env["PATH_INFO"]}?#{env["QUERY_STRING"]}"
  env["SCRIPT_NAME"]       = ''                       # /scripts/sample?a=c  の場合 ルートなので ''
  env["SERVER_NAME"]       = server_name  # "localhost"
  env["SERVER_PORT"]       = server_port  # "3000"

  # 一旦決め打ち
  env["SERVER_PROTOCOL"]   = "HTTP/1.1"

  env["SERVER_SOFTWARE"]   = 'magellan'

   @headers.each{|key, val|
    next if RACK_HEADER.include? key
    name = "HTTP_" + key
    name.gsub!(/-/o, "_")
    name.upcase!
    env[name] = val
  }

  env["rack.version"]      = [1, 5, 2]
  env["rack.url_scheme"]   = "http"
  env["rack.multithread"]  = true
  env["rack.multiprocess"] = false
  env["rack.run_once"]     = false
  env["rack.hijack?"]      = false

  env['rack.input']        = StringIO.new(@body.to_s)

  # 本来はロガーに渡すべきだが、設計するまで一旦標準エラー出力に出します
  env["rack.errors"]       = $stderr

  env["HTTP_VERSION"]      = env["SERVER_PROTOCOL"]
  env["REQUEST_PATH"]      = env["PATH_INFO"]
  env['rack.logger']       = Magellan.logger

  env
end