forked from rails-lambda/lamby
/
rack_http.rb
104 lines (89 loc) Β· 2.7 KB
/
rack_http.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
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
module Lamby
class RackHttp < Lamby::Rack
class << self
def handle?(event)
event.key?('version') &&
( event.dig('requestContext', 'http') ||
event.dig('requestContext', 'httpMethod') )
end
end
def response(handler)
if handler.base64_encodeable?
{ isBase64Encoded: true, body: handler.body64 }
else
super
end.tap do |r|
if cookies = handler.set_cookies
if payload_version_one?
r[:multiValueHeaders] ||= {}
r[:multiValueHeaders]['Set-Cookie'] = cookies
else
r[:cookies] = cookies
end
end
end
end
private
def env_base
{ ::Rack::REQUEST_METHOD => request_method,
::Rack::SCRIPT_NAME => '',
::Rack::PATH_INFO => path_info,
::Rack::QUERY_STRING => query_string,
::Rack::SERVER_NAME => server_name,
::Rack::SERVER_PORT => server_port,
::Rack::SERVER_PROTOCOL => server_protocol,
::Rack::RACK_VERSION => ::Rack::VERSION,
::Rack::RACK_URL_SCHEME => 'https',
::Rack::RACK_INPUT => StringIO.new(body || ''),
::Rack::RACK_ERRORS => $stderr,
LAMBDA_EVENT => event,
LAMBDA_CONTEXT => context
}.tap do |env|
ct = content_type
cl = content_length
env['CONTENT_TYPE'] = ct if ct
env['CONTENT_LENGTH'] = cl if cl
end
end
def env_headers
super.tap do |hdrs|
if cookies.any?
hdrs[HTTP_COOKIE] = cookies.join('; ')
end
end
end
def request_method
event.dig('requestContext', 'http', 'method') || event['httpMethod']
end
def cookies
event['cookies'] || []
end
# Using custom domain names with v1.0 yields a good `path` parameter sans
# stage. However, v2.0 and others do not. So we are just going to remove stage
# no matter waht from other places for both.
#
def path_info
stage = event.dig('requestContext', 'stage')
spath = event.dig('requestContext', 'http', 'path') || event.dig('requestContext', 'path')
spath = event['rawPath'] if spath != event['rawPath'] && !payload_version_one?
spath.sub /\A\/#{stage}/, ''
end
def server_name
headers['x-forwarded-host'] ||
headers['X-Forwarded-Host'] ||
headers['host'] ||
headers['Host']
end
def server_port
headers['x-forwarded-port'] || headers['X-Forwarded-Port']
end
def server_protocol
event.dig('requestContext', 'http', 'protocol') ||
event.dig('requestContext', 'protocol') ||
'HTTP/1.1'
end
def payload_version_one?
event['version'] == '1.0'
end
end
end