Skip to content

Commit

Permalink
Set Cache-Control only for streamed responses
Browse files Browse the repository at this point in the history
The pull request ruby-grape#1520 introduced a regression that always caused the
`Cache-Control` HTTP header to be set to `no-cache`, even if the
response wasn't a stream. To fix this, we only set HTTP headers if there
is an actual stream.

Closes ruby-grape#2087
  • Loading branch information
stanhu committed Jul 13, 2020
1 parent 84d68bd commit 28dde32
Show file tree
Hide file tree
Showing 4 changed files with 16 additions and 2 deletions.
2 changes: 1 addition & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

#### Fixes

* Your contribution here.
* [#2083](https://github.com/ruby-grape/grape/pull/2083): Set Cache-Control only for streamed responses - [@stanhu](https://github.com/stanhu).

### 1.4.0 (2020/07/10)

Expand Down
4 changes: 3 additions & 1 deletion lib/grape/dsl/inside_route.rb
Original file line number Diff line number Diff line change
Expand Up @@ -328,6 +328,8 @@ def sendfile(value = nil)
# * https://github.com/rack/rack/blob/99293fa13d86cd48021630fcc4bd5acc9de5bdc3/lib/rack/chunked.rb
# * https://github.com/rack/rack/blob/99293fa13d86cd48021630fcc4bd5acc9de5bdc3/lib/rack/etag.rb
def stream(value = nil)
return if value.nil? && @stream.nil?

header 'Content-Length', nil
header 'Transfer-Encoding', nil
header 'Cache-Control', 'no-cache' # Skips ETag generation (reading the response up front)
Expand All @@ -339,7 +341,7 @@ def stream(value = nil)
elsif !value.is_a?(NilClass)
raise ArgumentError, 'Stream object must respond to :each.'
else
instance_variable_defined?(:@stream) ? @stream : nil
@stream
end
end

Expand Down
5 changes: 5 additions & 0 deletions spec/grape/api_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -1149,6 +1149,11 @@ class DummyFormatClass
expect(last_response.headers['Content-Type']).to eq('text/plain')
end

it 'does not set Cache-Control' do
get '/foo'
expect(last_response.headers['Cache-Control']).to eq(nil)
end

it 'sets content type for xml' do
get '/foo.xml'
expect(last_response.headers['Content-Type']).to eq('application/xml')
Expand Down
7 changes: 7 additions & 0 deletions spec/grape/dsl/inside_route_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -351,6 +351,12 @@ def initialize
expect(subject.header['Cache-Control']).to eq 'no-cache'
end

it 'does not change Cache-Control header' do
subject.stream

expect(subject.header['Cache-Control']).to eq 'cache'
end

it 'sets Content-Length header to nil' do
subject.stream file_path

Expand Down Expand Up @@ -419,6 +425,7 @@ def initialize

it 'returns default' do
expect(subject.stream).to be nil
expect(subject.header['Cache-Control']).to eq nil
end
end

Expand Down

0 comments on commit 28dde32

Please sign in to comment.