Permalink
Browse files

Merged cookies from mrplum.

  • Loading branch information...
2 parents 583c4e2 + fc72e66 commit fca7d6d372ee08e737e3b579962c79ae0d59f6ac @dblock dblock committed Feb 14, 2012
Showing with 153 additions and 1 deletion.
  1. +3 −0 .gitignore
  2. +30 −0 README.markdown
  3. +1 −0 lib/grape.rb
  4. +41 −0 lib/grape/cookies.rb
  5. +15 −1 lib/grape/endpoint.rb
  6. +63 −0 spec/grape/endpoint_spec.rb
View
@@ -17,6 +17,9 @@ tmtags
## VIM
*.swp
+## RUBYMINE
+.idea
+
## PROJECT::GENERAL
coverage
doc
View
@@ -149,6 +149,36 @@ class API < Grape::API
end
````
+## Cookies
+
+You can set, get and delete your cookies very simply using `cookies` method:
+
+````ruby
+class API < Grape::API
+ get '/counter' do
+ cookies[:counter] ||= 0
+ cookies[:counter] += 1
+ { :counter => cookies[:counter] }
+ end
+
+ delete '/counter' do
+ { :result => cookies.delete(:counter) }
+ end
+end
+````
+
+To set more than value use hash-based syntax:
+
+````ruby
+cookies[:counter] = {
+ :value => 0,
+ :expires => Time.tomorrow,
+ :domain => '.example.com',
+ :path => '/'
+}
+cookies[:counter][:value] +=1
+````
+
## Raising Errors
You can raise errors explicitly.
View
@@ -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'
View
@@ -0,0 +1,41 @@
+module Grape
+ class Cookies
+
+ def initialize
+ @cookies = {}
+ @send_cookies = {}
+ end
+
+ def read(request)
+ request.cookies.each do |name, value|
+ @cookies[name.to_sym] = value
+ end
+ end
+
+ def write(header)
+ @cookies.select { |key, value|
+ @send_cookies[key.to_sym] == true
+ }.each { |name, value|
+ Rack::Utils.set_cookie_header!(
+ header, name, value.instance_of?(Hash) ? value : { :value => value })
+ }
+ end
+
+ def [](name)
+ @cookies[name]
+ end
+
+ def []=(name, value)
+ @cookies[name.to_sym] = value
+ @send_cookies[name.to_sym] = true
+ end
+
+ def each(&block)
+ @cookies.each(&block)
+ end
+
+ def delete(name)
+ self.[]=(name, { :value => 'deleted', :expires => Time.at(0) })
+ end
+ end
+end
View
@@ -157,6 +157,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.
#
@@ -231,10 +243,12 @@ def run(env)
@request = Rack::Request.new(@env)
self.extend helpers
+ cookies.read(@request)
run_filters befores
response_text = instance_eval &self.block
run_filters afters
-
+ cookies.write(header)
+
[status, header, [body || response_text]]
end
@@ -45,6 +45,69 @@ def app; subject end
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
subject.get('/hey') do

0 comments on commit fca7d6d

Please sign in to comment.