File tree Expand file tree Collapse file tree 7 files changed +71
-5
lines changed Expand file tree Collapse file tree 7 files changed +71
-5
lines changed Original file line number Diff line number Diff line change 11
11
* [ #952 ] ( https://github.com/intridea/grape/pull/952 ) : Status method now raises error when called with invalid status code - [ @dabrorius ] ( https://github.com/dabrorius ) .
12
12
* [ #957 ] ( https://github.com/intridea/grape/pull/957 ) : Regexp validator now supports ` allow_blank ` , ` nil ` value behavior changed - [ @calfzhou ] ( https://giihub.com/calfzhou ) .
13
13
* [ #962 ] ( https://github.com/intridea/grape/pull/962 ) : The ` default ` attribute with ` false ` value is documented now - [ @ajvondrak ] ( https://github.com/ajvondrak ) .
14
+ * [ #] ( https://github.com/intridea/grape/pull/ ) : Added ` file ` method, explicitly setting a file-like response object - [ @dblock ] ( https://github.com/dblock ) .
14
15
15
16
#### Fixes
16
17
Original file line number Diff line number Diff line change @@ -2009,7 +2009,7 @@ class API < Grape::API
2009
2009
end
2010
2010
```
2011
2011
2012
- You can also set the response body explicitly with `body`.
2012
+ You can set the response body explicitly with `body`.
2013
2013
2014
2014
```ruby
2015
2015
class API < Grape::API
@@ -2023,6 +2023,28 @@ end
2023
2023
2024
2024
Use `body false` to return `204 No Content` without any data or content-type.
2025
2025
2026
+ You can also set the response to a file-like object with `file`.
2027
+
2028
+ ```ruby
2029
+ class FileStreamer
2030
+ def initialize(file_path)
2031
+ @file_path = file_path
2032
+ end
2033
+
2034
+ def each(&blk)
2035
+ File.open(@file_path, ' rb' ) do |file|
2036
+ file.each(10, &blk)
2037
+ end
2038
+ end
2039
+ end
2040
+
2041
+ class API < Grape::API
2042
+ get ' / ' do
2043
+ file FileStreamer.new(' file.bin' )
2044
+ end
2045
+ end
2046
+ ```
2047
+
2026
2048
## Authentication
2027
2049
2028
2050
### Basic and Digest Auth
Original file line number Diff line number Diff line change @@ -169,6 +169,22 @@ def body(value = nil)
169
169
end
170
170
end
171
171
172
+ # Allows you to define the response as a file-like object.
173
+ #
174
+ # @example
175
+ # get '/file' do
176
+ # file FileStreamer.new(...)
177
+ # end
178
+ #
179
+ # GET /file # => "contents of file"
180
+ def file ( value = nil )
181
+ if value
182
+ @file = value
183
+ else
184
+ @file
185
+ end
186
+ end
187
+
172
188
# Allows you to make use of Grape Entities by setting
173
189
# the response body to the serializable hash of the
174
190
# entity provided in the `:with` option. This has the
Original file line number Diff line number Diff line change @@ -248,11 +248,13 @@ def run(env)
248
248
249
249
run_filters after_validations
250
250
251
- response_text = @block ? @block . call ( self ) : nil
251
+ response_object = @block ? @block . call ( self ) : nil
252
252
run_filters afters
253
253
cookies . write ( header )
254
254
255
- [ status , header , [ body || response_text ] ]
255
+ # The Body commonly is an Array of Strings, the application instance itself, or a File-like object.
256
+ response_object = file || [ body || response_object ]
257
+ [ status , header , response_object ]
256
258
end
257
259
258
260
def build_middleware
Original file line number Diff line number Diff line change @@ -29,9 +29,9 @@ def after
29
29
api_format = mime_types [ headers [ Grape ::Http ::Headers ::CONTENT_TYPE ] ] || env [ 'api.format' ]
30
30
formatter = Grape ::Formatter ::Base . formatter_for api_format , options
31
31
begin
32
- bodymap = bodies . collect do |body |
32
+ bodymap = bodies . respond_to? ( :collect ) ? bodies . collect do |body |
33
33
formatter . call body , env
34
- end
34
+ end : bodies
35
35
rescue Grape ::Exceptions ::InvalidFormatter => e
36
36
throw :error , status : 500 , message : e . message
37
37
end
Original file line number Diff line number Diff line change @@ -927,4 +927,18 @@ def memoized
927
927
expect ( last_response . status ) . to eq ( 406 )
928
928
end
929
929
end
930
+
931
+ context 'binary' do
932
+ before do
933
+ subject . get do
934
+ file FileStreamer . new ( __FILE__ )
935
+ end
936
+ end
937
+
938
+ it 'suports stream objects in response' do
939
+ get '/'
940
+ expect ( last_response . status ) . to eq 200
941
+ expect ( last_response . body ) . to eq File . read ( __FILE__ )
942
+ end
943
+ end
930
944
end
Original file line number Diff line number Diff line change
1
+ class FileStreamer
2
+ def initialize ( file_path )
3
+ @file_path = file_path
4
+ end
5
+
6
+ def each ( &blk )
7
+ File . open ( @file_path , 'rb' ) do |file |
8
+ file . each ( 10 , &blk )
9
+ end
10
+ end
11
+ end
You can’t perform that action at this time.
0 commit comments