Skip to content

Commit

Permalink
Cookies management
Browse files Browse the repository at this point in the history
  • Loading branch information
Łukasz Śliwa committed Feb 12, 2012
1 parent f7fb74a commit 7a8bed7
Show file tree
Hide file tree
Showing 5 changed files with 137 additions and 0 deletions.
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,9 @@ tmtags
## VIM
*.swp

## RUBYMINE
.idea

## PROJECT::GENERAL
coverage
doc
Expand Down
1 change: 1 addition & 0 deletions lib/grape.rb
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ module Grape
autoload :Client, 'grape/client'
autoload :Route, 'grape/route'
autoload :Entity, 'grape/entity'
autoload :Cookies, 'grape/cookies'

module Middleware
autoload :Base, 'grape/middleware/base'
Expand Down
39 changes: 39 additions & 0 deletions lib/grape/cookies.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
module Grape
class Cookies

def initialize
@send = true
@cookies = {}
@send_cookies = {}
end

def without_send
@send = false
yield self if block_given?
@send = true
end

def [](name)
@cookies[name]
end

def []=(name, value)
@cookies[name.to_sym] = value
@send_cookies[name.to_sym] = true if @send
end

def each(opt = nil, &block)
if opt == :to_send
@cookies.select { |key, value|
@send_cookies[key.to_sym] == true
}.each(&block)
else
@cookies.each(&block)
end
end

def delete(name)
self.[]=(name, { :value => 'deleted', :expires => Time.at(0) })
end
end
end
31 changes: 31 additions & 0 deletions lib/grape/endpoint.rb
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,18 @@ def header(key = nil, val = nil)
end
end

# Set or get a cookie
#
# @example
# cookies[:mycookie] = 'mycookie val'
# cookies['mycookie-string'] = 'mycookie string val'
# cookies[:more] = { :value => '123', :expires => Time.at(0) }
# cookies.delete :more
#
def cookies
@cookies ||= Cookies.new
end

# Allows you to define the response body as something other than the
# return value.
#
Expand Down Expand Up @@ -126,10 +138,14 @@ def call(env)
@header = {}
@request = Rack::Request.new(@env)

get_cookies

run_filters self.class.options[:befores]
response_text = instance_eval &self.class.block
run_filters self.class.options[:afters]

set_cookies

[status, header, [body || response_text]]
end

Expand All @@ -140,5 +156,20 @@ def run_filters(filters)
instance_eval &filter
end
end

def get_cookies
cookies.without_send do |c|
@request.cookies.each do |name, value|
c[name] = value
end
end
end

def set_cookies
cookies.each(:to_send) do |name, value|
Rack::Utils.set_cookie_header!(
header, name, value.instance_of?(Hash) ? value : { :value => value })
end
end
end
end
63 changes: 63 additions & 0 deletions spec/grape/endpoint_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,69 @@ def app; subject end
last_response.headers['X-Awesome'].should == 'true'
end
end

describe '#cookies' do
it 'should be callable from within a block' do
subject.get('/get/cookies') do
cookies['my-awesome-cookie1'] = 'is cool'
cookies['my-awesome-cookie2'] = {
:value => 'is cool too',
:domain => 'my.example.com',
:path => '/',
:secure => true,
}
cookies[:cookie3] = 'symbol'
cookies['cookie4'] = 'secret code here'
end

get('/get/cookies')

last_response.headers['Set-Cookie'].tap { |set_cookies|
set_cookies.should =~ /my-awesome-cookie1=is\+cool\n/
set_cookies.should =~ /my-awesome-cookie2=is\+cool\+too;\ domain=my\.example\.com;\ path=\/;\ secure\n/
set_cookies.should =~ /cookie3=symbol\n/
set_cookies.should =~ /cookie4=secret\+code\+here/
}
end

it "should set browser cookies and should not set response cookies" do
subject.get('/username') do
cookies[:username]
end
get('/username', {}, 'HTTP_COOKIE' => 'username=mrplum; sandbox=true')

last_response.body.should == 'mrplum'
last_response.headers['Set-Cookie'].should_not =~ /username=mrplum/
last_response.headers['Set-Cookie'].should_not =~ /sandbox=true/
end

it "should set and update browser cookies" do
subject.get('/username') do
cookies[:sandbox] = true if cookies[:sandbox] == 'false'
cookies[:username] += "_test"
end
get('/username', {}, 'HTTP_COOKIE' => 'username=user; sandbox=false')
last_response.body.should == 'user_test'
last_response.headers['Set-Cookie'].should =~ /username=user_test/
last_response.headers['Set-Cookie'].should =~ /sandbox=true/
end

it "should delete cookie" do
subject.get('/test') do
sum = 0
cookies.each do |name, val|
sum += val.to_i
cookies.delete name
end
sum
end
get('/test', {}, 'HTTP_COOKIE' => 'delete_this_cookie=1; and_this=2')
last_response.body.should == '3'
last_response.headers['Set-Cookie'].should ==
"delete_this_cookie=deleted; expires=Thu, 01-Jan-1970 00:00:00 GMT\n" +
'and_this=deleted; expires=Thu, 01-Jan-1970 00:00:00 GMT'
end
end

describe '#params' do
it 'should be available to the caller' do
Expand Down

0 comments on commit 7a8bed7

Please sign in to comment.