rack-shelf 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/Gemfile +5 -0
- data/Gemfile.lock +37 -0
- data/LICENSE.md +21 -0
- data/README.md +51 -0
- data/lib/rack/shelf.rb +52 -0
- data/lib/rack/shelf/api_gateway.rb +129 -0
- data/lib/rack/shelf/base64_response_adapter.rb +28 -0
- data/lib/rack/shelf/environment_builder.rb +158 -0
- data/lib/rack/shelf/response_adapter.rb +80 -0
- data/lib/rack/shelf/version.rb +7 -0
- metadata +81 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: b938a108e6359907bc7bec04a69ddae9e81207a8c5c7aded0d189359ef9a29ec
|
4
|
+
data.tar.gz: 454922f5c0b22591dafccf73850b29aaef98909e46b4ad749298f7481d26e437
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 63d4c509ea364e4ae94923f939eb051f107abee03145714d0a3cfad11512d18321d7b465763df0c27926f17db2480f1291574edd54a9f53c0faedb15334e1f49
|
7
|
+
data.tar.gz: 8e5aa94d9a2f057e25547b1652d4aba7043fa4684b3d034aa66cde63ca324c991a9ca19425943b176eb5b7ef882eb95128dfba9fb6caa07afa0c4943196595ca
|
data/Gemfile
ADDED
data/Gemfile.lock
ADDED
@@ -0,0 +1,37 @@
|
|
1
|
+
PATH
|
2
|
+
remote: .
|
3
|
+
specs:
|
4
|
+
rack-shelf (0.0.1)
|
5
|
+
rack
|
6
|
+
|
7
|
+
GEM
|
8
|
+
remote: https://rubygems.org/
|
9
|
+
specs:
|
10
|
+
ast (2.4.0)
|
11
|
+
jaro_winkler (1.5.4)
|
12
|
+
parallel (1.19.1)
|
13
|
+
parser (2.7.0.4)
|
14
|
+
ast (~> 2.4.0)
|
15
|
+
rack (2.1.1)
|
16
|
+
rainbow (3.0.0)
|
17
|
+
rexml (3.2.4)
|
18
|
+
rubocop (0.80.1)
|
19
|
+
jaro_winkler (~> 1.5.1)
|
20
|
+
parallel (~> 1.10)
|
21
|
+
parser (>= 2.7.0.1)
|
22
|
+
rainbow (>= 2.2.2, < 4.0)
|
23
|
+
rexml
|
24
|
+
ruby-progressbar (~> 1.7)
|
25
|
+
unicode-display_width (>= 1.4.0, < 1.7)
|
26
|
+
ruby-progressbar (1.10.1)
|
27
|
+
unicode-display_width (1.6.1)
|
28
|
+
|
29
|
+
PLATFORMS
|
30
|
+
ruby
|
31
|
+
|
32
|
+
DEPENDENCIES
|
33
|
+
rack-shelf!
|
34
|
+
rubocop (~> 0.80.1)
|
35
|
+
|
36
|
+
BUNDLED WITH
|
37
|
+
2.0.2
|
data/LICENSE.md
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
# MIT LICENSE
|
2
|
+
|
3
|
+
Copyright (c) 2020 Michael Miller <icy.arctic.fox@gmail.com>
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
7
|
+
in the Software without restriction, including without limitation the rights
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
10
|
+
furnished to do so, subject to the following conditions:
|
11
|
+
|
12
|
+
The above copyright notice and this permission notice shall be included in
|
13
|
+
all copies or substantial portions of the Software.
|
14
|
+
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
21
|
+
THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,51 @@
|
|
1
|
+
Rack Shelf
|
2
|
+
==========
|
3
|
+
|
4
|
+
Easily integrate a Rack application into AWS Lambda.
|
5
|
+
|
6
|
+
Provides adapters to convert AWS Lambda events to Rack environment requests
|
7
|
+
and Rack responses to AWS Lambda proxy integrations.
|
8
|
+
|
9
|
+
Shelf currently works with API Gateway.
|
10
|
+
|
11
|
+
Installation
|
12
|
+
------------
|
13
|
+
|
14
|
+
Add to your Gemfile:
|
15
|
+
|
16
|
+
```ruby
|
17
|
+
gem 'rack-shelf'
|
18
|
+
```
|
19
|
+
|
20
|
+
or gemspec:
|
21
|
+
|
22
|
+
```ruby
|
23
|
+
s.add_dependency 'rack-shelf'
|
24
|
+
```
|
25
|
+
|
26
|
+
Usage
|
27
|
+
-----
|
28
|
+
|
29
|
+
In your AWS Lambda handler file:
|
30
|
+
|
31
|
+
```ruby
|
32
|
+
require 'rack/shelf'
|
33
|
+
|
34
|
+
class App
|
35
|
+
def call
|
36
|
+
[200, {}, 'Hello world!']
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
def handler(event:, context:)
|
41
|
+
Rack::Shelf.api_gateway(App.new, event, context)
|
42
|
+
end
|
43
|
+
```
|
44
|
+
|
45
|
+
### Detailed Explanation
|
46
|
+
|
47
|
+
The `#api_gateway` method indicates the Lambda is expected to be invoked by API Gateway.
|
48
|
+
The method accepts three arguments: the Rack application, the Lambda event, and the Lambda context.
|
49
|
+
Shelf will translate the Lambda information to a Rack environment instance and invoke `#call` on the application.
|
50
|
+
It then takes the return value of `#call` (the three-element array) and translates it to a hash.
|
51
|
+
That hash contains the expected keys and values for an AWS Lambda proxy integration.
|
data/lib/rack/shelf.rb
ADDED
@@ -0,0 +1,52 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative 'shelf/api_gateway'
|
4
|
+
require_relative 'shelf/base64_response_adapter'
|
5
|
+
require_relative 'shelf/environment_builder'
|
6
|
+
require_relative 'shelf/response_adapter'
|
7
|
+
require_relative 'shelf/version'
|
8
|
+
|
9
|
+
module Rack
|
10
|
+
# Adapts AWS Lambda event sources to Rack environments.
|
11
|
+
module Shelf
|
12
|
+
extend self
|
13
|
+
|
14
|
+
# Runs a Rack application, translating the request and response.
|
15
|
+
# This method assumes the Lambda event came from API Gateway.
|
16
|
+
# @param app [#call] Rack application to call.
|
17
|
+
# @param event [Hash] Lambda event hash.
|
18
|
+
# @param context [Object] Lambda context object.
|
19
|
+
# @return [Hash] AWS Lambda response.
|
20
|
+
def api_gateway(app, event, context)
|
21
|
+
run(APIGateway, ResponseAdapter, app, event, context)
|
22
|
+
end
|
23
|
+
|
24
|
+
# Runs a Rack application, translating the request and response.
|
25
|
+
# This method assumes the Lambda event came from API Gateway.
|
26
|
+
# The response body is encoded as base-64.
|
27
|
+
# @param app [#call] Rack application to call.
|
28
|
+
# @param event [Hash] Lambda event hash.
|
29
|
+
# @param context [Object] Lambda context object.
|
30
|
+
# @return [Hash] AWS Lambda response.
|
31
|
+
def api_gateway_base64(app, event, context)
|
32
|
+
run(APIGateway, Base64ResponseAdapter, app, event, context)
|
33
|
+
end
|
34
|
+
|
35
|
+
private
|
36
|
+
|
37
|
+
# Runs the app and translates the request and response.
|
38
|
+
# @param request_adapter [#env] Translates the Lambda event.
|
39
|
+
# @param response_adapter [#convert, #error] Translates the Rack response.
|
40
|
+
# @param app [#call] Rack application to call.
|
41
|
+
# @param event [Hash] Lambda event hash.
|
42
|
+
# @param context [Object] Lambda context object.
|
43
|
+
# @return [Hash] AWS Lambda response.
|
44
|
+
def run(request_adapter, response_adapter, app, event, context)
|
45
|
+
env = request_adapter.env(event, context)
|
46
|
+
response = app.call(env)
|
47
|
+
response_adapter.convert(response)
|
48
|
+
rescue StandardError => e
|
49
|
+
response_adapter.error(e)
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
@@ -0,0 +1,129 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative 'environment_builder'
|
4
|
+
|
5
|
+
module Rack
|
6
|
+
module Shelf
|
7
|
+
# Converts AWS API Gateway events given to Lambda
|
8
|
+
# to Rack environment instances.
|
9
|
+
class APIGateway
|
10
|
+
# Produces a Rack compatible environment instance
|
11
|
+
# from a Lambda event and context.
|
12
|
+
# @param event [Hash] Event from the Lambda handler.
|
13
|
+
# @param context [Object] Context from the Lambda handler.
|
14
|
+
# @return [Hash] Rack environment.
|
15
|
+
def self.env(event, context)
|
16
|
+
new(event, context).build
|
17
|
+
end
|
18
|
+
|
19
|
+
# Creates an instance dedicated to building a Rack environment
|
20
|
+
# for a single event and context.
|
21
|
+
# @param event [Hash] Event from the Lambda handler.
|
22
|
+
# @param context [Object] Context from the Lambda handler.
|
23
|
+
def initialize(event, context)
|
24
|
+
@event = event
|
25
|
+
@context = context
|
26
|
+
@builder = EnvironmentBuilder.new
|
27
|
+
end
|
28
|
+
|
29
|
+
# Builds the rack environment.
|
30
|
+
# @return [Hash] Rack environment.
|
31
|
+
def build
|
32
|
+
build_common
|
33
|
+
build_headers
|
34
|
+
build_body
|
35
|
+
|
36
|
+
builder.build
|
37
|
+
end
|
38
|
+
|
39
|
+
private
|
40
|
+
|
41
|
+
# Rack environment builder instance.
|
42
|
+
# @return [EnvironmentBuilder]
|
43
|
+
attr_reader :builder
|
44
|
+
|
45
|
+
# Event from the Lambda handler.
|
46
|
+
# @return [Hash]
|
47
|
+
attr_reader :event
|
48
|
+
|
49
|
+
# Context from the Lambda handler.
|
50
|
+
# @return [Object]
|
51
|
+
attr_reader :context
|
52
|
+
|
53
|
+
# Retrieves the HTTP headers from the Lambda event.
|
54
|
+
# @return [Hash] HTTP headers.
|
55
|
+
def headers
|
56
|
+
event['headers'] || {}
|
57
|
+
end
|
58
|
+
|
59
|
+
# Retrieves the HTTP request method from the Lambda event.
|
60
|
+
# @return [String] HTTP request method.
|
61
|
+
def request_method
|
62
|
+
event.fetch('httpMethod')
|
63
|
+
end
|
64
|
+
|
65
|
+
# Retrieves the path information, or a default value.
|
66
|
+
# @return [String]
|
67
|
+
def path_info
|
68
|
+
event['path'] || '/'
|
69
|
+
end
|
70
|
+
|
71
|
+
# Retrieves the query parameters from the Lambda event.
|
72
|
+
# @return [Hash]
|
73
|
+
def query_params
|
74
|
+
event['queryStringParameters'] || {}
|
75
|
+
end
|
76
|
+
|
77
|
+
# Retrieves the server hostname, or a default value.
|
78
|
+
# @return [String]
|
79
|
+
def server_name
|
80
|
+
event['Host'] || 'localhost'
|
81
|
+
end
|
82
|
+
|
83
|
+
# Retrieves the server port, or a default value.
|
84
|
+
# @return [Integer]
|
85
|
+
def server_port
|
86
|
+
event['X-Forwarded-Port'] || 80
|
87
|
+
end
|
88
|
+
|
89
|
+
# Retrieves the URL scheme, or a default value.
|
90
|
+
# @return [String]
|
91
|
+
def url_scheme
|
92
|
+
headers.fetch('CloudFront-Forwarded-Proto') do
|
93
|
+
headers.fetch('X-Forwarded-Proto', 'http')
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
97
|
+
# Configures common Rack environment attributes.
|
98
|
+
# @return [void]
|
99
|
+
def build_common # rubocop:disable Metrics/AbcSize
|
100
|
+
builder.request_method(request_method)
|
101
|
+
builder.path_info(path_info)
|
102
|
+
builder.query_params(query_params)
|
103
|
+
builder.server_name(server_name)
|
104
|
+
builder.server_port(server_port)
|
105
|
+
builder.url_scheme(url_scheme)
|
106
|
+
end
|
107
|
+
|
108
|
+
# Configures the HTTP request headers.
|
109
|
+
# @return [void]
|
110
|
+
def build_headers
|
111
|
+
headers.each do |key, value|
|
112
|
+
builder.header(key, value)
|
113
|
+
end
|
114
|
+
end
|
115
|
+
|
116
|
+
# Configures the client request body portion.
|
117
|
+
# @return [void]
|
118
|
+
def build_body
|
119
|
+
return unless (body = event['body'])
|
120
|
+
|
121
|
+
if event['isBase64Encoded']
|
122
|
+
builder.base64_body(body)
|
123
|
+
else
|
124
|
+
builder.body(body)
|
125
|
+
end
|
126
|
+
end
|
127
|
+
end
|
128
|
+
end
|
129
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'base64'
|
4
|
+
require_relative 'response_adapter'
|
5
|
+
|
6
|
+
module Rack
|
7
|
+
module Shelf
|
8
|
+
# Transforms a standard Rack response array
|
9
|
+
# to a return value required by AWS Lambda.
|
10
|
+
# Encodes the response body as base-64.
|
11
|
+
# This is typically used for sending binary data (not text).
|
12
|
+
class Base64ResponseAdapter < ResponseAdapter
|
13
|
+
# Constructs the AWS Lambda response.
|
14
|
+
# @return [Hash]
|
15
|
+
def build
|
16
|
+
super.merge('isBase64Encoded' => true)
|
17
|
+
end
|
18
|
+
|
19
|
+
private
|
20
|
+
|
21
|
+
# Constructs the response body encoded in base-64.
|
22
|
+
# @return [String]
|
23
|
+
def body
|
24
|
+
Base64.encode64(super)
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,158 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'base64'
|
4
|
+
require 'rack'
|
5
|
+
require 'stringio'
|
6
|
+
|
7
|
+
module Rack
|
8
|
+
module Shelf
|
9
|
+
# Builds up a Rack env hash.
|
10
|
+
class EnvironmentBuilder
|
11
|
+
# Default values for the Rack environment.
|
12
|
+
DEFAULTS = {
|
13
|
+
'REQUEST_METHOD' => 'GET',
|
14
|
+
'SCRIPT_NAME' => '',
|
15
|
+
'PATH_INFO' => '/',
|
16
|
+
'QUERY_STRING' => '',
|
17
|
+
'SERVER_NAME' => 'localhost',
|
18
|
+
'SERVER_PORT' => '80',
|
19
|
+
'rack.version' => Rack::VERSION,
|
20
|
+
'rack.url_scheme' => 'http',
|
21
|
+
'rack.input' => StringIO.new,
|
22
|
+
'rack.errors' => $stderr,
|
23
|
+
'rack.multithread' => false,
|
24
|
+
'rack.multiprocess' => false,
|
25
|
+
'rack.run_once' => false,
|
26
|
+
'rack.hijack?' => false
|
27
|
+
}.freeze
|
28
|
+
|
29
|
+
# Creates the builder with reasonable defaults.
|
30
|
+
def initialize
|
31
|
+
@env = DEFAULTS.clone(freeze: false)
|
32
|
+
end
|
33
|
+
|
34
|
+
# Specifies the request method.
|
35
|
+
# @param method [String] Must be one of:
|
36
|
+
# +GET+, +POST+, +PUT+, +HEAD+, +DELETE+, +PATCH+, or +OPTIONS+.
|
37
|
+
# @return [void]
|
38
|
+
def request_method(method)
|
39
|
+
@env['REQUEST_METHOD'] = method
|
40
|
+
end
|
41
|
+
|
42
|
+
# Specifies the name (or mounting point) of the application.
|
43
|
+
# @param name [String] Script name.
|
44
|
+
# @return [void]
|
45
|
+
def script_name(name)
|
46
|
+
@env['SCRIPT_NAME'] = name
|
47
|
+
end
|
48
|
+
|
49
|
+
# Specifies the path info (path after the mounting point).
|
50
|
+
# @param path [String] Path info.
|
51
|
+
# @return [void]
|
52
|
+
def path_info(path)
|
53
|
+
@env['PATH_INFO'] = path
|
54
|
+
end
|
55
|
+
|
56
|
+
# Specifies the entire query string.
|
57
|
+
# @param string [String] Pre-encoded query string.
|
58
|
+
# @return [void]
|
59
|
+
def query_string(string)
|
60
|
+
@env['QUERY_STRING'] = string
|
61
|
+
end
|
62
|
+
|
63
|
+
# Specifies the query parameters as a hash.
|
64
|
+
# @param params [Hash] Query parameters.
|
65
|
+
# @return [void]
|
66
|
+
def query_params(params)
|
67
|
+
string = Rack::Utils.build_query(params)
|
68
|
+
query_string(string)
|
69
|
+
end
|
70
|
+
|
71
|
+
# Specifies the hostname of the server.
|
72
|
+
# @param name [String] Server name.
|
73
|
+
# @return [void]
|
74
|
+
def server_name(name)
|
75
|
+
@env['SERVER_NAME'] = name
|
76
|
+
end
|
77
|
+
|
78
|
+
# Specifies the port the server is listening on.
|
79
|
+
# @param port [#to_s] Port number.
|
80
|
+
# @return [void]
|
81
|
+
def server_port(port)
|
82
|
+
@env['SERVER_PORT'] = port.to_s
|
83
|
+
end
|
84
|
+
|
85
|
+
# Specifies the URL scheme for the request.
|
86
|
+
# @param scheme [String] Must be: +http+ or +https+.
|
87
|
+
# @return [void]
|
88
|
+
def url_scheme(scheme)
|
89
|
+
@env['rack.url_scheme'] = scheme
|
90
|
+
end
|
91
|
+
|
92
|
+
# Specifies the stream used for input (request body).
|
93
|
+
# @param io [IO] Input stream.
|
94
|
+
# @return [void]
|
95
|
+
def input_stream(io)
|
96
|
+
@env['rack.input'] = io
|
97
|
+
end
|
98
|
+
|
99
|
+
# Specifies the client request body.
|
100
|
+
# @param content [String] Request body.
|
101
|
+
# @return [void]
|
102
|
+
def body(content)
|
103
|
+
io = StringIO.new(content)
|
104
|
+
input_stream(io)
|
105
|
+
end
|
106
|
+
|
107
|
+
# Specifies the client request body encoded in base-64.
|
108
|
+
# @param content [String] Base-64 encoded request body.
|
109
|
+
# @return [void]
|
110
|
+
def base64_body(content)
|
111
|
+
decoded = Base64.decode64(content)
|
112
|
+
body(decoded)
|
113
|
+
end
|
114
|
+
|
115
|
+
# Specifies the stream used to display errors.
|
116
|
+
# @param io [IO] Error stream.
|
117
|
+
# @return [void]
|
118
|
+
def error_stream(io)
|
119
|
+
@env['rack.errors'] = io
|
120
|
+
end
|
121
|
+
|
122
|
+
# Defines an HTTP header in the request.
|
123
|
+
# @param header [String] HTTP header name.
|
124
|
+
# @param value [String] Value of the HTTP header.
|
125
|
+
# @return [void]
|
126
|
+
def header(header, value)
|
127
|
+
name = header.upcase.gsub('-', '_')
|
128
|
+
key = case name
|
129
|
+
when 'CONTENT_TYPE', 'CONTENT_LENGTH'
|
130
|
+
name
|
131
|
+
else
|
132
|
+
'HTTP_' + name
|
133
|
+
end
|
134
|
+
|
135
|
+
@env[key] = value
|
136
|
+
end
|
137
|
+
|
138
|
+
# Defines a custom application value.
|
139
|
+
# @param prefix [String] Prefix of the key.
|
140
|
+
# @param name [String] Name of the application key.
|
141
|
+
# @param value [Object] Value of the key.
|
142
|
+
# @return [void]
|
143
|
+
# @raise [ArgumentError] The prefix can't be +rack+.
|
144
|
+
def application(prefix, name, value)
|
145
|
+
raise ArgumentError, "Prefix can't be 'rack'" if prefix == 'rack'
|
146
|
+
|
147
|
+
key = [prefix, name].join('.')
|
148
|
+
@env[key] = value
|
149
|
+
end
|
150
|
+
|
151
|
+
# Creates the Rack env hash.
|
152
|
+
# @return [Hash]
|
153
|
+
def build
|
154
|
+
@env.clone
|
155
|
+
end
|
156
|
+
end
|
157
|
+
end
|
158
|
+
end
|
@@ -0,0 +1,80 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Rack
|
4
|
+
module Shelf
|
5
|
+
# Transforms a standard Rack response array
|
6
|
+
# to a return value required by AWS Lambda.
|
7
|
+
# @see https://docs.aws.amazon.com/apigateway/latest/developerguide/set-up-lambda-proxy-integrations.html#api-gateway-simple-proxy-for-lambda-output-format
|
8
|
+
class ResponseAdapter
|
9
|
+
# Converts a Rack response to one supported by AWS Lambda.
|
10
|
+
# @param response [Array] Three-element array.
|
11
|
+
# This is the standard response from a Rack application.
|
12
|
+
# Must have the elements: status code, headers, and body.
|
13
|
+
# @return [Hash] AWS Lambda response.
|
14
|
+
# @see https://www.rubydoc.info/github/rack/rack/file/SPEC#label-The+Response
|
15
|
+
def self.convert(response)
|
16
|
+
new(*response).build
|
17
|
+
end
|
18
|
+
|
19
|
+
# Generates a Lambda response for an error.
|
20
|
+
# @param exception [Exception, #to_s] Caught exception.
|
21
|
+
# @param status_code [Integer] HTTP response code.
|
22
|
+
# @return [Hash] AWS Lambda response.
|
23
|
+
def self.error(exception, status_code = 500)
|
24
|
+
new(status_code, {}, exception.to_s).build
|
25
|
+
end
|
26
|
+
|
27
|
+
# Creates an adapter dedicated to processing one response.
|
28
|
+
# @param status_code [#to_i] HTTP status code.
|
29
|
+
# @param headers [#each] HTTP headers.
|
30
|
+
# @param body [#each] Response body.
|
31
|
+
def initialize(status_code, headers, body)
|
32
|
+
@status_code = status_code
|
33
|
+
@headers = headers
|
34
|
+
@body = body
|
35
|
+
end
|
36
|
+
|
37
|
+
# Constructs the AWS Lambda response.
|
38
|
+
# @return [Hash]
|
39
|
+
def build
|
40
|
+
{
|
41
|
+
'status_code' => status_code,
|
42
|
+
'headers' => headers,
|
43
|
+
'body' => body,
|
44
|
+
'isBase64Encoded' => false
|
45
|
+
}
|
46
|
+
end
|
47
|
+
|
48
|
+
private
|
49
|
+
|
50
|
+
# The integer HTTP status code.
|
51
|
+
# @return [Integer]
|
52
|
+
def status_code
|
53
|
+
@status_code.to_i
|
54
|
+
end
|
55
|
+
|
56
|
+
# Constructs the HTTP headers.
|
57
|
+
# @return [Hash]
|
58
|
+
def headers
|
59
|
+
# Typically, the headers are already a hash.
|
60
|
+
# But, the Rack Spec only requires the object to expose `#each`.
|
61
|
+
{}.tap do |hash|
|
62
|
+
@headers.each do |key, value|
|
63
|
+
hash[key] = value
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
# Constructs the response body.
|
69
|
+
# @return [String]
|
70
|
+
def body
|
71
|
+
StringIO.new.tap do |io|
|
72
|
+
@body.each do |part|
|
73
|
+
io.write(part)
|
74
|
+
end
|
75
|
+
@body.close if @body.respond_to?(:close)
|
76
|
+
end.string
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
metadata
ADDED
@@ -0,0 +1,81 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: rack-shelf
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Michael Miller
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2020-03-22 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: rack
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ">="
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '0'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ">="
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '0'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: rubocop
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: 0.80.1
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: 0.80.1
|
41
|
+
description: Provides a translation for AWS Lambda events to Rack environments.
|
42
|
+
email:
|
43
|
+
- icy.arctic.fox@gmail.com
|
44
|
+
executables: []
|
45
|
+
extensions: []
|
46
|
+
extra_rdoc_files: []
|
47
|
+
files:
|
48
|
+
- Gemfile
|
49
|
+
- Gemfile.lock
|
50
|
+
- LICENSE.md
|
51
|
+
- README.md
|
52
|
+
- lib/rack/shelf.rb
|
53
|
+
- lib/rack/shelf/api_gateway.rb
|
54
|
+
- lib/rack/shelf/base64_response_adapter.rb
|
55
|
+
- lib/rack/shelf/environment_builder.rb
|
56
|
+
- lib/rack/shelf/response_adapter.rb
|
57
|
+
- lib/rack/shelf/version.rb
|
58
|
+
homepage: https://gitlab.com/arctic-fox/rack-shelf
|
59
|
+
licenses:
|
60
|
+
- MIT
|
61
|
+
metadata: {}
|
62
|
+
post_install_message:
|
63
|
+
rdoc_options: []
|
64
|
+
require_paths:
|
65
|
+
- lib
|
66
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
67
|
+
requirements:
|
68
|
+
- - ">="
|
69
|
+
- !ruby/object:Gem::Version
|
70
|
+
version: '0'
|
71
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - ">="
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '0'
|
76
|
+
requirements: []
|
77
|
+
rubygems_version: 3.0.3
|
78
|
+
signing_key:
|
79
|
+
specification_version: 4
|
80
|
+
summary: Adapts AWS Lambda event sources to Rack environments.
|
81
|
+
test_files: []
|