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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: 7a4d5e6683440676f486ce61b3c16ff2e7c8f65e
4
- data.tar.gz: be95c0c3dce56c965aff4b1cb398f2ad6fb4f6b3
2
+ SHA256:
3
+ metadata.gz: 8f879bc8ea95eac0ca9360c3a553084961d02944255f6ad380b64e855653b8b6
4
+ data.tar.gz: bd9478603340a1785324ab4f1db9517a8943fdcc1be13193e4d6b83b184fa032
5
5
  SHA512:
6
- metadata.gz: 8ae27dfd82bd822e700c476963118b15e68dee7850aaccb8b43a05670903f9f66217c8cd77dcf425f664581ecadf00eb43c1c1926648d97caf07c6d4a4dd0574
7
- data.tar.gz: df278b2f1b3e6f0b01305d601fb58f2d41aef0579232d5ae27564be76483afdfb58b9219708d5a944c7db293025d7bacec4924dc63c06aefed2a7df4ad00e9ec
6
+ metadata.gz: 12d13e99acef13b159595487b3c0198bc1a355371bdb149241d11e1d0715148e0749085d0f0c362d4defdec2e325b416b1e93aeb28be2d421516d4db8185fdac
7
+ data.tar.gz: a1f373194a95094f337c545e7751eac2c4d8500dfd607088a88e55774b755fa0ec659710319a2f7997e579231b7de806e63f2ce4a1639cdb732eed5bcbb743b9
data/.travis.yml CHANGED
@@ -1,6 +1,8 @@
1
1
  language: ruby
2
2
  sudo: false
3
3
  rvm:
4
- - 2.2.5
5
- - 2.3.0
6
- - 2.3.1
4
+ - 2.2
5
+ - 2.3
6
+ - 2.4
7
+ - 2.5
8
+ - 2.6
@@ -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
@@ -3,4 +3,4 @@ source 'https://rubygems.org'
3
3
  # Specify your gem's dependencies in rack-cors.gemspec
4
4
  gemspec
5
5
 
6
- gem 'pry-byebug'
6
+ gem 'pry-byebug', '~> 3.6.0'
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', :require => '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 '*', :headers => :any, :methods => [:get, :post, :options]
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 '*', :headers => :any, :methods => [:get, :post, :options]
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 with 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).
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
- :methods => [:get, :post, :delete, :put, :patch, :options, :head],
73
- :headers => 'x-domain-token',
74
- :expose => ['Some-Custom-Response-Header'],
75
- :max_age => 600
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/*', :headers => :any, :methods => :get
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 = 'OPTIONS'.freeze
20
- VARY = 'Vary'.freeze
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
- if env[REQUEST_METHOD] == OPTIONS and env[HTTP_ACCESS_CONTROL_REQUEST_METHOD]
79
- headers = process_preflight(env)
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(env[PATH_INFO])
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] || 1728000
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 = {CONTENT_TYPE => TEXT_PLAIN}
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+)|[\*#{special_chars.join}])/) do |match|
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
@@ -1,5 +1,5 @@
1
1
  module Rack
2
2
  class Cors
3
- VERSION = "1.0.2"
3
+ VERSION = "1.1.1"
4
4
  end
5
5
  end
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. Read more here: http://blog.sourcebender.com/2010/06/09/introducin-rack-cors.html. Fork the project here: https://github.com/cyu/rack-cors}
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.add_development_dependency "bundler", "~> 1.3"
22
- spec.add_development_dependency "rake"
23
- spec.add_development_dependency "minitest", ">= 5.3.0"
24
- spec.add_development_dependency "mocha", ">= 0.14.0"
25
- spec.add_development_dependency "rack-test", ">= 0"
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
@@ -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)
@@ -1,4 +1,4 @@
1
- // Generated by CoffeeScript 1.12.6
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("http://" + CORS_SERVER + "/", function(data, status, xhr) {
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("http://" + CORS_SERVER + "/", {
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("http://" + CORS_SERVER + "/", {
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("http://" + CORS_SERVER + "/", {
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("http://" + CORS_SERVER + "/", {
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("http://" + CORS_SERVER + "/static.txt", function(data, status, xhr) {
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: "http://" + CORS_SERVER + "/cors",
63
+ url: `http://${CORS_SERVER}/cors`,
56
64
  beforeSend: function(xhr) {
57
65
  return xhr.setRequestHeader('X-Requested-With', 'XMLHTTPRequest');
58
66
  },
@@ -19,11 +19,11 @@ end
19
19
 
20
20
  module MiniTest::Assertions
21
21
  def assert_cors_success(response)
22
- assert !response.headers['Access-Control-Allow-Origin'].nil?, "Expected a successful CORS response"
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
- assert response.headers['Access-Control-Allow-Origin'].nil?, "Expected a failed CORS response"
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 'should * origin should allow any origin' do
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 'should * origin should allow any origin, and set * if no credentials required' do
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, {'Content-Type' => 'text/plain'}, ['FAIL!']] }
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, {'Content-Type' => 'text/plain', 'Access-Control-Allow-Origin' => 'http://foo.net'}, ['success']] }
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.0.2
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: 2017-10-22 00:00:00.000000000 Z
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: '1.3'
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: '1.3'
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: '0'
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: '0'
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.3.0
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.3.0
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: 0.14.0
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: 0.14.0
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: '0'
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: '0'
83
- description: 'Middleware that will make Rack-based apps CORS compatible. Read more
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
- rubyforge_project:
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