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 1111* [ #952 ] ( https://github.com/intridea/grape/pull/952 ) : Status method now raises error when called with invalid status code - [ @dabrorius ] ( https://github.com/dabrorius ) .
1212* [ #957 ] ( https://github.com/intridea/grape/pull/957 ) : Regexp validator now supports ` allow_blank ` , ` nil ` value behavior changed - [ @calfzhou ] ( https://giihub.com/calfzhou ) .
1313* [ #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 ) .
1415
1516#### Fixes
1617
Original file line number Diff line number Diff line change @@ -2009,7 +2009,7 @@ class API < Grape::API
20092009end
20102010```
20112011
2012- You can also set the response body explicitly with `body`.
2012+ You can set the response body explicitly with `body`.
20132013
20142014```ruby
20152015class API < Grape::API
@@ -2023,6 +2023,28 @@ end
20232023
20242024Use `body false` to return `204 No Content` without any data or content-type.
20252025
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+
20262048## Authentication
20272049
20282050### Basic and Digest Auth
Original file line number Diff line number Diff line change @@ -169,6 +169,22 @@ def body(value = nil)
169169 end
170170 end
171171
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+
172188 # Allows you to make use of Grape Entities by setting
173189 # the response body to the serializable hash of the
174190 # 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)
248248
249249 run_filters after_validations
250250
251- response_text = @block ? @block . call ( self ) : nil
251+ response_object = @block ? @block . call ( self ) : nil
252252 run_filters afters
253253 cookies . write ( header )
254254
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 ]
256258 end
257259
258260 def build_middleware
Original file line number Diff line number Diff line change @@ -29,9 +29,9 @@ def after
2929 api_format = mime_types [ headers [ Grape ::Http ::Headers ::CONTENT_TYPE ] ] || env [ 'api.format' ]
3030 formatter = Grape ::Formatter ::Base . formatter_for api_format , options
3131 begin
32- bodymap = bodies . collect do |body |
32+ bodymap = bodies . respond_to? ( :collect ) ? bodies . collect do |body |
3333 formatter . call body , env
34- end
34+ end : bodies
3535 rescue Grape ::Exceptions ::InvalidFormatter => e
3636 throw :error , status : 500 , message : e . message
3737 end
Original file line number Diff line number Diff line change @@ -927,4 +927,18 @@ def memoized
927927 expect ( last_response . status ) . to eq ( 406 )
928928 end
929929 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
930944end
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