charcoal 0.1
Sign up to get free protection for your applications and to get access to all the features.
- data/Appraisals +18 -0
- data/Gemfile +15 -0
- data/LICENSE +20 -0
- data/README.md +36 -0
- data/Rakefile +53 -0
- data/charcoal.gemspec +78 -0
- data/gemfiles/rails_2.3.gemfile +15 -0
- data/gemfiles/rails_2.3.gemfile.lock +45 -0
- data/gemfiles/rails_3.1.gemfile +17 -0
- data/gemfiles/rails_3.1.gemfile.lock +88 -0
- data/gemfiles/rails_3.2.gemfile +17 -0
- data/gemfiles/rails_3.2.gemfile.lock +86 -0
- data/lib/charcoal.rb +19 -0
- data/lib/charcoal/controller_filter.rb +42 -0
- data/lib/charcoal/cors.rb +39 -0
- data/lib/charcoal/cors_controller.rb +48 -0
- data/lib/charcoal/cors_helper.rb +3 -0
- data/lib/charcoal/jsonp.rb +46 -0
- data/lib/charcoal/version.rb +3 -0
- data/test/cors_controller_test.rb +54 -0
- data/test/cors_test.rb +70 -0
- data/test/filters_test.rb +128 -0
- data/test/helper.rb +54 -0
- data/test/jsonp_test.rb +105 -0
- metadata +170 -0
data/Appraisals
ADDED
@@ -0,0 +1,18 @@
|
|
1
|
+
appraise "rails-2.3" do
|
2
|
+
gem "activesupport", "~> 2.3.5"
|
3
|
+
gem "actionpack", "~> 2.3.5"
|
4
|
+
end
|
5
|
+
|
6
|
+
appraise "rails-3.1" do
|
7
|
+
gem "activesupport", "~> 3.1.0"
|
8
|
+
gem "actionpack", "~> 3.1.0"
|
9
|
+
gem "railties", "~> 3.1.0"
|
10
|
+
gem "tzinfo"
|
11
|
+
end
|
12
|
+
|
13
|
+
appraise "rails-3.2" do
|
14
|
+
gem "activesupport", "~> 3.2.0"
|
15
|
+
gem "actionpack", "~> 3.2.0"
|
16
|
+
gem "railties", "~> 3.2.0"
|
17
|
+
gem "tzinfo"
|
18
|
+
end
|
data/Gemfile
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
source "http://rubygems.org"
|
2
|
+
|
3
|
+
gem "rake"
|
4
|
+
|
5
|
+
gem "activesupport", ">= 2.3.5"
|
6
|
+
gem "actionpack", ">= 2.3.5"
|
7
|
+
|
8
|
+
gem "yard", "~> 0.7", :group => :development
|
9
|
+
gem "bundler", "~> 1.2.0", :group => :development
|
10
|
+
gem "jeweler", "~> 1.8.4", :group => :development
|
11
|
+
|
12
|
+
gem "appraisal", ">= 0.5.0", :group => :test
|
13
|
+
gem "shoulda", ">= 0", :group => :test
|
14
|
+
gem "shoulda-context", ">= 0", :group => :test
|
15
|
+
gem "mocha", :group => :test
|
data/LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright (c) 2012 Steven Davidovitz
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,36 @@
|
|
1
|
+
# charcoal
|
2
|
+
|
3
|
+
JSONP ("JSON with padding") and CORS (Cross-Origin Resource Sharing) filtration for Rails versions 2 and above.
|
4
|
+
|
5
|
+
## Usage
|
6
|
+
|
7
|
+
### JSONP
|
8
|
+
|
9
|
+
Include the module `Charcoal::JSONP` in the controller you'd like to allow JSONP.
|
10
|
+
You may then use `allow_jsonp` class method with the following options:
|
11
|
+
|
12
|
+
|
13
|
+
Requests that come in with a callback parameter (e.g. `http://test.com/users.json?callback=hello`)
|
14
|
+
will have the response body wrapped in that callback and the content type changed to `application/javascript`
|
15
|
+
|
16
|
+
### CORS
|
17
|
+
|
18
|
+
Include the module `Charcoal::CORS` in the controller you'd like to allow CORS.
|
19
|
+
Preflight controller...
|
20
|
+
|
21
|
+
|
22
|
+
## Contributing to charcoal
|
23
|
+
|
24
|
+
* Check out the latest master to make sure the feature hasn't been implemented or the bug hasn't been fixed yet.
|
25
|
+
* Check out the issue tracker to make sure someone already hasn't requested it and/or contributed it.
|
26
|
+
* Fork the project.
|
27
|
+
* Start a feature/bugfix branch.
|
28
|
+
* Commit and push until you are happy with your contribution.
|
29
|
+
* Make sure to add tests for it. This is important so I don't break it in a future version unintentionally.
|
30
|
+
* Please try not to mess with the Rakefile, version, or history. If you want to have your own version, or is otherwise necessary, that is fine, but please isolate to its own commit so I can cherry-pick around it.
|
31
|
+
|
32
|
+
## Copyright
|
33
|
+
|
34
|
+
Copyright (c) 2012 Steven Davidovitz. See LICENSE for
|
35
|
+
further details.
|
36
|
+
|
data/Rakefile
ADDED
@@ -0,0 +1,53 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
require 'rubygems'
|
4
|
+
require 'bundler'
|
5
|
+
|
6
|
+
begin
|
7
|
+
Bundler.setup(:default, :development, :test)
|
8
|
+
rescue Bundler::BundlerError => e
|
9
|
+
$stderr.puts e.message
|
10
|
+
$stderr.puts "Run `bundle install` to install missing gems"
|
11
|
+
exit e.status_code
|
12
|
+
end
|
13
|
+
|
14
|
+
lib = File.expand_path('../lib/', __FILE__)
|
15
|
+
$:.unshift lib unless $:.include?(lib)
|
16
|
+
|
17
|
+
require 'charcoal/version'
|
18
|
+
|
19
|
+
require 'rake'
|
20
|
+
require 'jeweler'
|
21
|
+
|
22
|
+
Jeweler::Tasks.new do |gem|
|
23
|
+
# gem is a Gem::Specification... see http://docs.rubygems.org/read/chapter/20 for more options
|
24
|
+
gem.name = "charcoal"
|
25
|
+
gem.version = Charcoal::VERSION
|
26
|
+
gem.homepage = "http://github.com/steved555/charcoal"
|
27
|
+
gem.license = "MIT"
|
28
|
+
gem.summary = %Q{Cross-Origin helper for Rails}
|
29
|
+
gem.description = %Q{Helps you support JSONP and CORS in your Rails app}
|
30
|
+
gem.email = "sdavidovitz@zendesk.com"
|
31
|
+
gem.authors = ["Steven Davidovitz"]
|
32
|
+
# dependencies defined in Gemfile
|
33
|
+
end
|
34
|
+
Jeweler::RubygemsDotOrgTasks.new
|
35
|
+
|
36
|
+
require 'appraisal'
|
37
|
+
|
38
|
+
require 'rake/testtask'
|
39
|
+
Rake::TestTask.new(:test) do |test|
|
40
|
+
test.libs << 'lib' << 'test'
|
41
|
+
test.pattern = 'test/**/*_test.rb'
|
42
|
+
test.verbose = true
|
43
|
+
end
|
44
|
+
|
45
|
+
desc 'Test the plugin under all supported Rails versions.'
|
46
|
+
task :all => ["appraisal:cleanup", "appraisal:install"] do
|
47
|
+
exec('rake appraisal test')
|
48
|
+
end
|
49
|
+
|
50
|
+
task :default => :test
|
51
|
+
|
52
|
+
require 'yard'
|
53
|
+
YARD::Rake::YardocTask.new
|
data/charcoal.gemspec
ADDED
@@ -0,0 +1,78 @@
|
|
1
|
+
# Generated by jeweler
|
2
|
+
# DO NOT EDIT THIS FILE DIRECTLY
|
3
|
+
# Instead, edit Jeweler::Tasks in Rakefile, and run 'rake gemspec'
|
4
|
+
# -*- encoding: utf-8 -*-
|
5
|
+
|
6
|
+
Gem::Specification.new do |s|
|
7
|
+
s.name = "charcoal"
|
8
|
+
s.version = "0.1"
|
9
|
+
|
10
|
+
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
|
+
s.authors = ["Steven Davidovitz"]
|
12
|
+
s.date = "2012-11-21"
|
13
|
+
s.description = "Helps you support JSONP and CORS in your Rails app"
|
14
|
+
s.email = "sdavidovitz@zendesk.com"
|
15
|
+
s.extra_rdoc_files = [
|
16
|
+
"LICENSE",
|
17
|
+
"README.md"
|
18
|
+
]
|
19
|
+
s.files = [
|
20
|
+
"Appraisals",
|
21
|
+
"Gemfile",
|
22
|
+
"LICENSE",
|
23
|
+
"README.md",
|
24
|
+
"Rakefile",
|
25
|
+
"charcoal.gemspec",
|
26
|
+
"gemfiles/rails_2.3.gemfile",
|
27
|
+
"gemfiles/rails_2.3.gemfile.lock",
|
28
|
+
"gemfiles/rails_3.1.gemfile",
|
29
|
+
"gemfiles/rails_3.1.gemfile.lock",
|
30
|
+
"gemfiles/rails_3.2.gemfile",
|
31
|
+
"gemfiles/rails_3.2.gemfile.lock",
|
32
|
+
"lib/charcoal.rb",
|
33
|
+
"lib/charcoal/controller_filter.rb",
|
34
|
+
"lib/charcoal/cors.rb",
|
35
|
+
"lib/charcoal/cors_controller.rb",
|
36
|
+
"lib/charcoal/cors_helper.rb",
|
37
|
+
"lib/charcoal/jsonp.rb",
|
38
|
+
"lib/charcoal/version.rb",
|
39
|
+
"test/cors_controller_test.rb",
|
40
|
+
"test/cors_test.rb",
|
41
|
+
"test/filters_test.rb",
|
42
|
+
"test/helper.rb",
|
43
|
+
"test/jsonp_test.rb"
|
44
|
+
]
|
45
|
+
s.homepage = "http://github.com/steved555/charcoal"
|
46
|
+
s.licenses = ["MIT"]
|
47
|
+
s.require_paths = ["lib"]
|
48
|
+
s.rubygems_version = "1.8.24"
|
49
|
+
s.summary = "Cross-Origin helper for Rails"
|
50
|
+
|
51
|
+
if s.respond_to? :specification_version then
|
52
|
+
s.specification_version = 3
|
53
|
+
|
54
|
+
if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
|
55
|
+
s.add_runtime_dependency(%q<rake>, [">= 0"])
|
56
|
+
s.add_runtime_dependency(%q<activesupport>, [">= 2.3.5"])
|
57
|
+
s.add_runtime_dependency(%q<actionpack>, [">= 2.3.5"])
|
58
|
+
s.add_development_dependency(%q<yard>, ["~> 0.7"])
|
59
|
+
s.add_development_dependency(%q<bundler>, ["~> 1.2.0"])
|
60
|
+
s.add_development_dependency(%q<jeweler>, ["~> 1.8.4"])
|
61
|
+
else
|
62
|
+
s.add_dependency(%q<rake>, [">= 0"])
|
63
|
+
s.add_dependency(%q<activesupport>, [">= 2.3.5"])
|
64
|
+
s.add_dependency(%q<actionpack>, [">= 2.3.5"])
|
65
|
+
s.add_dependency(%q<yard>, ["~> 0.7"])
|
66
|
+
s.add_dependency(%q<bundler>, ["~> 1.2.0"])
|
67
|
+
s.add_dependency(%q<jeweler>, ["~> 1.8.4"])
|
68
|
+
end
|
69
|
+
else
|
70
|
+
s.add_dependency(%q<rake>, [">= 0"])
|
71
|
+
s.add_dependency(%q<activesupport>, [">= 2.3.5"])
|
72
|
+
s.add_dependency(%q<actionpack>, [">= 2.3.5"])
|
73
|
+
s.add_dependency(%q<yard>, ["~> 0.7"])
|
74
|
+
s.add_dependency(%q<bundler>, ["~> 1.2.0"])
|
75
|
+
s.add_dependency(%q<jeweler>, ["~> 1.8.4"])
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
@@ -0,0 +1,15 @@
|
|
1
|
+
# This file was generated by Appraisal
|
2
|
+
|
3
|
+
source "http://rubygems.org"
|
4
|
+
|
5
|
+
gem "rake"
|
6
|
+
gem "yard", "~> 0.7", :group=>:development
|
7
|
+
gem "bundler", "~> 1.2.0", :group=>:development
|
8
|
+
gem "jeweler", "~> 1.8.4", :group=>:development
|
9
|
+
gem "appraisal", ">= 0.5.0", :group=>:test
|
10
|
+
gem "shoulda", ">= 0", :group=>:test
|
11
|
+
gem "shoulda-context", ">= 0", :group=>:test
|
12
|
+
gem "mocha", :group=>:test
|
13
|
+
gem "activesupport", "~> 2.3.5"
|
14
|
+
gem "actionpack", "~> 2.3.5"
|
15
|
+
|
@@ -0,0 +1,45 @@
|
|
1
|
+
GEM
|
2
|
+
remote: http://rubygems.org/
|
3
|
+
specs:
|
4
|
+
actionpack (2.3.14)
|
5
|
+
activesupport (= 2.3.14)
|
6
|
+
rack (~> 1.1.0)
|
7
|
+
activesupport (2.3.14)
|
8
|
+
appraisal (0.5.1)
|
9
|
+
bundler
|
10
|
+
rake
|
11
|
+
git (1.2.5)
|
12
|
+
jeweler (1.8.4)
|
13
|
+
bundler (~> 1.0)
|
14
|
+
git (>= 1.2.5)
|
15
|
+
rake
|
16
|
+
rdoc
|
17
|
+
json (1.7.5)
|
18
|
+
metaclass (0.0.1)
|
19
|
+
mocha (0.13.0)
|
20
|
+
metaclass (~> 0.0.1)
|
21
|
+
rack (1.1.3)
|
22
|
+
rake (10.0.2)
|
23
|
+
rdoc (3.12)
|
24
|
+
json (~> 1.4)
|
25
|
+
shoulda (3.0.1)
|
26
|
+
shoulda-context (~> 1.0.0)
|
27
|
+
shoulda-matchers (~> 1.0.0)
|
28
|
+
shoulda-context (1.0.0)
|
29
|
+
shoulda-matchers (1.0.0)
|
30
|
+
yard (0.8.3)
|
31
|
+
|
32
|
+
PLATFORMS
|
33
|
+
ruby
|
34
|
+
|
35
|
+
DEPENDENCIES
|
36
|
+
actionpack (~> 2.3.5)
|
37
|
+
activesupport (~> 2.3.5)
|
38
|
+
appraisal (>= 0.5.0)
|
39
|
+
bundler (~> 1.2.0)
|
40
|
+
jeweler (~> 1.8.4)
|
41
|
+
mocha
|
42
|
+
rake
|
43
|
+
shoulda
|
44
|
+
shoulda-context
|
45
|
+
yard (~> 0.7)
|
@@ -0,0 +1,17 @@
|
|
1
|
+
# This file was generated by Appraisal
|
2
|
+
|
3
|
+
source "http://rubygems.org"
|
4
|
+
|
5
|
+
gem "rake"
|
6
|
+
gem "yard", "~> 0.7", :group=>:development
|
7
|
+
gem "bundler", "~> 1.2.0", :group=>:development
|
8
|
+
gem "jeweler", "~> 1.8.4", :group=>:development
|
9
|
+
gem "appraisal", ">= 0.5.0", :group=>:test
|
10
|
+
gem "shoulda", ">= 0", :group=>:test
|
11
|
+
gem "shoulda-context", ">= 0", :group=>:test
|
12
|
+
gem "mocha", :group=>:test
|
13
|
+
gem "activesupport", "~> 3.1.0"
|
14
|
+
gem "actionpack", "~> 3.1.0"
|
15
|
+
gem "railties", "~> 3.1.0"
|
16
|
+
gem "tzinfo"
|
17
|
+
|
@@ -0,0 +1,88 @@
|
|
1
|
+
GEM
|
2
|
+
remote: http://rubygems.org/
|
3
|
+
specs:
|
4
|
+
actionpack (3.1.8)
|
5
|
+
activemodel (= 3.1.8)
|
6
|
+
activesupport (= 3.1.8)
|
7
|
+
builder (~> 3.0.0)
|
8
|
+
erubis (~> 2.7.0)
|
9
|
+
i18n (~> 0.6)
|
10
|
+
rack (~> 1.3.6)
|
11
|
+
rack-cache (~> 1.2)
|
12
|
+
rack-mount (~> 0.8.2)
|
13
|
+
rack-test (~> 0.6.1)
|
14
|
+
sprockets (~> 2.0.4)
|
15
|
+
activemodel (3.1.8)
|
16
|
+
activesupport (= 3.1.8)
|
17
|
+
builder (~> 3.0.0)
|
18
|
+
i18n (~> 0.6)
|
19
|
+
activesupport (3.1.8)
|
20
|
+
multi_json (>= 1.0, < 1.3)
|
21
|
+
appraisal (0.5.1)
|
22
|
+
bundler
|
23
|
+
rake
|
24
|
+
builder (3.0.4)
|
25
|
+
erubis (2.7.0)
|
26
|
+
git (1.2.5)
|
27
|
+
hike (1.2.1)
|
28
|
+
i18n (0.6.1)
|
29
|
+
jeweler (1.8.4)
|
30
|
+
bundler (~> 1.0)
|
31
|
+
git (>= 1.2.5)
|
32
|
+
rake
|
33
|
+
rdoc
|
34
|
+
json (1.7.5)
|
35
|
+
metaclass (0.0.1)
|
36
|
+
mocha (0.13.0)
|
37
|
+
metaclass (~> 0.0.1)
|
38
|
+
multi_json (1.2.0)
|
39
|
+
rack (1.3.6)
|
40
|
+
rack-cache (1.2)
|
41
|
+
rack (>= 0.4)
|
42
|
+
rack-mount (0.8.3)
|
43
|
+
rack (>= 1.0.0)
|
44
|
+
rack-ssl (1.3.2)
|
45
|
+
rack
|
46
|
+
rack-test (0.6.2)
|
47
|
+
rack (>= 1.0)
|
48
|
+
railties (3.1.8)
|
49
|
+
actionpack (= 3.1.8)
|
50
|
+
activesupport (= 3.1.8)
|
51
|
+
rack-ssl (~> 1.3.2)
|
52
|
+
rake (>= 0.8.7)
|
53
|
+
rdoc (~> 3.4)
|
54
|
+
thor (~> 0.14.6)
|
55
|
+
rake (10.0.2)
|
56
|
+
rdoc (3.12)
|
57
|
+
json (~> 1.4)
|
58
|
+
shoulda (3.1.1)
|
59
|
+
shoulda-context (~> 1.0)
|
60
|
+
shoulda-matchers (~> 1.2)
|
61
|
+
shoulda-context (1.0.0)
|
62
|
+
shoulda-matchers (1.3.0)
|
63
|
+
activesupport (>= 3.0.0)
|
64
|
+
sprockets (2.0.4)
|
65
|
+
hike (~> 1.2)
|
66
|
+
rack (~> 1.0)
|
67
|
+
tilt (~> 1.1, != 1.3.0)
|
68
|
+
thor (0.14.6)
|
69
|
+
tilt (1.3.3)
|
70
|
+
tzinfo (0.3.35)
|
71
|
+
yard (0.8.3)
|
72
|
+
|
73
|
+
PLATFORMS
|
74
|
+
ruby
|
75
|
+
|
76
|
+
DEPENDENCIES
|
77
|
+
actionpack (~> 3.1.0)
|
78
|
+
activesupport (~> 3.1.0)
|
79
|
+
appraisal (>= 0.5.0)
|
80
|
+
bundler (~> 1.2.0)
|
81
|
+
jeweler (~> 1.8.4)
|
82
|
+
mocha
|
83
|
+
railties (~> 3.1.0)
|
84
|
+
rake
|
85
|
+
shoulda
|
86
|
+
shoulda-context
|
87
|
+
tzinfo
|
88
|
+
yard (~> 0.7)
|
@@ -0,0 +1,17 @@
|
|
1
|
+
# This file was generated by Appraisal
|
2
|
+
|
3
|
+
source "http://rubygems.org"
|
4
|
+
|
5
|
+
gem "rake"
|
6
|
+
gem "yard", "~> 0.7", :group=>:development
|
7
|
+
gem "bundler", "~> 1.2.0", :group=>:development
|
8
|
+
gem "jeweler", "~> 1.8.4", :group=>:development
|
9
|
+
gem "appraisal", ">= 0.5.0", :group=>:test
|
10
|
+
gem "shoulda", ">= 0", :group=>:test
|
11
|
+
gem "shoulda-context", ">= 0", :group=>:test
|
12
|
+
gem "mocha", :group=>:test
|
13
|
+
gem "activesupport", "~> 3.2.0"
|
14
|
+
gem "actionpack", "~> 3.2.0"
|
15
|
+
gem "railties", "~> 3.2.0"
|
16
|
+
gem "tzinfo"
|
17
|
+
|
@@ -0,0 +1,86 @@
|
|
1
|
+
GEM
|
2
|
+
remote: http://rubygems.org/
|
3
|
+
specs:
|
4
|
+
actionpack (3.2.8)
|
5
|
+
activemodel (= 3.2.8)
|
6
|
+
activesupport (= 3.2.8)
|
7
|
+
builder (~> 3.0.0)
|
8
|
+
erubis (~> 2.7.0)
|
9
|
+
journey (~> 1.0.4)
|
10
|
+
rack (~> 1.4.0)
|
11
|
+
rack-cache (~> 1.2)
|
12
|
+
rack-test (~> 0.6.1)
|
13
|
+
sprockets (~> 2.1.3)
|
14
|
+
activemodel (3.2.8)
|
15
|
+
activesupport (= 3.2.8)
|
16
|
+
builder (~> 3.0.0)
|
17
|
+
activesupport (3.2.8)
|
18
|
+
i18n (~> 0.6)
|
19
|
+
multi_json (~> 1.0)
|
20
|
+
appraisal (0.5.1)
|
21
|
+
bundler
|
22
|
+
rake
|
23
|
+
builder (3.0.4)
|
24
|
+
erubis (2.7.0)
|
25
|
+
git (1.2.5)
|
26
|
+
hike (1.2.1)
|
27
|
+
i18n (0.6.1)
|
28
|
+
jeweler (1.8.4)
|
29
|
+
bundler (~> 1.0)
|
30
|
+
git (>= 1.2.5)
|
31
|
+
rake
|
32
|
+
rdoc
|
33
|
+
journey (1.0.4)
|
34
|
+
json (1.7.5)
|
35
|
+
metaclass (0.0.1)
|
36
|
+
mocha (0.13.0)
|
37
|
+
metaclass (~> 0.0.1)
|
38
|
+
multi_json (1.3.7)
|
39
|
+
rack (1.4.1)
|
40
|
+
rack-cache (1.2)
|
41
|
+
rack (>= 0.4)
|
42
|
+
rack-ssl (1.3.2)
|
43
|
+
rack
|
44
|
+
rack-test (0.6.2)
|
45
|
+
rack (>= 1.0)
|
46
|
+
railties (3.2.8)
|
47
|
+
actionpack (= 3.2.8)
|
48
|
+
activesupport (= 3.2.8)
|
49
|
+
rack-ssl (~> 1.3.2)
|
50
|
+
rake (>= 0.8.7)
|
51
|
+
rdoc (~> 3.4)
|
52
|
+
thor (>= 0.14.6, < 2.0)
|
53
|
+
rake (10.0.2)
|
54
|
+
rdoc (3.12)
|
55
|
+
json (~> 1.4)
|
56
|
+
shoulda (3.1.1)
|
57
|
+
shoulda-context (~> 1.0)
|
58
|
+
shoulda-matchers (~> 1.2)
|
59
|
+
shoulda-context (1.0.0)
|
60
|
+
shoulda-matchers (1.3.0)
|
61
|
+
activesupport (>= 3.0.0)
|
62
|
+
sprockets (2.1.3)
|
63
|
+
hike (~> 1.2)
|
64
|
+
rack (~> 1.0)
|
65
|
+
tilt (~> 1.1, != 1.3.0)
|
66
|
+
thor (0.16.0)
|
67
|
+
tilt (1.3.3)
|
68
|
+
tzinfo (0.3.35)
|
69
|
+
yard (0.8.3)
|
70
|
+
|
71
|
+
PLATFORMS
|
72
|
+
ruby
|
73
|
+
|
74
|
+
DEPENDENCIES
|
75
|
+
actionpack (~> 3.2.0)
|
76
|
+
activesupport (~> 3.2.0)
|
77
|
+
appraisal (>= 0.5.0)
|
78
|
+
bundler (~> 1.2.0)
|
79
|
+
jeweler (~> 1.8.4)
|
80
|
+
mocha
|
81
|
+
railties (~> 3.2.0)
|
82
|
+
rake
|
83
|
+
shoulda
|
84
|
+
shoulda-context
|
85
|
+
tzinfo
|
86
|
+
yard (~> 0.7)
|
data/lib/charcoal.rb
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
module Charcoal
|
2
|
+
def self.configuration
|
3
|
+
@configuration ||= {
|
4
|
+
"credentials" => true,
|
5
|
+
"expose-headers" => %w{},
|
6
|
+
"allow-headers" => %w{X-Requested-With X-Prototype-Version},
|
7
|
+
"max-age" => 86400,
|
8
|
+
"allow-origin" => "*"
|
9
|
+
}
|
10
|
+
end
|
11
|
+
|
12
|
+
autoload :ControllerFilter, 'charcoal/controller_filter'
|
13
|
+
autoload :CORS, 'charcoal/cors'
|
14
|
+
autoload :JSONP, 'charcoal/jsonp'
|
15
|
+
|
16
|
+
autoload :CORSController, 'charcoal/cors_controller'
|
17
|
+
# autoload :ParameterWhitelist, "charcoal/parameter_whitelist"
|
18
|
+
end
|
19
|
+
|
@@ -0,0 +1,42 @@
|
|
1
|
+
module Charcoal
|
2
|
+
module ControllerFilter
|
3
|
+
def self.included(klass)
|
4
|
+
klass.extend(ClassMethods)
|
5
|
+
end
|
6
|
+
|
7
|
+
module ClassMethods
|
8
|
+
def allow(filter, &block)
|
9
|
+
define_method "allow_#{filter}" do |*args|
|
10
|
+
# If we don't need 1.8 compat then ->(options = {}) instead of *args and the next line
|
11
|
+
options = args.last.is_a?(Hash) ? args.pop : {}
|
12
|
+
options.assert_valid_keys(:only, :except, :if, :unless)
|
13
|
+
|
14
|
+
methods = args.map(&:to_sym)
|
15
|
+
methods = [:all] if methods.empty?
|
16
|
+
|
17
|
+
if options[:unless]
|
18
|
+
directive = lambda {|c| !parse_directive(options[:unless]).call(c)}
|
19
|
+
else
|
20
|
+
directive = parse_directive(options[:if] || true)
|
21
|
+
end
|
22
|
+
|
23
|
+
methods.each do |method|
|
24
|
+
instance_exec(method, directive, &block)
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
private
|
31
|
+
|
32
|
+
def parse_directive(directive)
|
33
|
+
return directive if directive.respond_to?(:call)
|
34
|
+
|
35
|
+
if directive.respond_to?(:to_sym) && method_defined?(directive.to_sym)
|
36
|
+
lambda {|c| c.send(directive.to_sym)}
|
37
|
+
else
|
38
|
+
lambda {|c| directive}
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
require 'charcoal/controller_filter'
|
2
|
+
|
3
|
+
module Charcoal
|
4
|
+
module CORS
|
5
|
+
def self.included(klass)
|
6
|
+
klass.extend(ClassMethods)
|
7
|
+
klass.after_filter :set_cors_headers, :if => :cors_allowed?
|
8
|
+
end
|
9
|
+
|
10
|
+
module ClassMethods
|
11
|
+
include ControllerFilter
|
12
|
+
|
13
|
+
def cors_allowed
|
14
|
+
@cors_allowed ||= Hash.new(lambda {|_| false})
|
15
|
+
end
|
16
|
+
|
17
|
+
allow :cors do |method, directive|
|
18
|
+
cors_allowed[method.to_sym] = directive
|
19
|
+
end
|
20
|
+
|
21
|
+
def cors_allowed?(instance, action)
|
22
|
+
cors_allowed[action.to_sym].try(:call, instance) ||
|
23
|
+
(action != :all && cors_allowed?(instance, :all))
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
def cors_allowed?
|
28
|
+
self.class.cors_allowed?(self, params[:action])
|
29
|
+
end
|
30
|
+
|
31
|
+
protected
|
32
|
+
|
33
|
+
def set_cors_headers
|
34
|
+
headers["Access-Control-Allow-Origin"] = Charcoal.configuration["allow-origin"].to_s
|
35
|
+
headers["Access-Control-Allow-Credentials"] = Charcoal.configuration["credentials"].to_s
|
36
|
+
headers["Access-Control-Expose-Headers"] = Charcoal.configuration["expose-headers"].join(",")
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
@@ -0,0 +1,48 @@
|
|
1
|
+
# This controller handles CORS preflight requests
|
2
|
+
# See https://developer.mozilla.org/En/HTTP_access_control for documentation
|
3
|
+
|
4
|
+
require 'action_controller'
|
5
|
+
require 'active_support/version'
|
6
|
+
|
7
|
+
require 'charcoal/cors_helper'
|
8
|
+
|
9
|
+
class Charcoal::CORSController < ActionController::Base
|
10
|
+
include Charcoal::CORS
|
11
|
+
|
12
|
+
# OPTIONS *
|
13
|
+
def preflight
|
14
|
+
allowed_methods = ActionController::Routing::HTTP_METHODS.select do |verb|
|
15
|
+
begin
|
16
|
+
route = if ActiveSupport::VERSION::MAJOR >= 3
|
17
|
+
Rails.application.routes.recognize_path(request.path, request.env.merge(:method => verb))
|
18
|
+
else
|
19
|
+
ActionController::Routing::Routes.routes.find {|r| r.recognize(request.path, request.env.merge(:method => verb))}
|
20
|
+
end
|
21
|
+
|
22
|
+
if route
|
23
|
+
route = route.requirements if ActiveSupport::VERSION::MAJOR < 3
|
24
|
+
|
25
|
+
controller = route[:controller].camelize
|
26
|
+
controller = "#{controller}Controller".constantize
|
27
|
+
|
28
|
+
action = route[:action] || params[:path].last.split(".").first
|
29
|
+
|
30
|
+
controller.respond_to?(:cors_allowed) && controller.cors_allowed?(self, action)
|
31
|
+
else
|
32
|
+
false
|
33
|
+
end
|
34
|
+
rescue ActionController::RoutingError
|
35
|
+
false
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
if allowed_methods.any?
|
40
|
+
set_cors_headers
|
41
|
+
headers["Access-Control-Allow-Methods"] = allowed_methods.join(",").upcase
|
42
|
+
headers["Access-Control-Max-Age"] = Charcoal.configuration["max-age"].to_s
|
43
|
+
headers['Access-Control-Allow-Headers'] = Charcoal.configuration["allow-headers"].join(",")
|
44
|
+
end
|
45
|
+
|
46
|
+
head :ok, :content_type => "text/plain"
|
47
|
+
end
|
48
|
+
end
|
@@ -0,0 +1,46 @@
|
|
1
|
+
require 'charcoal/controller_filter'
|
2
|
+
|
3
|
+
module Charcoal
|
4
|
+
module JSONP
|
5
|
+
def self.included(klass)
|
6
|
+
klass.extend(ClassMethods)
|
7
|
+
klass.prepend_around_filter :add_jsonp_callback
|
8
|
+
end
|
9
|
+
|
10
|
+
module ClassMethods
|
11
|
+
include ControllerFilter
|
12
|
+
|
13
|
+
def jsonp_allowed
|
14
|
+
@jsonp_allowed ||= Hash.new(lambda {|_| false})
|
15
|
+
end
|
16
|
+
|
17
|
+
allow :jsonp do |method, directive|
|
18
|
+
jsonp_allowed[method.to_sym] = directive
|
19
|
+
end
|
20
|
+
|
21
|
+
def jsonp_allowed?(instance, action)
|
22
|
+
jsonp_allowed[action.to_sym].try(:call, instance) ||
|
23
|
+
(action != :all && jsonp_allowed?(instance, :all))
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
def jsonp_allowed?
|
28
|
+
self.class.jsonp_allowed?(self, params[:action])
|
29
|
+
end
|
30
|
+
|
31
|
+
def jsonp_request?
|
32
|
+
params[:callback].present? && jsonp_allowed?
|
33
|
+
end
|
34
|
+
|
35
|
+
protected
|
36
|
+
|
37
|
+
def add_jsonp_callback
|
38
|
+
yield
|
39
|
+
|
40
|
+
if response.status.to_s.starts_with?('200') && jsonp_request?
|
41
|
+
response.body = "#{params[:callback]}(#{response.body})"
|
42
|
+
response.content_type = "application/javascript"
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
@@ -0,0 +1,54 @@
|
|
1
|
+
require File.expand_path("helper", File.dirname(__FILE__))
|
2
|
+
|
3
|
+
class TestController < ActionController::Base
|
4
|
+
include Charcoal::CORS
|
5
|
+
allow_cors :test
|
6
|
+
|
7
|
+
# GET, PUT
|
8
|
+
def test; end
|
9
|
+
end
|
10
|
+
|
11
|
+
class Charcoal::CORSControllerTest < ActionController::TestCase
|
12
|
+
context Charcoal::CORSController do
|
13
|
+
setup do
|
14
|
+
@request.env["HTTPS"] = "on"
|
15
|
+
end
|
16
|
+
|
17
|
+
context "unrecognized path to #preflight" do
|
18
|
+
setup do
|
19
|
+
@request.stubs(:path => "/my_unrecognized_path")
|
20
|
+
get :preflight
|
21
|
+
end
|
22
|
+
|
23
|
+
should "allow proper methods" do
|
24
|
+
assert_nil @response.headers["Access-Control-Allow-Methods"], @response.headers.inspect
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
context "OPTIONS to #preflight" do
|
29
|
+
context "with request method = OPTIONS" do
|
30
|
+
setup do
|
31
|
+
@request.stubs(:path => "/test")
|
32
|
+
get :preflight
|
33
|
+
end
|
34
|
+
|
35
|
+
should "allow proper methods" do
|
36
|
+
assert_equal "GET,PUT", @response.headers["Access-Control-Allow-Methods"], @response.headers.inspect
|
37
|
+
end
|
38
|
+
|
39
|
+
should "set Access-Control-Allow-Headers header" do
|
40
|
+
assert_equal Charcoal.configuration["allow-headers"].join(","), @response.headers["Access-Control-Allow-Headers"], @response.headers.inspect
|
41
|
+
end
|
42
|
+
|
43
|
+
should "set Access-Control-Max-Age header" do
|
44
|
+
assert_equal Charcoal.configuration["max-age"].to_s, @response.headers["Access-Control-Max-Age"], @response.headers.inspect
|
45
|
+
end
|
46
|
+
|
47
|
+
should "render text/plain response" do
|
48
|
+
assert_equal " ", @response.body
|
49
|
+
assert_match %r[text/plain], @response.headers["Content-Type"], @response.headers.inspect
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
data/test/cors_test.rb
ADDED
@@ -0,0 +1,70 @@
|
|
1
|
+
require File.expand_path('helper', File.dirname(__FILE__))
|
2
|
+
|
3
|
+
class TestCorsController < ActionController::Base
|
4
|
+
include Charcoal::CORS
|
5
|
+
|
6
|
+
allow_cors :test_action
|
7
|
+
|
8
|
+
def test_action
|
9
|
+
render :text => "noop"
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
class TestCorsControllerTest < ActionController::TestCase
|
14
|
+
context TestCorsController do
|
15
|
+
context "allowing cors" do
|
16
|
+
subject { TestCorsController.new }
|
17
|
+
|
18
|
+
setup do
|
19
|
+
subject.params = { :action => "test_action" }
|
20
|
+
end
|
21
|
+
|
22
|
+
should "allow cors" do
|
23
|
+
assert subject.cors_allowed?
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
context "cors callback" do
|
28
|
+
{
|
29
|
+
"Access-Control-Allow-Origin" => "allow-origin",
|
30
|
+
"Access-Control-Allow-Credentials" => "credentials",
|
31
|
+
}.each do |header, key|
|
32
|
+
context "CORS header -> #{header}" do
|
33
|
+
setup do
|
34
|
+
@original, Charcoal.configuration[key] = Charcoal.configuration[key], "test"
|
35
|
+
|
36
|
+
get :test_action
|
37
|
+
end
|
38
|
+
|
39
|
+
teardown do
|
40
|
+
Charcoal.configuration[key] = @original
|
41
|
+
end
|
42
|
+
|
43
|
+
should "be the same as the configuration" do
|
44
|
+
assert_equal "test", @response.headers[header], @response.headers.inspect
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
context "without any other request method" do
|
50
|
+
setup do
|
51
|
+
@original, Charcoal.configuration["expose-headers"] = Charcoal.configuration["expose-headers"], %w{test 123}
|
52
|
+
|
53
|
+
get :test_action
|
54
|
+
end
|
55
|
+
|
56
|
+
teardown do
|
57
|
+
Charcoal.configuration["expose-headers"] = @original
|
58
|
+
end
|
59
|
+
|
60
|
+
should "render action" do
|
61
|
+
assert_equal "noop", @response.body
|
62
|
+
end
|
63
|
+
|
64
|
+
should "set Access-Control-Expose-Headers" do
|
65
|
+
assert_equal "test,123", @response.headers["Access-Control-Expose-Headers"], @response.headers.inspect
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
@@ -0,0 +1,128 @@
|
|
1
|
+
require File.expand_path('helper', File.dirname(__FILE__))
|
2
|
+
|
3
|
+
class FiltersControllerTester < ActionController::Base
|
4
|
+
class << self
|
5
|
+
include Charcoal::ControllerFilter
|
6
|
+
|
7
|
+
allow :filtering do |method, directive|
|
8
|
+
filtering_allowed[method] = directive
|
9
|
+
end
|
10
|
+
|
11
|
+
def filtering_allowed
|
12
|
+
@filtering_allowed ||= Hash.new(lambda {|_| false })
|
13
|
+
end
|
14
|
+
|
15
|
+
def filtering_allowed?(instance, action)
|
16
|
+
filtering_allowed[action.to_sym].try(:call, instance) ||
|
17
|
+
(action != :all && filtering_allowed?(instance, :all))
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
def filtering_allowed?
|
22
|
+
self.class.filtering_allowed?(self, params[:action])
|
23
|
+
end
|
24
|
+
|
25
|
+
def test_action1; true; end
|
26
|
+
def test_action2; false; end
|
27
|
+
end
|
28
|
+
|
29
|
+
class FiltersTest < ActiveSupport::TestCase
|
30
|
+
context Charcoal::ControllerFilter do
|
31
|
+
subject { FiltersControllerTester.new }
|
32
|
+
setup do
|
33
|
+
subject.params = {}
|
34
|
+
end
|
35
|
+
|
36
|
+
context "controller action filtering" do
|
37
|
+
teardown do
|
38
|
+
FiltersControllerTester.filtering_allowed.clear
|
39
|
+
end
|
40
|
+
|
41
|
+
context "if" do
|
42
|
+
context "with a lambda" do
|
43
|
+
setup { FiltersControllerTester.allow_filtering :test_action1, :if => lambda {|c| c.test_action1 } }
|
44
|
+
|
45
|
+
should "should allow filtering for test_action1" do
|
46
|
+
subject.params.replace(:action => :test_action1)
|
47
|
+
assert subject.filtering_allowed?
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
context "with a method" do
|
52
|
+
setup { FiltersControllerTester.allow_filtering :test_action1, :if => :test_action1 }
|
53
|
+
|
54
|
+
should "should allow filtering for test_action1" do
|
55
|
+
subject.params.replace(:action => :test_action1)
|
56
|
+
assert subject.filtering_allowed?
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
context "with a true/false" do
|
61
|
+
setup { FiltersControllerTester.allow_filtering :test_action1, :if => true }
|
62
|
+
|
63
|
+
should "should allow filtering for test_action1" do
|
64
|
+
subject.params.replace(:action => :test_action1)
|
65
|
+
assert subject.filtering_allowed?
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
context "unless" do
|
71
|
+
context "with a lambda" do
|
72
|
+
setup { FiltersControllerTester.allow_filtering :test_action1, :unless => lambda {|c| c.test_action2 } }
|
73
|
+
|
74
|
+
should "should allow filtering for test_action1" do
|
75
|
+
subject.params.replace(:action => :test_action1)
|
76
|
+
assert subject.filtering_allowed?
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
context "with a method" do
|
81
|
+
setup { FiltersControllerTester.allow_filtering :test_action1, :unless => :test_action2 }
|
82
|
+
|
83
|
+
should "should allow filtering for test_action1" do
|
84
|
+
subject.params.replace(:action => :test_action1)
|
85
|
+
assert subject.filtering_allowed?
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
89
|
+
context "with a true/false" do
|
90
|
+
setup { FiltersControllerTester.allow_filtering :test_action1, :unless => false }
|
91
|
+
|
92
|
+
should "should allow filtering for test_action1" do
|
93
|
+
subject.params.replace(:action => :test_action1)
|
94
|
+
assert subject.filtering_allowed?
|
95
|
+
end
|
96
|
+
end
|
97
|
+
end
|
98
|
+
|
99
|
+
context "only" do
|
100
|
+
setup { FiltersControllerTester.allow_filtering :test_action1 }
|
101
|
+
|
102
|
+
should "should allow filtering for test_action1" do
|
103
|
+
subject.params.replace(:action => :test_action1)
|
104
|
+
assert subject.filtering_allowed?
|
105
|
+
end
|
106
|
+
|
107
|
+
should "should not allow filtering for test_action2" do
|
108
|
+
subject.params.replace(:action => :test_action2)
|
109
|
+
assert !subject.filtering_allowed?
|
110
|
+
end
|
111
|
+
end
|
112
|
+
|
113
|
+
context "none" do
|
114
|
+
setup { FiltersControllerTester.allow_filtering }
|
115
|
+
|
116
|
+
should "should allow filtering for test_action1" do
|
117
|
+
subject.params.replace(:action => :test_action1)
|
118
|
+
assert subject.filtering_allowed?
|
119
|
+
end
|
120
|
+
|
121
|
+
should "should allow filtering for test_action2" do
|
122
|
+
subject.params.replace(:action => :test_action1)
|
123
|
+
assert subject.filtering_allowed?
|
124
|
+
end
|
125
|
+
end
|
126
|
+
end
|
127
|
+
end
|
128
|
+
end
|
data/test/helper.rb
ADDED
@@ -0,0 +1,54 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'bundler'
|
3
|
+
|
4
|
+
ENV["RAILS_ENV"] = "test"
|
5
|
+
|
6
|
+
begin
|
7
|
+
Bundler.setup(:default, :development, :test)
|
8
|
+
rescue Bundler::BundlerError => e
|
9
|
+
$stderr.puts e.message
|
10
|
+
$stderr.puts "Run `bundle install` to install missing gems"
|
11
|
+
exit e.status_code
|
12
|
+
end
|
13
|
+
|
14
|
+
require 'active_support/version'
|
15
|
+
|
16
|
+
if ActiveSupport::VERSION::MAJOR >= 3
|
17
|
+
require "action_controller/railtie"
|
18
|
+
require "rails/test_unit/railtie"
|
19
|
+
|
20
|
+
class TestApp < Rails::Application
|
21
|
+
config.active_support.deprecation = :stderr
|
22
|
+
config.logger = Logger.new(RUBY_PLATFORM =~ /(mingw|bccwin|wince|mswin32)/i ? 'NUL:' : '/dev/null')
|
23
|
+
end
|
24
|
+
|
25
|
+
TestApp.initialize!
|
26
|
+
|
27
|
+
TestApp.routes.draw do
|
28
|
+
match '/test' => "test#test", :via => [:get, :put]
|
29
|
+
match ':controller/:action'
|
30
|
+
end
|
31
|
+
|
32
|
+
class ActionController::TestCase
|
33
|
+
def setup
|
34
|
+
@routes = TestApp.routes
|
35
|
+
end
|
36
|
+
end
|
37
|
+
else
|
38
|
+
require "action_controller"
|
39
|
+
require "active_support"
|
40
|
+
|
41
|
+
MissingSourceFile::REGEXPS.push([/^cannot load such file -- (.+)$/i, 1])
|
42
|
+
|
43
|
+
ActionController::Routing::Routes.draw do |map|
|
44
|
+
map.connect '/test', :controller => :test, :action => :test, :conditions => { :method => [:get, :put] }
|
45
|
+
map.connect ':controller/:action'
|
46
|
+
end
|
47
|
+
|
48
|
+
ActionDispatch = ActionController
|
49
|
+
end
|
50
|
+
|
51
|
+
require 'test/unit'
|
52
|
+
require 'shoulda'
|
53
|
+
|
54
|
+
require 'charcoal'
|
data/test/jsonp_test.rb
ADDED
@@ -0,0 +1,105 @@
|
|
1
|
+
require File.expand_path('helper', File.dirname(__FILE__))
|
2
|
+
|
3
|
+
class JSONPControllerTester < ActionController::Base
|
4
|
+
include Charcoal::JSONP
|
5
|
+
|
6
|
+
caches_action :test
|
7
|
+
allow_jsonp :test
|
8
|
+
|
9
|
+
def test
|
10
|
+
render :json => { :key => :value }
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
class JSONPTest < ActionController::TestCase
|
15
|
+
tests JSONPControllerTester
|
16
|
+
|
17
|
+
context JSONPControllerTester do
|
18
|
+
context "with caching" do
|
19
|
+
setup do
|
20
|
+
@caching, ActionController::Base.perform_caching = ActionController::Base.perform_caching, true
|
21
|
+
@cache_store, ActionController::Base.cache_store = ActionController::Base.cache_store, :memory_store
|
22
|
+
end
|
23
|
+
|
24
|
+
teardown do
|
25
|
+
ActionController::Base.perform_caching = @caching
|
26
|
+
ActionController::Base.cache_store = @cache_store
|
27
|
+
end
|
28
|
+
|
29
|
+
context "a GET to :test" do
|
30
|
+
setup do
|
31
|
+
get :test, :callback => "hello"
|
32
|
+
end
|
33
|
+
|
34
|
+
should "return a proper response" do
|
35
|
+
assert_match /hello\(.*\)/, @response.body
|
36
|
+
end
|
37
|
+
|
38
|
+
should "return a proper response type" do
|
39
|
+
assert_equal "application/javascript", @response.content_type
|
40
|
+
end
|
41
|
+
|
42
|
+
context "a second call" do
|
43
|
+
setup do
|
44
|
+
get :test, :callback => "hello"
|
45
|
+
end
|
46
|
+
|
47
|
+
should "properly cache the response" do
|
48
|
+
assert_match /hello\(.*\)/, @response.body
|
49
|
+
end
|
50
|
+
|
51
|
+
should "properly cache the response type" do
|
52
|
+
assert_equal "application/javascript", @response.content_type
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
context Charcoal::JSONP do
|
60
|
+
subject { JSONPControllerTester.new }
|
61
|
+
|
62
|
+
setup do
|
63
|
+
subject.params = {}
|
64
|
+
end
|
65
|
+
|
66
|
+
context "jsonp callback" do
|
67
|
+
setup do
|
68
|
+
@response = '{"test": 123}'
|
69
|
+
@content_type = "application/json"
|
70
|
+
|
71
|
+
subject.response = ActionDispatch::Response.new
|
72
|
+
subject.response.body = @response
|
73
|
+
subject.response.status = '200 OK'
|
74
|
+
subject.response.content_type = @content_type
|
75
|
+
end
|
76
|
+
|
77
|
+
context "with params" do
|
78
|
+
setup do
|
79
|
+
subject.params.replace(:callback => "callback", :action => "test")
|
80
|
+
subject.send(:add_jsonp_callback) {}
|
81
|
+
end
|
82
|
+
|
83
|
+
should "add jsonp if there is a callback" do
|
84
|
+
assert_equal "callback(#{@response})", subject.response.body
|
85
|
+
end
|
86
|
+
|
87
|
+
should "change content-type" do
|
88
|
+
assert_equal "application/javascript", subject.response.content_type
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
context "without params" do
|
93
|
+
setup { subject.send(:add_jsonp_callback) {} }
|
94
|
+
|
95
|
+
should "not add jsonp callback" do
|
96
|
+
assert_equal @response, subject.response.body
|
97
|
+
end
|
98
|
+
|
99
|
+
should "not change content-type" do
|
100
|
+
assert_equal @content_type, subject.response.content_type
|
101
|
+
end
|
102
|
+
end
|
103
|
+
end
|
104
|
+
end
|
105
|
+
end
|
metadata
ADDED
@@ -0,0 +1,170 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: charcoal
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: '0.1'
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Steven Davidovitz
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2012-11-21 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: rake
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
17
|
+
none: false
|
18
|
+
requirements:
|
19
|
+
- - ! '>='
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: '0'
|
22
|
+
type: :runtime
|
23
|
+
prerelease: false
|
24
|
+
version_requirements: !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
26
|
+
requirements:
|
27
|
+
- - ! '>='
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
version: '0'
|
30
|
+
- !ruby/object:Gem::Dependency
|
31
|
+
name: activesupport
|
32
|
+
requirement: !ruby/object:Gem::Requirement
|
33
|
+
none: false
|
34
|
+
requirements:
|
35
|
+
- - ! '>='
|
36
|
+
- !ruby/object:Gem::Version
|
37
|
+
version: 2.3.5
|
38
|
+
type: :runtime
|
39
|
+
prerelease: false
|
40
|
+
version_requirements: !ruby/object:Gem::Requirement
|
41
|
+
none: false
|
42
|
+
requirements:
|
43
|
+
- - ! '>='
|
44
|
+
- !ruby/object:Gem::Version
|
45
|
+
version: 2.3.5
|
46
|
+
- !ruby/object:Gem::Dependency
|
47
|
+
name: actionpack
|
48
|
+
requirement: !ruby/object:Gem::Requirement
|
49
|
+
none: false
|
50
|
+
requirements:
|
51
|
+
- - ! '>='
|
52
|
+
- !ruby/object:Gem::Version
|
53
|
+
version: 2.3.5
|
54
|
+
type: :runtime
|
55
|
+
prerelease: false
|
56
|
+
version_requirements: !ruby/object:Gem::Requirement
|
57
|
+
none: false
|
58
|
+
requirements:
|
59
|
+
- - ! '>='
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: 2.3.5
|
62
|
+
- !ruby/object:Gem::Dependency
|
63
|
+
name: yard
|
64
|
+
requirement: !ruby/object:Gem::Requirement
|
65
|
+
none: false
|
66
|
+
requirements:
|
67
|
+
- - ~>
|
68
|
+
- !ruby/object:Gem::Version
|
69
|
+
version: '0.7'
|
70
|
+
type: :development
|
71
|
+
prerelease: false
|
72
|
+
version_requirements: !ruby/object:Gem::Requirement
|
73
|
+
none: false
|
74
|
+
requirements:
|
75
|
+
- - ~>
|
76
|
+
- !ruby/object:Gem::Version
|
77
|
+
version: '0.7'
|
78
|
+
- !ruby/object:Gem::Dependency
|
79
|
+
name: bundler
|
80
|
+
requirement: !ruby/object:Gem::Requirement
|
81
|
+
none: false
|
82
|
+
requirements:
|
83
|
+
- - ~>
|
84
|
+
- !ruby/object:Gem::Version
|
85
|
+
version: 1.2.0
|
86
|
+
type: :development
|
87
|
+
prerelease: false
|
88
|
+
version_requirements: !ruby/object:Gem::Requirement
|
89
|
+
none: false
|
90
|
+
requirements:
|
91
|
+
- - ~>
|
92
|
+
- !ruby/object:Gem::Version
|
93
|
+
version: 1.2.0
|
94
|
+
- !ruby/object:Gem::Dependency
|
95
|
+
name: jeweler
|
96
|
+
requirement: !ruby/object:Gem::Requirement
|
97
|
+
none: false
|
98
|
+
requirements:
|
99
|
+
- - ~>
|
100
|
+
- !ruby/object:Gem::Version
|
101
|
+
version: 1.8.4
|
102
|
+
type: :development
|
103
|
+
prerelease: false
|
104
|
+
version_requirements: !ruby/object:Gem::Requirement
|
105
|
+
none: false
|
106
|
+
requirements:
|
107
|
+
- - ~>
|
108
|
+
- !ruby/object:Gem::Version
|
109
|
+
version: 1.8.4
|
110
|
+
description: Helps you support JSONP and CORS in your Rails app
|
111
|
+
email: sdavidovitz@zendesk.com
|
112
|
+
executables: []
|
113
|
+
extensions: []
|
114
|
+
extra_rdoc_files:
|
115
|
+
- LICENSE
|
116
|
+
- README.md
|
117
|
+
files:
|
118
|
+
- Appraisals
|
119
|
+
- Gemfile
|
120
|
+
- LICENSE
|
121
|
+
- README.md
|
122
|
+
- Rakefile
|
123
|
+
- charcoal.gemspec
|
124
|
+
- gemfiles/rails_2.3.gemfile
|
125
|
+
- gemfiles/rails_2.3.gemfile.lock
|
126
|
+
- gemfiles/rails_3.1.gemfile
|
127
|
+
- gemfiles/rails_3.1.gemfile.lock
|
128
|
+
- gemfiles/rails_3.2.gemfile
|
129
|
+
- gemfiles/rails_3.2.gemfile.lock
|
130
|
+
- lib/charcoal.rb
|
131
|
+
- lib/charcoal/controller_filter.rb
|
132
|
+
- lib/charcoal/cors.rb
|
133
|
+
- lib/charcoal/cors_controller.rb
|
134
|
+
- lib/charcoal/cors_helper.rb
|
135
|
+
- lib/charcoal/jsonp.rb
|
136
|
+
- lib/charcoal/version.rb
|
137
|
+
- test/cors_controller_test.rb
|
138
|
+
- test/cors_test.rb
|
139
|
+
- test/filters_test.rb
|
140
|
+
- test/helper.rb
|
141
|
+
- test/jsonp_test.rb
|
142
|
+
homepage: http://github.com/steved555/charcoal
|
143
|
+
licenses:
|
144
|
+
- MIT
|
145
|
+
post_install_message:
|
146
|
+
rdoc_options: []
|
147
|
+
require_paths:
|
148
|
+
- lib
|
149
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
150
|
+
none: false
|
151
|
+
requirements:
|
152
|
+
- - ! '>='
|
153
|
+
- !ruby/object:Gem::Version
|
154
|
+
version: '0'
|
155
|
+
segments:
|
156
|
+
- 0
|
157
|
+
hash: 1806808510332302197
|
158
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
159
|
+
none: false
|
160
|
+
requirements:
|
161
|
+
- - ! '>='
|
162
|
+
- !ruby/object:Gem::Version
|
163
|
+
version: '0'
|
164
|
+
requirements: []
|
165
|
+
rubyforge_project:
|
166
|
+
rubygems_version: 1.8.24
|
167
|
+
signing_key:
|
168
|
+
specification_version: 3
|
169
|
+
summary: Cross-Origin helper for Rails
|
170
|
+
test_files: []
|