rack-cors 1.0.2 → 1.1.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -5
- data/.travis.yml +5 -3
- data/{CHANGELOG → CHANGELOG.md} +32 -0
- data/Gemfile +1 -1
- data/README.md +15 -11
- data/lib/rack/cors.rb +36 -18
- data/lib/rack/cors/version.rb +1 -1
- data/rack-cors.gemspec +7 -6
- data/test/cors/test.cors.coffee +5 -0
- data/test/cors/test.cors.js +16 -8
- data/test/unit/cors_test.rb +65 -13
- data/test/unit/test.ru +3 -0
- metadata +45 -27
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 8f879bc8ea95eac0ca9360c3a553084961d02944255f6ad380b64e855653b8b6
|
4
|
+
data.tar.gz: bd9478603340a1785324ab4f1db9517a8943fdcc1be13193e4d6b83b184fa032
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 12d13e99acef13b159595487b3c0198bc1a355371bdb149241d11e1d0715148e0749085d0f0c362d4defdec2e325b416b1e93aeb28be2d421516d4db8185fdac
|
7
|
+
data.tar.gz: a1f373194a95094f337c545e7751eac2c4d8500dfd607088a88e55774b755fa0ec659710319a2f7997e579231b7de806e63f2ce4a1639cdb732eed5bcbb743b9
|
data/.travis.yml
CHANGED
data/{CHANGELOG → CHANGELOG.md}
RENAMED
@@ -1,6 +1,38 @@
|
|
1
1
|
# Change Log
|
2
2
|
All notable changes to this project will be documented in this file.
|
3
3
|
|
4
|
+
## 1.1.1 - 2019-12-29
|
5
|
+
### Changed
|
6
|
+
- Allow /<resource>/* to match /<resource>/ and /<resource> paths
|
7
|
+
|
8
|
+
## 1.1.0 - 2019-11-19
|
9
|
+
### Changed
|
10
|
+
- Use Rack::Utils.escape_path instead of Rack::Utils.escape
|
11
|
+
- Require Rack 2.0 for escape_path method
|
12
|
+
- Don't try to clean path if invalid.
|
13
|
+
- Return 400 (Bad Request) on preflights with invalid path
|
14
|
+
|
15
|
+
## 1.0.6 - 2019-11-14
|
16
|
+
### Changed
|
17
|
+
- Use Rack::Utils.escape to make compat with Rack 1.6.0
|
18
|
+
|
19
|
+
## 1.0.5 - 2019-11-14
|
20
|
+
### Changed
|
21
|
+
- Update Gem spec to require rack >= 1.6.0
|
22
|
+
|
23
|
+
## 1.0.4 - 2019-11-13
|
24
|
+
### Security
|
25
|
+
- Escape and resolve path before evaluating resource rules (thanks to Colby Morgan)
|
26
|
+
|
27
|
+
## 1.0.3 - 2019-03-24
|
28
|
+
### Changed
|
29
|
+
- Don't send 'Content-Type' header with pre-flight requests
|
30
|
+
- Allow ruby array for vary header config
|
31
|
+
|
32
|
+
## 1.0.2 - 2017-10-22
|
33
|
+
### Fixed
|
34
|
+
- Automatically allow simple headers when headers are set
|
35
|
+
|
4
36
|
## 1.0.1 - 2017-07-18
|
5
37
|
### Fixed
|
6
38
|
- Allow lambda origin configuration
|
data/Gemfile
CHANGED
data/README.md
CHANGED
@@ -13,7 +13,7 @@ Install the gem:
|
|
13
13
|
Or in your Gemfile:
|
14
14
|
|
15
15
|
```ruby
|
16
|
-
gem 'rack-cors'
|
16
|
+
gem 'rack-cors'
|
17
17
|
```
|
18
18
|
|
19
19
|
|
@@ -25,7 +25,6 @@ Put something like the code below in `config/application.rb` of your Rails appli
|
|
25
25
|
```ruby
|
26
26
|
module YourApp
|
27
27
|
class Application < Rails::Application
|
28
|
-
|
29
28
|
# ...
|
30
29
|
|
31
30
|
# Rails 5
|
@@ -33,7 +32,7 @@ module YourApp
|
|
33
32
|
config.middleware.insert_before 0, Rack::Cors do
|
34
33
|
allow do
|
35
34
|
origins '*'
|
36
|
-
resource '*', :
|
35
|
+
resource '*', headers: :any, methods: [:get, :post, :options]
|
37
36
|
end
|
38
37
|
end
|
39
38
|
|
@@ -42,15 +41,14 @@ module YourApp
|
|
42
41
|
config.middleware.insert_before 0, "Rack::Cors" do
|
43
42
|
allow do
|
44
43
|
origins '*'
|
45
|
-
resource '*', :
|
44
|
+
resource '*', headers: :any, methods: [:get, :post, :options]
|
46
45
|
end
|
47
46
|
end
|
48
|
-
|
49
47
|
end
|
50
48
|
end
|
51
49
|
```
|
52
50
|
|
53
|
-
We use `insert_before` to make sure `Rack::Cors` runs at the beginning of the stack to make sure it isn't interfered with
|
51
|
+
We use `insert_before` to make sure `Rack::Cors` runs at the beginning of the stack to make sure it isn't interfered with by other middleware (see `Rack::Cache` note in **Common Gotchas** section). Check out the [rails 4 example](https://github.com/cyu/rack-cors/tree/master/examples/rails4) and [rails 3 example](https://github.com/cyu/rack-cors/tree/master/examples/rails3).
|
54
52
|
|
55
53
|
See The [Rails Guide to Rack](http://guides.rubyonrails.org/rails_on_rack.html) for more details on rack middlewares or watch the [railscast](http://railscasts.com/episodes/151-rack-middleware).
|
56
54
|
|
@@ -69,16 +67,22 @@ use Rack::Cors do
|
|
69
67
|
|
70
68
|
resource '/file/list_all/', :headers => 'x-domain-token'
|
71
69
|
resource '/file/at/*',
|
72
|
-
:
|
73
|
-
:
|
74
|
-
:
|
75
|
-
:
|
70
|
+
methods: [:get, :post, :delete, :put, :patch, :options, :head],
|
71
|
+
headers: 'x-domain-token',
|
72
|
+
expose: ['Some-Custom-Response-Header'],
|
73
|
+
max_age: 600
|
76
74
|
# headers to expose
|
77
75
|
end
|
78
76
|
|
79
77
|
allow do
|
80
78
|
origins '*'
|
81
|
-
resource '/public/*', :
|
79
|
+
resource '/public/*', headers: :any, methods: :get
|
80
|
+
|
81
|
+
# Only allow a request for a specific host
|
82
|
+
resource '/api/v1/*',
|
83
|
+
headers: :any,
|
84
|
+
methods: :get,
|
85
|
+
if: proc { |env| env['HTTP_HOST'] == 'api.example.com' }
|
82
86
|
end
|
83
87
|
end
|
84
88
|
```
|
data/lib/rack/cors.rb
CHANGED
@@ -16,10 +16,8 @@ module Rack
|
|
16
16
|
# retaining the old key for backwards compatibility
|
17
17
|
ENV_KEY = 'rack.cors'.freeze
|
18
18
|
|
19
|
-
OPTIONS
|
20
|
-
VARY
|
21
|
-
CONTENT_TYPE = 'Content-Type'.freeze
|
22
|
-
TEXT_PLAIN = 'text/plain'.freeze
|
19
|
+
OPTIONS = 'OPTIONS'.freeze
|
20
|
+
VARY = 'Vary'.freeze
|
23
21
|
|
24
22
|
DEFAULT_VARY_HEADERS = ['Origin'].freeze
|
25
23
|
|
@@ -66,24 +64,29 @@ module Rack
|
|
66
64
|
def call(env)
|
67
65
|
env[HTTP_ORIGIN] ||= env[HTTP_X_ORIGIN] if env[HTTP_X_ORIGIN]
|
68
66
|
|
67
|
+
path = evaluate_path(env)
|
68
|
+
|
69
69
|
add_headers = nil
|
70
70
|
if env[HTTP_ORIGIN]
|
71
71
|
debug(env) do
|
72
72
|
[ 'Incoming Headers:',
|
73
73
|
" Origin: #{env[HTTP_ORIGIN]}",
|
74
|
+
" Path-Info: #{path}",
|
74
75
|
" Access-Control-Request-Method: #{env[HTTP_ACCESS_CONTROL_REQUEST_METHOD]}",
|
75
76
|
" Access-Control-Request-Headers: #{env[HTTP_ACCESS_CONTROL_REQUEST_HEADERS]}"
|
76
77
|
].join("\n")
|
77
78
|
end
|
78
|
-
|
79
|
-
|
79
|
+
|
80
|
+
if env[REQUEST_METHOD] == OPTIONS && env[HTTP_ACCESS_CONTROL_REQUEST_METHOD]
|
81
|
+
return [400, {}, []] unless Rack::Utils.valid_path?(path)
|
82
|
+
headers = process_preflight(env, path)
|
80
83
|
debug(env) do
|
81
84
|
"Preflight Headers:\n" +
|
82
85
|
headers.collect{|kv| " #{kv.join(': ')}"}.join("\n")
|
83
86
|
end
|
84
87
|
return [200, headers, []]
|
85
88
|
else
|
86
|
-
add_headers = process_cors(env)
|
89
|
+
add_headers = process_cors(env, path)
|
87
90
|
end
|
88
91
|
else
|
89
92
|
Result.miss(env, Result::MISS_NO_ORIGIN)
|
@@ -92,7 +95,7 @@ module Rack
|
|
92
95
|
# This call must be done BEFORE calling the app because for some reason
|
93
96
|
# env[PATH_INFO] gets changed after that and it won't match. (At least
|
94
97
|
# in rails 4.1.6)
|
95
|
-
vary_resource = resource_for_path(
|
98
|
+
vary_resource = resource_for_path(path)
|
96
99
|
|
97
100
|
status, headers, body = @app.call env
|
98
101
|
|
@@ -117,7 +120,7 @@ module Rack
|
|
117
120
|
else
|
118
121
|
DEFAULT_VARY_HEADERS
|
119
122
|
end
|
120
|
-
headers[VARY] = ((vary ? vary.split(/,\s*/) : []) + cors_vary_headers).uniq.join(', ')
|
123
|
+
headers[VARY] = ((vary ? ([vary].flatten.map { |v| v.split(/,\s*/) }.flatten) : []) + cors_vary_headers).uniq.join(', ')
|
121
124
|
end
|
122
125
|
|
123
126
|
if debug? && result = env[RACK_CORS]
|
@@ -149,14 +152,28 @@ module Rack
|
|
149
152
|
end
|
150
153
|
end
|
151
154
|
|
155
|
+
def evaluate_path(env)
|
156
|
+
path = env[PATH_INFO]
|
157
|
+
|
158
|
+
if path
|
159
|
+
path = Rack::Utils.unescape_path(path)
|
160
|
+
|
161
|
+
if Rack::Utils.valid_path?(path)
|
162
|
+
path = Rack::Utils.clean_path_info(path)
|
163
|
+
end
|
164
|
+
end
|
165
|
+
|
166
|
+
path
|
167
|
+
end
|
168
|
+
|
152
169
|
def all_resources
|
153
170
|
@all_resources ||= []
|
154
171
|
end
|
155
172
|
|
156
|
-
def process_preflight(env)
|
173
|
+
def process_preflight(env, path)
|
157
174
|
result = Result.preflight(env)
|
158
175
|
|
159
|
-
resource, error = match_resource(env)
|
176
|
+
resource, error = match_resource(path, env)
|
160
177
|
unless resource
|
161
178
|
result.miss(error)
|
162
179
|
return {}
|
@@ -165,8 +182,8 @@ module Rack
|
|
165
182
|
return resource.process_preflight(env, result)
|
166
183
|
end
|
167
184
|
|
168
|
-
def process_cors(env)
|
169
|
-
resource, error = match_resource(env)
|
185
|
+
def process_cors(env, path)
|
186
|
+
resource, error = match_resource(path, env)
|
170
187
|
if resource
|
171
188
|
Result.hit(env)
|
172
189
|
cors = resource.to_headers(env)
|
@@ -187,8 +204,7 @@ module Rack
|
|
187
204
|
nil
|
188
205
|
end
|
189
206
|
|
190
|
-
def match_resource(env)
|
191
|
-
path = env[PATH_INFO]
|
207
|
+
def match_resource(path, env)
|
192
208
|
origin = env[HTTP_ORIGIN]
|
193
209
|
|
194
210
|
origin_matched = false
|
@@ -332,7 +348,7 @@ module Rack
|
|
332
348
|
|
333
349
|
self.path = path
|
334
350
|
self.credentials = public_resource ? false : (opts[:credentials] == true)
|
335
|
-
self.max_age = opts[:max_age] ||
|
351
|
+
self.max_age = opts[:max_age] || 7200
|
336
352
|
self.pattern = compile(path)
|
337
353
|
self.if_proc = opts[:if]
|
338
354
|
self.vary_headers = opts[:vary] && [opts[:vary]].flatten
|
@@ -363,7 +379,7 @@ module Rack
|
|
363
379
|
end
|
364
380
|
|
365
381
|
def process_preflight(env, result)
|
366
|
-
headers = {
|
382
|
+
headers = {}
|
367
383
|
|
368
384
|
request_method = env[HTTP_ACCESS_CONTROL_REQUEST_METHOD]
|
369
385
|
if request_method.nil?
|
@@ -431,8 +447,10 @@ module Rack
|
|
431
447
|
if path.respond_to? :to_str
|
432
448
|
special_chars = %w{. + ( )}
|
433
449
|
pattern =
|
434
|
-
path.to_str.gsub(/((:\w+)
|
450
|
+
path.to_str.gsub(/((:\w+)|\/\*|[\*#{special_chars.join}])/) do |match|
|
435
451
|
case match
|
452
|
+
when "/*"
|
453
|
+
"\\/?(.*?)"
|
436
454
|
when "*"
|
437
455
|
"(.*?)"
|
438
456
|
when *special_chars
|
data/lib/rack/cors/version.rb
CHANGED
data/rack-cors.gemspec
CHANGED
@@ -8,7 +8,7 @@ Gem::Specification.new do |spec|
|
|
8
8
|
spec.version = Rack::Cors::VERSION
|
9
9
|
spec.authors = ["Calvin Yu"]
|
10
10
|
spec.email = ["me@sourcebender.com"]
|
11
|
-
spec.description = %q{Middleware that will make Rack-based apps CORS compatible.
|
11
|
+
spec.description = %q{Middleware that will make Rack-based apps CORS compatible. Fork the project here: https://github.com/cyu/rack-cors}
|
12
12
|
spec.summary = %q{Middleware for enabling Cross-Origin Resource Sharing in Rack apps}
|
13
13
|
spec.homepage = "https://github.com/cyu/rack-cors"
|
14
14
|
spec.license = "MIT"
|
@@ -18,9 +18,10 @@ Gem::Specification.new do |spec|
|
|
18
18
|
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
19
19
|
spec.require_paths = ["lib"]
|
20
20
|
|
21
|
-
spec.
|
22
|
-
spec.add_development_dependency "
|
23
|
-
spec.add_development_dependency "
|
24
|
-
spec.add_development_dependency "
|
25
|
-
spec.add_development_dependency "
|
21
|
+
spec.add_dependency "rack", ">= 2.0.0"
|
22
|
+
spec.add_development_dependency "bundler", ">= 1.16.0", '< 3'
|
23
|
+
spec.add_development_dependency "rake", "~> 12.3.0"
|
24
|
+
spec.add_development_dependency "minitest", "~> 5.11.0"
|
25
|
+
spec.add_development_dependency "mocha", "~> 1.6.0"
|
26
|
+
spec.add_development_dependency "rack-test", "~> 1.1.0"
|
26
27
|
end
|
data/test/cors/test.cors.coffee
CHANGED
@@ -12,6 +12,11 @@ describe 'CORS', ->
|
|
12
12
|
expect(data).to.eql('Hello world')
|
13
13
|
done()
|
14
14
|
|
15
|
+
it 'should allow PATCH access to dynamic resource', (done) ->
|
16
|
+
$.ajax("http://#{CORS_SERVER}/", type: 'PATCH').done (data, textStatus, jqXHR) ->
|
17
|
+
expect(data).to.eql('Hello world')
|
18
|
+
done()
|
19
|
+
|
15
20
|
it 'should allow HEAD access to dynamic resource', (done) ->
|
16
21
|
$.ajax("http://#{CORS_SERVER}/", type: 'HEAD').done (data, textStatus, jqXHR) ->
|
17
22
|
expect(jqXHR.status).to.eql(200)
|
data/test/cors/test.cors.js
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
// Generated by CoffeeScript
|
1
|
+
// Generated by CoffeeScript 2.3.1
|
2
2
|
(function() {
|
3
3
|
var CORS_SERVER;
|
4
4
|
|
@@ -6,21 +6,29 @@
|
|
6
6
|
|
7
7
|
describe('CORS', function() {
|
8
8
|
it('should allow access to dynamic resource', function(done) {
|
9
|
-
return $.get(
|
9
|
+
return $.get(`http://${CORS_SERVER}/`, function(data, status, xhr) {
|
10
10
|
expect(data).to.eql('Hello world');
|
11
11
|
return done();
|
12
12
|
});
|
13
13
|
});
|
14
14
|
it('should allow PUT access to dynamic resource', function(done) {
|
15
|
-
return $.ajax(
|
15
|
+
return $.ajax(`http://${CORS_SERVER}/`, {
|
16
16
|
type: 'PUT'
|
17
17
|
}).done(function(data, textStatus, jqXHR) {
|
18
18
|
expect(data).to.eql('Hello world');
|
19
19
|
return done();
|
20
20
|
});
|
21
21
|
});
|
22
|
+
it('should allow PATCH access to dynamic resource', function(done) {
|
23
|
+
return $.ajax(`http://${CORS_SERVER}/`, {
|
24
|
+
type: 'PATCH'
|
25
|
+
}).done(function(data, textStatus, jqXHR) {
|
26
|
+
expect(data).to.eql('Hello world');
|
27
|
+
return done();
|
28
|
+
});
|
29
|
+
});
|
22
30
|
it('should allow HEAD access to dynamic resource', function(done) {
|
23
|
-
return $.ajax(
|
31
|
+
return $.ajax(`http://${CORS_SERVER}/`, {
|
24
32
|
type: 'HEAD'
|
25
33
|
}).done(function(data, textStatus, jqXHR) {
|
26
34
|
expect(jqXHR.status).to.eql(200);
|
@@ -28,7 +36,7 @@
|
|
28
36
|
});
|
29
37
|
});
|
30
38
|
it('should allow DELETE access to dynamic resource', function(done) {
|
31
|
-
return $.ajax(
|
39
|
+
return $.ajax(`http://${CORS_SERVER}/`, {
|
32
40
|
type: 'DELETE'
|
33
41
|
}).done(function(data, textStatus, jqXHR) {
|
34
42
|
expect(data).to.eql('Hello world');
|
@@ -36,7 +44,7 @@
|
|
36
44
|
});
|
37
45
|
});
|
38
46
|
it('should allow OPTIONS access to dynamic resource', function(done) {
|
39
|
-
return $.ajax(
|
47
|
+
return $.ajax(`http://${CORS_SERVER}/`, {
|
40
48
|
type: 'OPTIONS'
|
41
49
|
}).done(function(data, textStatus, jqXHR) {
|
42
50
|
expect(jqXHR.status).to.eql(200);
|
@@ -44,7 +52,7 @@
|
|
44
52
|
});
|
45
53
|
});
|
46
54
|
it('should allow access to static resource', function(done) {
|
47
|
-
return $.get(
|
55
|
+
return $.get(`http://${CORS_SERVER}/static.txt`, function(data, status, xhr) {
|
48
56
|
expect($.trim(data)).to.eql("hello world");
|
49
57
|
return done();
|
50
58
|
});
|
@@ -52,7 +60,7 @@
|
|
52
60
|
return it('should allow post resource', function(done) {
|
53
61
|
return $.ajax({
|
54
62
|
type: 'POST',
|
55
|
-
url:
|
63
|
+
url: `http://${CORS_SERVER}/cors`,
|
56
64
|
beforeSend: function(xhr) {
|
57
65
|
return xhr.setRequestHeader('X-Requested-With', 'XMLHTTPRequest');
|
58
66
|
},
|
data/test/unit/cors_test.rb
CHANGED
@@ -19,11 +19,11 @@ end
|
|
19
19
|
|
20
20
|
module MiniTest::Assertions
|
21
21
|
def assert_cors_success(response)
|
22
|
-
|
22
|
+
assert !response.headers['Access-Control-Allow-Origin'].nil?, "Expected a successful CORS response"
|
23
23
|
end
|
24
24
|
|
25
25
|
def assert_not_cors_success(response)
|
26
|
-
|
26
|
+
assert response.headers['Access-Control-Allow-Origin'].nil?, "Expected a failed CORS response"
|
27
27
|
end
|
28
28
|
end
|
29
29
|
|
@@ -40,6 +40,18 @@ class CaptureResult
|
|
40
40
|
end
|
41
41
|
end
|
42
42
|
|
43
|
+
class FakeProxy
|
44
|
+
def initialize(app, options = {})
|
45
|
+
@app = app
|
46
|
+
end
|
47
|
+
|
48
|
+
def call(env)
|
49
|
+
status, headers, body = @app.call(env)
|
50
|
+
headers['Vary'] = %w(Origin User-Agent)
|
51
|
+
[status, headers, body]
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
43
55
|
Rack::MockResponse.infect_an_assertion :assert_cors_success, :must_render_cors_success, :only_one_argument
|
44
56
|
Rack::MockResponse.infect_an_assertion :assert_not_cors_success, :wont_render_cors_success, :only_one_argument
|
45
57
|
|
@@ -48,11 +60,12 @@ describe Rack::Cors do
|
|
48
60
|
|
49
61
|
attr_accessor :cors_result
|
50
62
|
|
51
|
-
def load_app(name)
|
63
|
+
def load_app(name, options = {})
|
52
64
|
test = self
|
53
65
|
Rack::Builder.new do
|
54
66
|
use CaptureResult, :holder => test
|
55
67
|
eval File.read(File.dirname(__FILE__) + "/#{name}.ru")
|
68
|
+
use FakeProxy if options[:proxy]
|
56
69
|
map('/') do
|
57
70
|
run proc { |env|
|
58
71
|
[200, {'Content-Type' => 'text/html'}, ['success']]
|
@@ -133,6 +146,21 @@ describe Rack::Cors do
|
|
133
146
|
last_response.headers['Vary'].must_equal 'Origin, Host'
|
134
147
|
end
|
135
148
|
|
149
|
+
it "decode URL and resolve paths before resource matching" do
|
150
|
+
header 'Origin', 'http://localhost:3000'
|
151
|
+
get '/public/a/..%2F..%2Fprivate/stuff'
|
152
|
+
last_response.wont_render_cors_success
|
153
|
+
end
|
154
|
+
|
155
|
+
describe 'with array of upstream Vary headers' do
|
156
|
+
let(:app) { load_app('test', { proxy: true }) }
|
157
|
+
|
158
|
+
it 'should add to them' do
|
159
|
+
successful_cors_request '/vary_test'
|
160
|
+
last_response.headers['Vary'].must_equal 'Origin, User-Agent, Host'
|
161
|
+
end
|
162
|
+
end
|
163
|
+
|
136
164
|
it 'should add Vary header if Access-Control-Allow-Origin header was added and if it is specific' do
|
137
165
|
successful_cors_request '/', :origin => "http://192.168.0.3:8080"
|
138
166
|
last_response.headers['Access-Control-Allow-Origin'].must_equal 'http://192.168.0.3:8080'
|
@@ -244,6 +272,19 @@ describe Rack::Cors do
|
|
244
272
|
cors.call({'HTTP_ORIGIN' => 'test.com'})
|
245
273
|
end
|
246
274
|
end
|
275
|
+
|
276
|
+
it 'should use Logger if none is set' do
|
277
|
+
app = mock
|
278
|
+
app.stubs(:call).returns([200, {}, ['']])
|
279
|
+
|
280
|
+
logger = mock
|
281
|
+
Logger.expects(:new).returns(logger)
|
282
|
+
logger.expects(:tap).returns(logger)
|
283
|
+
logger.expects(:debug)
|
284
|
+
|
285
|
+
cors = Rack::Cors.new(app, :debug => true) {}
|
286
|
+
cors.call({'HTTP_ORIGIN' => 'test.com'})
|
287
|
+
end
|
247
288
|
end
|
248
289
|
|
249
290
|
describe 'preflight requests' do
|
@@ -280,6 +321,11 @@ describe Rack::Cors do
|
|
280
321
|
last_response.must_render_cors_success
|
281
322
|
end
|
282
323
|
|
324
|
+
it 'allows PATCH method' do
|
325
|
+
preflight_request('http://localhost:3000', '/', :methods => [ :patch ])
|
326
|
+
last_response.must_render_cors_success
|
327
|
+
end
|
328
|
+
|
283
329
|
it 'should allow header case insensitive match' do
|
284
330
|
preflight_request('http://localhost:3000', '/single_header', :headers => 'X-Domain-Token')
|
285
331
|
last_response.must_render_cors_success
|
@@ -295,13 +341,25 @@ describe Rack::Cors do
|
|
295
341
|
last_response.must_render_cors_success
|
296
342
|
end
|
297
343
|
|
298
|
-
it
|
344
|
+
it "should allow '*' origins to allow any origin" do
|
299
345
|
preflight_request('http://locohost:3000', '/public')
|
300
346
|
last_response.must_render_cors_success
|
301
347
|
last_response.headers['Access-Control-Allow-Origin'].must_equal '*'
|
302
348
|
end
|
303
349
|
|
304
|
-
it
|
350
|
+
it "should allow '/<path>/' resource if match pattern is /<path>/*" do
|
351
|
+
preflight_request('http://localhost:3000', '/wildcard/')
|
352
|
+
last_response.must_render_cors_success
|
353
|
+
last_response.headers['Access-Control-Allow-Origin'].wont_equal nil
|
354
|
+
end
|
355
|
+
|
356
|
+
it "should allow '/<path>' resource if match pattern is /<path>/*" do
|
357
|
+
preflight_request('http://localhost:3000', '/wildcard')
|
358
|
+
last_response.must_render_cors_success
|
359
|
+
last_response.headers['Access-Control-Allow-Origin'].wont_equal nil
|
360
|
+
end
|
361
|
+
|
362
|
+
it "should allow '*' origin to allow any origin, and set '*' if no credentials required" do
|
305
363
|
preflight_request('http://locohost:3000', '/public_without_credentials')
|
306
364
|
last_response.must_render_cors_success
|
307
365
|
last_response.headers['Access-Control-Allow-Origin'].must_equal '*'
|
@@ -313,12 +371,6 @@ describe Rack::Cors do
|
|
313
371
|
last_response.headers['Access-Control-Allow-Origin'].must_equal 'file://'
|
314
372
|
end
|
315
373
|
|
316
|
-
it 'should return a Content-Type' do
|
317
|
-
preflight_request('http://localhost:3000', '/')
|
318
|
-
last_response.must_render_cors_success
|
319
|
-
last_response.headers['Content-Type'].wont_be_nil
|
320
|
-
end
|
321
|
-
|
322
374
|
describe '' do
|
323
375
|
|
324
376
|
let(:app) do
|
@@ -332,7 +384,7 @@ describe Rack::Cors do
|
|
332
384
|
end
|
333
385
|
end
|
334
386
|
map('/') do
|
335
|
-
run ->(env) { [500, {
|
387
|
+
run ->(env) { [500, {}, ['FAIL!']] }
|
336
388
|
end
|
337
389
|
end
|
338
390
|
end
|
@@ -389,7 +441,7 @@ describe Rack::Cors do
|
|
389
441
|
end
|
390
442
|
end
|
391
443
|
map('/') do
|
392
|
-
run ->(env) { [200, {'
|
444
|
+
run ->(env) { [200, {'Access-Control-Allow-Origin' => 'http://foo.net'}, ['success']] }
|
393
445
|
end
|
394
446
|
end
|
395
447
|
end
|
data/test/unit/test.ru
CHANGED
@@ -19,6 +19,8 @@ use Rack::Cors do
|
|
19
19
|
resource '/expose_multiple_headers', :expose => %w{expose-test-1 expose-test-2}
|
20
20
|
resource '/conditional', :methods => :get, :if => proc { |env| !!env['HTTP_X_OK'] }
|
21
21
|
resource '/vary_test', :methods => :get, :vary => %w{ Origin Host }
|
22
|
+
resource '/patch_test', :methods => :patch
|
23
|
+
resource '/wildcard/*', :methods => :any
|
22
24
|
# resource '/file/at/*',
|
23
25
|
# :methods => [:get, :post, :put, :delete],
|
24
26
|
# :headers => :any,
|
@@ -40,6 +42,7 @@ use Rack::Cors do
|
|
40
42
|
allow do
|
41
43
|
origins '*'
|
42
44
|
resource '/public'
|
45
|
+
resource '/public/*'
|
43
46
|
resource '/public_without_credentials', :credentials => false
|
44
47
|
end
|
45
48
|
|
metadata
CHANGED
@@ -1,87 +1,106 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rack-cors
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.1.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Calvin Yu
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2019-12-30 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: rack
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ">="
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: 2.0.0
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ">="
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: 2.0.0
|
13
27
|
- !ruby/object:Gem::Dependency
|
14
28
|
name: bundler
|
15
29
|
requirement: !ruby/object:Gem::Requirement
|
16
30
|
requirements:
|
17
|
-
- - "
|
31
|
+
- - ">="
|
18
32
|
- !ruby/object:Gem::Version
|
19
|
-
version:
|
33
|
+
version: 1.16.0
|
34
|
+
- - "<"
|
35
|
+
- !ruby/object:Gem::Version
|
36
|
+
version: '3'
|
20
37
|
type: :development
|
21
38
|
prerelease: false
|
22
39
|
version_requirements: !ruby/object:Gem::Requirement
|
23
40
|
requirements:
|
24
|
-
- - "
|
41
|
+
- - ">="
|
42
|
+
- !ruby/object:Gem::Version
|
43
|
+
version: 1.16.0
|
44
|
+
- - "<"
|
25
45
|
- !ruby/object:Gem::Version
|
26
|
-
version: '
|
46
|
+
version: '3'
|
27
47
|
- !ruby/object:Gem::Dependency
|
28
48
|
name: rake
|
29
49
|
requirement: !ruby/object:Gem::Requirement
|
30
50
|
requirements:
|
31
|
-
- - "
|
51
|
+
- - "~>"
|
32
52
|
- !ruby/object:Gem::Version
|
33
|
-
version:
|
53
|
+
version: 12.3.0
|
34
54
|
type: :development
|
35
55
|
prerelease: false
|
36
56
|
version_requirements: !ruby/object:Gem::Requirement
|
37
57
|
requirements:
|
38
|
-
- - "
|
58
|
+
- - "~>"
|
39
59
|
- !ruby/object:Gem::Version
|
40
|
-
version:
|
60
|
+
version: 12.3.0
|
41
61
|
- !ruby/object:Gem::Dependency
|
42
62
|
name: minitest
|
43
63
|
requirement: !ruby/object:Gem::Requirement
|
44
64
|
requirements:
|
45
|
-
- - "
|
65
|
+
- - "~>"
|
46
66
|
- !ruby/object:Gem::Version
|
47
|
-
version: 5.
|
67
|
+
version: 5.11.0
|
48
68
|
type: :development
|
49
69
|
prerelease: false
|
50
70
|
version_requirements: !ruby/object:Gem::Requirement
|
51
71
|
requirements:
|
52
|
-
- - "
|
72
|
+
- - "~>"
|
53
73
|
- !ruby/object:Gem::Version
|
54
|
-
version: 5.
|
74
|
+
version: 5.11.0
|
55
75
|
- !ruby/object:Gem::Dependency
|
56
76
|
name: mocha
|
57
77
|
requirement: !ruby/object:Gem::Requirement
|
58
78
|
requirements:
|
59
|
-
- - "
|
79
|
+
- - "~>"
|
60
80
|
- !ruby/object:Gem::Version
|
61
|
-
version:
|
81
|
+
version: 1.6.0
|
62
82
|
type: :development
|
63
83
|
prerelease: false
|
64
84
|
version_requirements: !ruby/object:Gem::Requirement
|
65
85
|
requirements:
|
66
|
-
- - "
|
86
|
+
- - "~>"
|
67
87
|
- !ruby/object:Gem::Version
|
68
|
-
version:
|
88
|
+
version: 1.6.0
|
69
89
|
- !ruby/object:Gem::Dependency
|
70
90
|
name: rack-test
|
71
91
|
requirement: !ruby/object:Gem::Requirement
|
72
92
|
requirements:
|
73
|
-
- - "
|
93
|
+
- - "~>"
|
74
94
|
- !ruby/object:Gem::Version
|
75
|
-
version:
|
95
|
+
version: 1.1.0
|
76
96
|
type: :development
|
77
97
|
prerelease: false
|
78
98
|
version_requirements: !ruby/object:Gem::Requirement
|
79
99
|
requirements:
|
80
|
-
- - "
|
100
|
+
- - "~>"
|
81
101
|
- !ruby/object:Gem::Version
|
82
|
-
version:
|
83
|
-
description: 'Middleware that will make Rack-based apps CORS compatible.
|
84
|
-
here: http://blog.sourcebender.com/2010/06/09/introducin-rack-cors.html. Fork the
|
102
|
+
version: 1.1.0
|
103
|
+
description: 'Middleware that will make Rack-based apps CORS compatible. Fork the
|
85
104
|
project here: https://github.com/cyu/rack-cors'
|
86
105
|
email:
|
87
106
|
- me@sourcebender.com
|
@@ -90,7 +109,7 @@ extensions: []
|
|
90
109
|
extra_rdoc_files: []
|
91
110
|
files:
|
92
111
|
- ".travis.yml"
|
93
|
-
- CHANGELOG
|
112
|
+
- CHANGELOG.md
|
94
113
|
- Gemfile
|
95
114
|
- LICENSE.txt
|
96
115
|
- README.md
|
@@ -128,8 +147,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
128
147
|
- !ruby/object:Gem::Version
|
129
148
|
version: '0'
|
130
149
|
requirements: []
|
131
|
-
|
132
|
-
rubygems_version: 2.5.2
|
150
|
+
rubygems_version: 3.0.3
|
133
151
|
signing_key:
|
134
152
|
specification_version: 4
|
135
153
|
summary: Middleware for enabling Cross-Origin Resource Sharing in Rack apps
|