Class: Apigatewayv2Rack::Request

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

Overview

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(event, context, use_x_forwarded_host: false) ⇒ Request

Returns a new instance of Request.



14
15
16
17
18
19
# File 'lib/apigatewayv2_rack/request.rb', line 14

def initialize(event, context, use_x_forwarded_host: false)
  @event = event
  @context = context

  @use_x_forwarded_host = use_x_forwarded_host
end

Instance Attribute Details

#contextObject (readonly)

Returns the value of attribute context.



21
22
23
# File 'lib/apigatewayv2_rack/request.rb', line 21

def context
  @context
end

#eventObject (readonly)

Returns the value of attribute event.



21
22
23
# File 'lib/apigatewayv2_rack/request.rb', line 21

def event
  @event
end

#use_x_forwarded_hostObject (readonly)

Returns the value of attribute use_x_forwarded_host.



22
23
24
# File 'lib/apigatewayv2_rack/request.rb', line 22

def use_x_forwarded_host
  @use_x_forwarded_host
end

Instance Method Details

#bodyObject



53
54
55
# File 'lib/apigatewayv2_rack/request.rb', line 53

def body
  @body ||= event['body'] ? (event['isBase64Encoded'] ? Base64.decode64(event['body']) : event['body']) : ''
end

#cookies_as_envObject



76
77
78
79
80
81
82
# File 'lib/apigatewayv2_rack/request.rb', line 76

def cookies_as_env
  if event['cookies']
    { 'HTTP_COOKIE' => event['cookies'].join('; ') }
  else
    {}
  end
end

#elb?Boolean

Returns:

  • (Boolean)


24
25
26
# File 'lib/apigatewayv2_rack/request.rb', line 24

def elb?
  event.dig('requestContext')&.key?('elb')
end

#headersObject



61
62
63
64
# File 'lib/apigatewayv2_rack/request.rb', line 61

def headers
  # Assume everything is lower-cased
  @headers ||= event['multiValueHeaders']&.transform_values { |v| v.join(',') } || event['headers']
end

#headers_as_envObject



66
67
68
69
70
71
72
73
74
# File 'lib/apigatewayv2_rack/request.rb', line 66

def headers_as_env
  r = {}
  headers.each do |k,v|
    next if k == 'content-type'
    next if k == 'content-length'
    r["HTTP_#{k.upcase.tr(?-, ?_)}"] = v
  end
  r
end

#multivalued?Boolean

Returns:

  • (Boolean)


28
29
30
# File 'lib/apigatewayv2_rack/request.rb', line 28

def multivalued?
  event.key?('multiValueHeaders')
end

#pathObject



40
41
42
# File 'lib/apigatewayv2_rack/request.rb', line 40

def path
  (event['rawPath'] || event['path']) or raise Apigatewayv2Rack::Error.new("neither rawPath and path are defined")
end

#protocolObject



32
33
34
# File 'lib/apigatewayv2_rack/request.rb', line 32

def protocol
  event.dig('requestContext', 'http', 'protocol') || 'HTTP/1.1'
end

#query_stringObject



44
45
46
# File 'lib/apigatewayv2_rack/request.rb', line 44

def query_string
  event['rawQueryString'] || encode_query_string_parameters(event['multiValueQueryStringParameters'] || event['queryStringParameters']) || ''
end

#request_methodObject



36
37
38
# File 'lib/apigatewayv2_rack/request.rb', line 36

def request_method
  event['httpMethod'] || event.fetch('requestContext').fetch('http').fetch('method')
end

#source_ipObject



57
58
59
# File 'lib/apigatewayv2_rack/request.rb', line 57

def source_ip
  event.dig('requestContext', 'http', 'sourceIp') || '0.0.0.0' # XXX:
end

#to_hObject



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/apigatewayv2_rack/request.rb', line 84

def to_h
  {
    'SERVER_PROTOCOL' => protocol,
    'REQUEST_METHOD' => request_method,
    'SCRIPT_NAME' => '',
    'PATH_INFO' => path,
    'QUERY_STRING' => query_string,
    'SERVER_NAME' => headers['host'] || 'unknown',
    'SERVER_PORT' => (use_x_forwarded_host && ['x-forwarded-port']&.to_i&.to_s) || '80',
    'CONTENT_LENGTH' => body.bytesize.to_s,
    'CONTENT_TYPE' => headers['content-type'] || '',
    'REMOTE_ADDR' => source_ip,
    'rack.version' => Rack::VERSION,
    'rack.url_scheme' => (use_x_forwarded_host && headers['x-forwarded-proto']) || 'https',
    'rack.input' => StringIO.new(body),
    'rack.errors' => $stderr,
    'rack.multithread' => false,
    'rack.multiprocess' => false,
    'rack.run_once' => false,
    # compat with serverless-rack gem
    'serverless.event' => event,
    'serverless.context' => context,
    'serverless.authorizer' => nil,
    # itself
    'apigatewayv2.request' => self,
  }
    .merge(headers_as_env)
    .merge(cookies_as_env)
rescue KeyError => e
  raise Apigatewayv2Rack::Error.new("malformed request: #{e.inspect}")
end