Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Convenient cache and content type for response generation #944

Closed
wants to merge 4 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
1 change: 1 addition & 0 deletions lib/rack.rb
Expand Up @@ -38,6 +38,7 @@ def self.release
SERVER_ADDR = 'SERVER_ADDR'.freeze
SERVER_PORT = 'SERVER_PORT'.freeze
CACHE_CONTROL = 'Cache-Control'.freeze
EXPIRES = 'Expires'.freeze
CONTENT_LENGTH = 'Content-Length'.freeze
CONTENT_TYPE = 'Content-Type'.freeze
SET_COOKIE = 'Set-Cookie'.freeze
Expand Down
22 changes: 22 additions & 0 deletions lib/rack/response.rb
Expand Up @@ -211,6 +211,28 @@ def etag
def etag= v
set_header ETAG, v
end

def content_type
get_header CONTENT_TYPE
end

def content_type= v
set_header CONTENT_TYPE, v
end

# Specifies that the content shouldn't be cached. Overrides `cache!` if already called.
def do_not_cache!
set_header CACHE_CONTROL, "no-cache, must-revalidate"
set_header EXPIRES, Time.now.httpdate
end

# Specify that the content should be cached.
def cache!(duration = 3600, access = "public")
unless headers[CACHE_CONTROL] =~ /no-cache/
set_header CACHE_CONTROL, "#{access}, max-age=#{duration}"
set_header EXPIRES, (Time.now + duration).httpdate
end
end
end

include Helpers
Expand Down
33 changes: 33 additions & 0 deletions test/spec_response.rb
Expand Up @@ -20,6 +20,14 @@
assert_equal etag, response.to_a[2]['ETag']
end

it 'has a content-type method' do
response = Rack::Response.new
content_type = 'foo'
response.content_type = content_type
assert_equal content_type, response.content_type
assert_equal content_type, response.to_a[2]['Content-Type']
end

it "have sensible default values" do
response = Rack::Response.new
status, header, body = response.finish
Expand Down Expand Up @@ -389,6 +397,31 @@ def object_with_each.each
res.finish.last.wont_respond_to(:to_ary)
lambda { res.finish.last.to_ary }.must_raise NoMethodError
end

it "should specify not to cache content" do
response = Rack::Response.new

response.cache!(1000)
response.do_not_cache!

expect(response['Cache-Control']).must_be_equal "no-cache, must-revalidate"

expires_header = Time.parse(response['Expires'])
expect(expires_header).must_be :<=, Time.now
end

it "should specify to cache content" do
response = Rack::Response.new

duration = 120
expires = Time.now + 100 # At least this far into the future
response.cache!(duration)

expect(response['Cache-Control']).must_be_equal "public, max-age=120"

expires_header = Time.parse(response['Expires'])
expect(expires_header).must_be :>=, expires
end
end

describe Rack::Response, 'headers' do
Expand Down