Skip to content

Commit b8bfd9a

Browse files
committed
un-deprecate stream-like objects
- this splits the "stream" and "file" inside_route methods - file is purely for specifying a file (and utilizing sendfile when it can) - stream is purely for stream-like objects.. This allows you to have streaming responses of generated data
1 parent f50576a commit b8bfd9a

File tree

8 files changed

+41
-32
lines changed

8 files changed

+41
-32
lines changed

lib/grape.rb

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -164,9 +164,9 @@ module Presenters
164164
autoload :Presenter
165165
end
166166

167-
module ServeFile
167+
module ServeStream
168168
extend ActiveSupport::Autoload
169-
autoload :FileResponse
169+
autoload :StreamResponse
170170
autoload :FileBody
171171
autoload :SendfileResponse
172172
end

lib/grape/dsl/inside_route.rb

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -189,13 +189,13 @@ def body(value = nil)
189189
# GET /file # => "contents of file"
190190
def file(value = nil)
191191
if value.is_a?(String)
192-
file_body = Grape::ServeFile::FileBody.new(value)
193-
@file = Grape::ServeFile::FileResponse.new(file_body)
192+
file_body = Grape::ServeStream::FileBody.new(value)
193+
@stream = Grape::ServeStream::StreamResponse.new(file_body)
194194
elsif !value.is_a?(NilClass)
195195
warn '[DEPRECATION] Argument as FileStreamer-like object is deprecated. Use path to file instead.'
196-
@file = Grape::ServeFile::FileResponse.new(value)
196+
@stream = Grape::ServeStream::StreamResponse.new(value)
197197
else
198-
@file
198+
@stream
199199
end
200200
end
201201

@@ -218,7 +218,16 @@ def stream(value = nil)
218218
header 'Content-Length', nil
219219
header 'Transfer-Encoding', nil
220220
header 'Cache-Control', 'no-cache' # Skips ETag generation (reading the response up front)
221-
file(value)
221+
if value.is_a?(String)
222+
warn '[DEPRECATION] Use `file file_path` to stream a file instead.'
223+
file(value)
224+
elsif value.respond_to?(:each)
225+
@stream = Grape::ServeStream::StreamResponse.new(value)
226+
elsif !value.is_a?(NilClass)
227+
raise ArgumentError, 'Stream object must respond to :each.'
228+
else
229+
@stream
230+
end
222231
end
223232

224233
# Allows you to make use of Grape Entities by setting

lib/grape/middleware/formatter.rb

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -34,9 +34,9 @@ def after
3434
def build_formatted_response(status, headers, bodies)
3535
headers = ensure_content_type(headers)
3636

37-
if bodies.is_a?(Grape::ServeFile::FileResponse)
38-
Grape::ServeFile::SendfileResponse.new([], status, headers) do |resp|
39-
resp.body = bodies.file
37+
if bodies.is_a?(Grape::ServeStream::StreamResponse)
38+
Grape::ServeStream::SendfileResponse.new([], status, headers) do |resp|
39+
resp.body = bodies.stream
4040
end
4141
else
4242
# Allow content-type to be explicitly overwritten

lib/grape/serve_file/file_body.rb renamed to lib/grape/serve_stream/file_body.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
module Grape
2-
module ServeFile
2+
module ServeStream
33
CHUNK_SIZE = 16_384
44

55
# Class helps send file through API

lib/grape/serve_file/sendfile_response.rb renamed to lib/grape/serve_stream/sendfile_response.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
module Grape
2-
module ServeFile
2+
module ServeStream
33
# Response should respond to to_path method
44
# for using Rack::SendFile middleware
55
class SendfileResponse < Rack::Response

lib/grape/serve_file/file_response.rb renamed to lib/grape/serve_stream/stream_response.rb

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,20 @@
11
module Grape
2-
module ServeFile
3-
# A simple class used to identify responses which represent files and do not
2+
module ServeStream
3+
# A simple class used to identify responses which represent streams (or files) and do not
44
# need to be formatted or pre-read by Rack::Response
5-
class FileResponse
6-
attr_reader :file
5+
class StreamResponse
6+
attr_reader :stream
77

8-
# @param file [Object]
9-
def initialize(file)
10-
@file = file
8+
# @param stream [Object]
9+
def initialize(stream)
10+
@stream = stream
1111
end
1212

1313
# Equality provided mostly for tests.
1414
#
1515
# @return [Boolean]
1616
def ==(other)
17-
file == other.file
17+
stream == other.stream
1818
end
1919
end
2020
end

spec/grape/dsl/inside_route_spec.rb

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -185,15 +185,15 @@ def initialize
185185
let(:file_path) { '/some/file/path' }
186186

187187
let(:file_response) do
188-
file_body = Grape::ServeFile::FileBody.new(file_path)
189-
Grape::ServeFile::FileResponse.new(file_body)
188+
file_body = Grape::ServeStream::FileBody.new(file_path)
189+
Grape::ServeStream::StreamResponse.new(file_body)
190190
end
191191

192192
before do
193193
subject.file file_path
194194
end
195195

196-
it 'returns value wrapped in FileResponse' do
196+
it 'returns value wrapped in StreamResponse' do
197197
expect(subject.file).to eq file_response
198198
end
199199
end
@@ -202,14 +202,14 @@ def initialize
202202
let(:file_object) { Class.new }
203203

204204
let(:file_response) do
205-
Grape::ServeFile::FileResponse.new(file_object)
205+
Grape::ServeStream::StreamResponse.new(file_object)
206206
end
207207

208208
before do
209209
subject.file file_object
210210
end
211211

212-
it 'returns value wrapped in FileResponse' do
212+
it 'returns value wrapped in StreamResponse' do
213213
expect(subject.file).to eq file_response
214214
end
215215
end
@@ -222,7 +222,7 @@ def initialize
222222

223223
describe '#stream' do
224224
describe 'set' do
225-
let(:file_object) { Class.new }
225+
let(:file_object) { double('StreamerObject', each: nil) }
226226

227227
before do
228228
subject.header 'Cache-Control', 'cache'
@@ -231,12 +231,12 @@ def initialize
231231
subject.stream file_object
232232
end
233233

234-
it 'returns value wrapped in FileResponse' do
235-
expect(subject.stream).to eq Grape::ServeFile::FileResponse.new(file_object)
234+
it 'returns value wrapped in StreamResponse' do
235+
expect(subject.stream).to eq Grape::ServeStream::StreamResponse.new(file_object)
236236
end
237237

238-
it 'also sets result of file to value wrapped in FileResponse' do
239-
expect(subject.file).to eq Grape::ServeFile::FileResponse.new(file_object)
238+
it 'also sets result of file to value wrapped in StreamResponse' do
239+
expect(subject.file).to eq Grape::ServeStream::StreamResponse.new(file_object)
240240
end
241241

242242
it 'sets Cache-Control header to no-cache' do

spec/grape/middleware/formatter_spec.rb

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -287,9 +287,9 @@ def to_xml
287287
let(:app) { ->(_env) { [200, {}, @body] } }
288288

289289
it 'returns Grape::Uril::SendFileReponse' do
290-
@body = Grape::ServeFile::FileResponse.new('file')
290+
@body = Grape::ServeStream::StreamResponse.new('file')
291291
env = { 'PATH_INFO' => '/somewhere', 'HTTP_ACCEPT' => 'application/json' }
292-
expect(subject.call(env)).to be_a(Grape::ServeFile::SendfileResponse)
292+
expect(subject.call(env)).to be_a(Grape::ServeStream::SendfileResponse)
293293
end
294294
end
295295

0 commit comments

Comments
 (0)