rack-cors 0.2.9 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of rack-cors might be problematic. Click here for more details.

checksums.yaml CHANGED
@@ -1,15 +1,7 @@
1
1
  ---
2
- !binary "U0hBMQ==":
3
- metadata.gz: !binary |-
4
- OTQyY2Q0OGNmOGZjMWNhOTc0OTdmOTY3ZTk0NDY0NzhmODE5YTI5Yg==
5
- data.tar.gz: !binary |-
6
- ZDQyMTJlMTg3MDczMmE0ZjFkMmZjOGExMGU3NDE0NmQ2MGY1YzBlZQ==
2
+ SHA1:
3
+ metadata.gz: 7fa6e09583a5f2886f25edeea60c8684dd4570e2
4
+ data.tar.gz: d6527b5970f02a3a43dfc305cf8c3edde91ae00b
7
5
  SHA512:
8
- metadata.gz: !binary |-
9
- NGViNTEzOTIzZjc2ZjVhNjZkZDBmODQ5NzAzNzk3ZThiYzZkMGU2YTU3MmUx
10
- NDc3ODlkMTIwNjFmNGZhOWUwZmNjMmEyN2YxZWQ1NTA3NDU3NjEzMGYyNDdi
11
- NTM4ZTI3NmQ4ZTE1MmNjOGY5ZTBlNDk2YTQyZDQ0NzA5ZTc2NTE=
12
- data.tar.gz: !binary |-
13
- NGIwN2QwMjQ1OTQwNzY3M2MzYWFiNWI0Y2RjMjVmMTEzMTk3YjE1ZGJhNjQw
14
- YzRjNzhkZTRmZGExYjU2YzU5Y2Q4OTkyNzAyYTFhODRmNGViOGI0MTQyNmNh
15
- MjAwYjUxZjRkMGZjMjRmMDJhYjRiOWU2ZmNjNTFjNmEzZTY2YWQ=
6
+ metadata.gz: 6b4048b21713e5b87d4fca48995253fb500e28e82e38a57a6af489bfa0989706e6cb008f9894d2d87c7b5c7dc215aa32fdfcb3d65748cf5152a79e8c59e1813f
7
+ data.tar.gz: dd9967c547e09f5eebecc4dfcaf1fab6f16395786af08f8c0dbb09d92e3c6c5400c5d828536b5e66588086c9d9fd1e5af7cfcdebe438c92689b7c2bf066421fd
@@ -0,0 +1,15 @@
1
+ # Change Log
2
+ All notable changes to this project will be documented in this file.
3
+
4
+ ## 0.3.0 - 2014-10-19
5
+ ### Added
6
+ - Added support for defining a logger with a Proc
7
+ - Return a X-Rack-CORS header when in debug mode detailing how
8
+ Rack::Cors processed a request
9
+ - Added support for non HTTP/HTTPS origins when just a domain is
10
+ is specified
11
+
12
+ ### Changed
13
+ - Changed the log level of the fallback logger to DEBUG
14
+ - Print warning when attempting to use :any as an allowed method
15
+ - Treat incoming `Origin: null` headers as file://
@@ -0,0 +1,113 @@
1
+ # Rack CORS Middleware [![Build Status](https://travis-ci.org/cyu/rack-cors.svg?branch=master)](https://travis-ci.org/cyu/rack-cors)
2
+
3
+ `Rack::Cors` provides support for Cross-Origin Resource Sharing (CORS) for Rack compatible web applications.
4
+
5
+ The [CORS spec](http://www.w3.org/TR/cors/) allows web applications to make cross domain AJAX calls without using workarounds such as JSONP. See [Cross-domain Ajax with Cross-Origin Resource Sharing](http://www.nczonline.net/blog/2010/05/25/cross-domain-ajax-with-cross-origin-resource-sharing/)
6
+
7
+ ## Installation
8
+
9
+ Install the gem:
10
+
11
+ `gem install rack-cors`
12
+
13
+ Or in your Gemfile:
14
+
15
+ ```ruby
16
+ gem 'rack-cors', :require => 'rack/cors'
17
+ ```
18
+
19
+
20
+ ## Configuration
21
+
22
+ ### Rack
23
+
24
+ In `config.ru`, configure `Rack::Cors` by passing a block to the `use` command:
25
+
26
+ ```ruby
27
+ use Rack::Cors do
28
+ allow do
29
+ origins 'localhost:3000', '127.0.0.1:3000',
30
+ /http:\/\/192\.168\.0\.\d{1,3}(:\d+)?/
31
+ # regular expressions can be used here
32
+
33
+ resource '/file/list_all/', :headers => 'x-domain-token'
34
+ resource '/file/at/*',
35
+ :methods => [:get, :post, :put, :delete, :options],
36
+ :headers => 'x-domain-token',
37
+ :expose => ['Some-Custom-Response-Header'],
38
+ :max_age => 600
39
+ # headers to expose
40
+ end
41
+
42
+ allow do
43
+ origins '*'
44
+ resource '/public/*', :headers => :any, :methods => :get
45
+ end
46
+ end
47
+ ```
48
+
49
+ ### Rails
50
+ Put something like the code below in `config/application.rb` of your Rails application. For example, this will allow GET, POST or OPTIONS requests from any origin on any resource.
51
+
52
+ ```ruby
53
+ module YourApp
54
+ class Application < Rails::Application
55
+
56
+ # ...
57
+
58
+ config.middleware.insert_before 0, "Rack::Cors" do
59
+ allow do
60
+ origins '*'
61
+ resource '*', :headers => :any, :methods => [:get, :post, :options]
62
+ end
63
+ end
64
+
65
+ end
66
+ end
67
+ ```
68
+ Refer to [rails 3 example](https://github.com/cyu/rack-cors/tree/master/examples/rails3) and [rails 4 example](https://github.com/cyu/rack-cors/tree/master/examples/rails4) for more details.
69
+
70
+ 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.)
71
+
72
+ ### Configuration Reference
73
+
74
+ #### Middleware Options
75
+ * **debug** (boolean): Enables debug logging and `X-Rack-CORS` HTTP headers for debugging.
76
+ * **logger** (Object or Proc): Specify the logger to log to. If a proc is provided, it will be called when a logger is needed (this is helpful in cases where the logger is initialized after `Rack::Cors` is used, like `Rails.logger`.
77
+
78
+ #### Origin
79
+ Origins can be specified as a string, a regular expression, or as '*' to allow all origins.
80
+
81
+ #### Resource
82
+ A Resource path can be specified as exact string match (`/path/to/file.txt`) or with a '*' wildcard (`/all/files/in/*`). A resource that take the following options:
83
+
84
+ * **methods** (string or array): The HTTP methods allowed for the resource.
85
+ * **headers** (string or array or `:any`): The HTTP headers that will be allowed in the CORS resource request. Use `:any` to allow for any headers in the actual request.
86
+ * **expose** (string or an array): The HTTP headers in the resource response can can be exposed to the client.
87
+ * **credentials** (boolean): Sets the `Access-Control-Allow-Credentials` response header.
88
+ * **max_age** (number): Sets the `Access-Control-Max-Age` response header.
89
+
90
+
91
+ ## Common Gotchas
92
+
93
+ Incorrect positioning of `Rack::Cors` in the middleware stack can produce unexpected results. The Rails example above will put it above all middleware which should cover most issues.
94
+
95
+ Here are some common cases:
96
+
97
+ * **Serving static files.** Insert this middleware before `ActionDispatch::Static` so that static files are served with the proper CORS headers (see note below for a caveat). **NOTE:** that this might not work in production environments as static files are usually served from the web server (Nginx, Apache) and not the Rails container.
98
+
99
+ * **Caching in the middleware.** Insert this middleware before `Rack::Cache` so that the proper CORS headers are written and not cached ones.
100
+
101
+ * **Authentication via Warden** Warden will return immediately if a resource that requires authentication is accessed without authentication. If `Warden::Manager`is in the stack before `Rack::Cors`, it will return without the correct CORS headers being applied, resulting in a failed CORS request. Be sure to insert this middleware before 'Warden::Manager`.
102
+
103
+ To determine where to put the CORS middleware in the Rack stack, run the following command:
104
+
105
+ ```bash
106
+ bundle exec rake middleware
107
+ ```
108
+
109
+ In many cases, the Rack stack will be different running in production environments. For example, the `ActionDispatch::Static` middleware will not be part of the stack if `config.serve_static_assets = false`. You can run the following command to see what your middleware stack looks like in production:
110
+
111
+ ```bash
112
+ bundle exec RAILS_ENV=production rake middleware
113
+ ```
@@ -2,11 +2,23 @@ require 'logger'
2
2
 
3
3
  module Rack
4
4
  class Cors
5
+ ENV_KEY = 'X_RACK_CORS'.freeze
6
+
7
+ ORIGIN_HEADER_KEY = 'HTTP_ORIGIN'.freeze
8
+ PATH_INFO_HEADER_KEY = 'PATH_INFO'.freeze
9
+
5
10
  def initialize(app, opts={}, &block)
6
11
  @app = app
7
- @logger = opts[:logger]
8
12
  @debug_mode = !!opts[:debug]
9
13
 
14
+ if logger = opts[:logger]
15
+ if logger.respond_to? :call
16
+ @logger_proc = opts[:logger]
17
+ else
18
+ @logger = logger
19
+ end
20
+ end
21
+
10
22
  if block_given?
11
23
  if block.arity == 1
12
24
  block.call(self)
@@ -16,6 +28,10 @@ module Rack
16
28
  end
17
29
  end
18
30
 
31
+ def debug?
32
+ @debug_mode
33
+ end
34
+
19
35
  def allow(&block)
20
36
  all_resources << (resources = Resources.new)
21
37
 
@@ -27,14 +43,13 @@ module Rack
27
43
  end
28
44
 
29
45
  def call(env)
30
- env['HTTP_ORIGIN'] = 'file://' if env['HTTP_ORIGIN'] == 'null'
31
- env['HTTP_ORIGIN'] ||= env['HTTP_X_ORIGIN']
46
+ env[ORIGIN_HEADER_KEY] ||= env['HTTP_X_ORIGIN']
32
47
 
33
- cors_headers = nil
34
- if env['HTTP_ORIGIN']
48
+ add_headers = nil
49
+ if env[ORIGIN_HEADER_KEY]
35
50
  debug(env) do
36
51
  [ 'Incoming Headers:',
37
- " Origin: #{env['HTTP_ORIGIN']}",
52
+ " Origin: #{env[ORIGIN_HEADER_KEY]}",
38
53
  " Access-Control-Request-Method: #{env['HTTP_ACCESS_CONTROL_REQUEST_METHOD']}",
39
54
  " Access-Control-Request-Headers: #{env['HTTP_ACCESS_CONTROL_REQUEST_HEADERS']}"
40
55
  ].join("\n")
@@ -48,12 +63,16 @@ module Rack
48
63
  return [200, headers, []]
49
64
  end
50
65
  else
51
- cors_headers = process_cors(env)
66
+ add_headers = process_cors(env)
52
67
  end
68
+ else
69
+ Result.miss(env, Result::MISS_NO_ORIGIN)
53
70
  end
71
+
54
72
  status, headers, body = @app.call env
55
- if cors_headers
56
- headers = headers.merge(cors_headers)
73
+
74
+ if add_headers
75
+ headers = headers.merge(add_headers)
57
76
 
58
77
  # http://www.w3.org/TR/cors/#resource-implementation
59
78
  unless headers['Access-Control-Allow-Origin'] == '*'
@@ -61,16 +80,33 @@ module Rack
61
80
  headers['Vary'] = ((vary ? vary.split(/,\s*/) : []) + ['Origin']).uniq.join(', ')
62
81
  end
63
82
  end
83
+
84
+ if debug? && result = env[ENV_KEY]
85
+ result.append_header(headers)
86
+ end
87
+
64
88
  [status, headers, body]
65
89
  end
66
90
 
67
91
  protected
68
92
  def debug(env, message = nil, &block)
69
- if @debug_mode
70
- logger = @logger || env['rack.logger'] || begin
71
- @logger = ::Logger.new(STDOUT).tap {|logger| logger.level = ::Logger::Severity::INFO}
72
- end
73
- logger.debug(message, &block)
93
+ (@logger || select_logger(env)).debug(message, &block) if debug?
94
+ end
95
+
96
+ def select_logger(env)
97
+ @logger = if @logger_proc
98
+ logger_proc = @logger_proc
99
+ @logger_proc = nil
100
+ logger_proc.call
101
+
102
+ elsif defined?(Rails) && Rails.logger
103
+ Rails.logger
104
+
105
+ elsif env['rack.logger']
106
+ env['rack.logger']
107
+
108
+ else
109
+ ::Logger.new(STDOUT).tap { |logger| logger.level = ::Logger::Severity::DEBUG }
74
110
  end
75
111
  end
76
112
 
@@ -79,22 +115,104 @@ module Rack
79
115
  end
80
116
 
81
117
  def process_preflight(env)
82
- resource = find_resource(env['HTTP_ORIGIN'], env['PATH_INFO'],env)
83
- resource && resource.process_preflight(env)
118
+ resource, error = find_resource(env)
119
+ if resource
120
+ Result.preflight_hit(env)
121
+ preflight = resource.process_preflight(env)
122
+ preflight
123
+
124
+ else
125
+ Result.preflight_miss(env, error)
126
+ nil
127
+ end
84
128
  end
85
129
 
86
130
  def process_cors(env)
87
- resource = find_resource(env['HTTP_ORIGIN'], env['PATH_INFO'],env)
88
- resource.to_headers(env) if resource
131
+ resource, error = find_resource(env)
132
+ if resource
133
+ Result.hit(env)
134
+ cors = resource.to_headers(env)
135
+ cors
136
+
137
+ else
138
+ Result.miss(env, error)
139
+ nil
140
+ end
89
141
  end
90
142
 
91
- def find_resource(origin, path, env)
143
+ def find_resource(env)
144
+ path = env[PATH_INFO_HEADER_KEY]
145
+ origin = env[ORIGIN_HEADER_KEY]
146
+
147
+ origin_matched = false
92
148
  all_resources.each do |r|
93
- if r.allow_origin?(origin, env) and found = r.find_resource(path)
94
- return found
149
+ if r.allow_origin?(origin, env)
150
+ origin_matched = true
151
+ if found = r.find_resource(path)
152
+ return [found, nil]
153
+ end
154
+ end
155
+ end
156
+
157
+ [nil, origin_matched ? Result::MISS_NO_PATH : Result::MISS_NO_ORIGIN]
158
+ end
159
+
160
+ class Result
161
+ HEADER_KEY = 'X-Rack-CORS'.freeze
162
+
163
+ MISS_NO_ORIGIN = 'no-origin'.freeze
164
+ MISS_NO_PATH = 'no-path'.freeze
165
+
166
+ attr_accessor :preflight, :hit, :miss_reason
167
+
168
+ def hit?
169
+ !!hit
170
+ end
171
+
172
+ def preflight?
173
+ !!preflight
174
+ end
175
+
176
+ def self.hit(env)
177
+ r = Result.new
178
+ r.preflight = false
179
+ r.hit = true
180
+ env[ENV_KEY] = r
181
+ end
182
+
183
+ def self.miss(env, reason)
184
+ r = Result.new
185
+ r.preflight = false
186
+ r.hit = false
187
+ r.miss_reason = reason
188
+ env[ENV_KEY] = r
189
+ end
190
+
191
+ def self.preflight_hit(env)
192
+ r = Result.new
193
+ r.preflight = true
194
+ r.hit = true
195
+ env[ENV_KEY] = r
196
+ end
197
+
198
+ def self.preflight_miss(env, reason)
199
+ r = Result.new
200
+ r.preflight = true
201
+ r.hit = false
202
+ r.miss_reason = reason
203
+ env[ENV_KEY] = r
204
+ end
205
+
206
+ def append_header(headers)
207
+ headers[HEADER_KEY] = if hit?
208
+ preflight? ? 'preflight-hit' : 'hit'
209
+ else
210
+ [
211
+ (preflight? ? 'preflight-miss' : 'preflight-hit'),
212
+ miss_reason
213
+ ].join('; ')
95
214
  end
96
215
  end
97
- nil
98
216
  end
99
217
 
100
218
  class Resources
@@ -104,13 +222,14 @@ module Rack
104
222
  @public_resources = false
105
223
  end
106
224
 
107
- def origins(*args,&blk)
225
+ def origins(*args, &blk)
108
226
  @origins = args.flatten.collect do |n|
109
227
  case n
110
- when Regexp, /^https?:\/\// then n
111
- when 'file://' then n
112
- when '*' then @public_resources = true; n
113
- else ["http://#{n}", "https://#{n}"]
228
+ when Regexp,
229
+ /^https?:\/\//,
230
+ 'file://' then n
231
+ when '*' then @public_resources = true; n
232
+ else Regexp.compile("^[a-z][a-z0-9.+-]*:\\\/\\\/#{Regexp.quote(n)}")
114
233
  end
115
234
  end.flatten
116
235
  @origins.push(blk) if blk
@@ -126,11 +245,14 @@ module Rack
126
245
 
127
246
  def allow_origin?(source,env = {})
128
247
  return true if public_resources?
248
+
249
+ effective_source = (source == 'null' ? 'file://' : source)
250
+
129
251
  return !! @origins.detect do |origin|
130
252
  if origin.is_a?(Proc)
131
253
  origin.call(source,env)
132
254
  else
133
- origin === source
255
+ origin === effective_source
134
256
  end
135
257
  end
136
258
  end
@@ -145,7 +267,7 @@ module Rack
145
267
 
146
268
  def initialize(public_resource, path, opts={})
147
269
  self.path = path
148
- self.methods = ensure_enum(opts[:methods]) || [:get]
270
+ self.methods = prepare_and_validate_methods_option(opts[:methods]) || [:get]
149
271
  self.credentials = opts[:credentials].nil? ? true : opts[:credentials]
150
272
  self.max_age = opts[:max_age] || 1728000
151
273
  self.pattern = compile(path)
@@ -173,7 +295,7 @@ module Rack
173
295
  def to_headers(env)
174
296
  x_origin = env['HTTP_ACCESS_CONTROL_REQUEST_HEADERS']
175
297
  h = {
176
- 'Access-Control-Allow-Origin' => origin_for_response_header(env['HTTP_ORIGIN']),
298
+ 'Access-Control-Allow-Origin' => origin_for_response_header(env[ORIGIN_HEADER_KEY]),
177
299
  'Access-Control-Allow-Methods' => methods.collect{|m| m.to_s.upcase}.join(', '),
178
300
  'Access-Control-Expose-Headers' => expose.nil? ? '' : expose.join(', '),
179
301
  'Access-Control-Max-Age' => max_age.to_s }
@@ -188,7 +310,7 @@ module Rack
188
310
 
189
311
  def origin_for_response_header(origin)
190
312
  return '*' if public_resource? && !credentials
191
- origin == 'file://' ? 'null' : origin
313
+ origin
192
314
  end
193
315
 
194
316
  def to_preflight_headers(env)
@@ -217,6 +339,11 @@ module Rack
217
339
  end
218
340
  end
219
341
 
342
+ def prepare_and_validate_methods_option setting
343
+ raise ArgumentError.new("rack-cors methods must be an single HTTP verb, or an array of verbs") if setting && setting == :any
344
+ ensure_enum setting
345
+ end
346
+
220
347
  def ensure_enum(v)
221
348
  return nil if v.nil?
222
349
  [v].flatten
@@ -1,5 +1,5 @@
1
1
  module Rack
2
2
  class Cors
3
- VERSION = "0.2.9"
3
+ VERSION = "0.3.0"
4
4
  end
5
5
  end
@@ -8,9 +8,9 @@ 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: http://github.com/cyu/rack-cors}
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}
12
12
  spec.summary = %q{Middleware for enabling Cross-Origin Resource Sharing in Rack apps}
13
- spec.homepage = "http://github.com/cyu/rack-cors"
13
+ spec.homepage = "https://github.com/cyu/rack-cors"
14
14
  spec.license = "MIT"
15
15
 
16
16
  spec.files = `git ls-files`.split($/).reject { |f| f == '.gitignore' or f =~ /^examples/ }
@@ -20,7 +20,7 @@ Gem::Specification.new do |spec|
20
20
 
21
21
  spec.add_development_dependency "bundler", "~> 1.3"
22
22
  spec.add_development_dependency "rake"
23
- spec.add_development_dependency "shoulda", ">= 0"
23
+ spec.add_development_dependency "minitest", ">= 5.3.0"
24
24
  spec.add_development_dependency "mocha", ">= 0.14.0"
25
25
  spec.add_development_dependency "rack-test", ">= 0"
26
26
  end
@@ -7,6 +7,26 @@ describe 'CORS', ->
7
7
  expect(data).to.eql('Hello world')
8
8
  done()
9
9
 
10
+ it 'should allow PUT access to dynamic resource', (done) ->
11
+ $.ajax("http://#{CORS_SERVER}/", type: 'PUT').done (data, textStatus, jqXHR) ->
12
+ expect(data).to.eql('Hello world')
13
+ done()
14
+
15
+ it 'should allow HEAD access to dynamic resource', (done) ->
16
+ $.ajax("http://#{CORS_SERVER}/", type: 'HEAD').done (data, textStatus, jqXHR) ->
17
+ expect(jqXHR.status).to.eql(200)
18
+ done()
19
+
20
+ it 'should allow DELETE access to dynamic resource', (done) ->
21
+ $.ajax("http://#{CORS_SERVER}/", type: 'DELETE').done (data, textStatus, jqXHR) ->
22
+ expect(data).to.eql('Hello world')
23
+ done()
24
+
25
+ it 'should allow OPTIONS access to dynamic resource', (done) ->
26
+ $.ajax("http://#{CORS_SERVER}/", type: 'OPTIONS').done (data, textStatus, jqXHR) ->
27
+ expect(jqXHR.status).to.eql(200)
28
+ done()
29
+
10
30
  it 'should allow access to static resource', (done) ->
11
31
  $.get "http://#{CORS_SERVER}/static.txt", (data, status, xhr) ->
12
32
  expect($.trim(data)).to.eql("hello world")
@@ -20,4 +40,3 @@ describe 'CORS', ->
20
40
  success:(data, status, xhr) ->
21
41
  expect($.trim(data)).to.eql("OK!")
22
42
  done()
23
-
@@ -1,3 +1,4 @@
1
+ // Generated by CoffeeScript 1.7.1
1
2
  (function() {
2
3
  var CORS_SERVER;
3
4
 
@@ -10,6 +11,38 @@
10
11
  return done();
11
12
  });
12
13
  });
14
+ it('should allow PUT access to dynamic resource', function(done) {
15
+ return $.ajax("http://" + CORS_SERVER + "/", {
16
+ type: 'PUT'
17
+ }).done(function(data, textStatus, jqXHR) {
18
+ expect(data).to.eql('Hello world');
19
+ return done();
20
+ });
21
+ });
22
+ it('should allow HEAD access to dynamic resource', function(done) {
23
+ return $.ajax("http://" + CORS_SERVER + "/", {
24
+ type: 'HEAD'
25
+ }).done(function(data, textStatus, jqXHR) {
26
+ expect(jqXHR.status).to.eql(200);
27
+ return done();
28
+ });
29
+ });
30
+ it('should allow DELETE access to dynamic resource', function(done) {
31
+ return $.ajax("http://" + CORS_SERVER + "/", {
32
+ type: 'DELETE'
33
+ }).done(function(data, textStatus, jqXHR) {
34
+ expect(data).to.eql('Hello world');
35
+ return done();
36
+ });
37
+ });
38
+ it('should allow OPTIONS access to dynamic resource', function(done) {
39
+ return $.ajax("http://" + CORS_SERVER + "/", {
40
+ type: 'OPTIONS'
41
+ }).done(function(data, textStatus, jqXHR) {
42
+ expect(jqXHR.status).to.eql(200);
43
+ return done();
44
+ });
45
+ });
13
46
  it('should allow access to static resource', function(done) {
14
47
  return $.get("http://" + CORS_SERVER + "/static.txt", function(data, status, xhr) {
15
48
  expect($.trim(data)).to.eql("hello world");
@@ -1,9 +1,9 @@
1
1
  require 'rubygems'
2
- require 'test/unit'
2
+ require 'minitest/autorun'
3
3
  require 'rack/test'
4
- require 'shoulda'
5
4
  require 'mocha/setup'
6
5
  require 'rack/cors'
6
+ require 'ostruct'
7
7
 
8
8
  Rack::Test::Session.class_eval do
9
9
  def options(uri, params = {}, env = {}, &block)
@@ -16,149 +16,231 @@ Rack::Test::Methods.class_eval do
16
16
  def_delegator :current_session, :options
17
17
  end
18
18
 
19
- class CorsTest < Test::Unit::TestCase
19
+ describe Rack::Cors do
20
20
  include Rack::Test::Methods
21
21
 
22
- def app
23
- eval "Rack::Builder.new {( " + File.read(File.dirname(__FILE__) + '/test.ru') + "\n )}"
22
+ attr_accessor :cors_result
23
+
24
+ def load_app(name)
25
+ test = self
26
+ Rack::Builder.new do
27
+ eval File.read(File.dirname(__FILE__) + "/#{name}.ru")
28
+ map('/') do
29
+ run proc { |env|
30
+ test.cors_result = env[Rack::Cors::ENV_KEY]
31
+ [200, {'Content-Type' => 'text/html'}, ['success']]
32
+ }
33
+ end
34
+ end
24
35
  end
25
36
 
26
- should('support simple cors request') { cors_request }
37
+ let(:app) { load_app('test') }
27
38
 
28
- should 'support OPTIONS cors request' do
39
+ it 'should support simple CORS request' do
40
+ cors_request
41
+ cors_result.must_be :hit
42
+ end
43
+
44
+ it "should not return CORS headers if Origin header isn't present" do
45
+ get '/'
46
+ should_render_cors_failure
47
+ cors_result.wont_be :hit
48
+ end
49
+
50
+ it 'should support OPTIONS CORS request' do
29
51
  cors_request '/options', :method => :options
30
52
  end
31
53
 
32
- should 'support regex origins configuration' do
54
+ it 'should support regex origins configuration' do
33
55
  cors_request :origin => 'http://192.168.0.1:1234'
34
56
  end
35
57
 
36
- should 'support proc origins configuration' do
58
+ it 'should support proc origins configuration' do
37
59
  cors_request '/proc-origin', :origin => 'http://10.10.10.10:3000'
38
60
  end
39
61
 
40
- should 'support alternative X-Origin header' do
62
+ it 'should support alternative X-Origin header' do
41
63
  header 'X-Origin', 'http://localhost:3000'
42
64
  get '/'
43
- assert_cors_success
65
+ should_render_cors_success
44
66
  end
45
67
 
46
- should 'support expose header configuration' do
68
+ it 'should support expose header configuration' do
47
69
  cors_request '/expose_single_header'
48
- assert_equal 'expose-test', last_response.headers['Access-Control-Expose-Headers']
70
+ last_response.headers['Access-Control-Expose-Headers'].must_equal 'expose-test'
49
71
  end
50
72
 
51
- should 'support expose multiple header configuration' do
73
+ it 'should support expose multiple header configuration' do
52
74
  cors_request '/expose_multiple_headers'
53
- assert_equal 'expose-test-1, expose-test-2', last_response.headers['Access-Control-Expose-Headers']
75
+ last_response.headers['Access-Control-Expose-Headers'].must_equal 'expose-test-1, expose-test-2'
54
76
  end
55
77
 
56
- should 'add Vary header if Access-Control-Allow-Origin header was added and if it is specific' do
78
+ it 'should add Vary header if Access-Control-Allow-Origin header was added and if it is specific' do
57
79
  cors_request '/', :origin => "http://192.168.0.3:8080"
58
- assert_cors_success
59
- assert_equal 'http://192.168.0.3:8080', last_response.headers['Access-Control-Allow-Origin']
60
- assert_not_nil last_response.headers['Vary'], 'missing Vary header'
80
+ last_response.headers['Access-Control-Allow-Origin'].must_equal 'http://192.168.0.3:8080'
81
+ last_response.headers['Vary'].wont_be_nil
61
82
  end
62
83
 
63
- should 'not add Vary header if Access-Control-Allow-Origin header was added and if it is generic (*)' do
84
+ it 'should not add Vary header if Access-Control-Allow-Origin header was added and if it is generic (*)' do
64
85
  cors_request '/public_without_credentials', :origin => "http://192.168.1.3:8080"
65
- assert_cors_success
66
- assert_equal '*', last_response.headers['Access-Control-Allow-Origin']
67
- assert_nil last_response.headers['Vary'], 'no expecting Vary header'
86
+ last_response.headers['Access-Control-Allow-Origin'].must_equal '*'
87
+ last_response.headers['Vary'].must_be_nil
68
88
  end
69
89
 
70
- should 'support multi allow configurations for the same resource' do
90
+ it 'should support multi allow configurations for the same resource' do
71
91
  cors_request '/multi-allow-config', :origin => "http://mucho-grande.com"
72
- assert_cors_success
73
- assert_equal 'http://mucho-grande.com', last_response.headers['Access-Control-Allow-Origin']
74
- assert_equal 'Origin', last_response.headers['Vary'], 'expecting Vary header'
92
+ last_response.headers['Access-Control-Allow-Origin'].must_equal 'http://mucho-grande.com'
93
+ last_response.headers['Vary'].must_equal 'Origin'
75
94
 
76
95
  cors_request '/multi-allow-config', :origin => "http://192.168.1.3:8080"
77
- assert_cors_success
78
- assert_equal '*', last_response.headers['Access-Control-Allow-Origin']
79
- assert_nil last_response.headers['Vary'], 'no expecting Vary header'
96
+ last_response.headers['Access-Control-Allow-Origin'].must_equal '*'
97
+ last_response.headers['Vary'].must_be_nil
80
98
  end
81
99
 
82
- should 'not log debug messages if debug option is false' do
83
- app = mock
84
- app.stubs(:call).returns(200, {}, [''])
100
+ it "should not return CORS headers on OPTIONS request if Access-Control-Allow-Origin is not present" do
101
+ options '/get-only'
102
+ last_response.headers['Access-Control-Allow-Origin'].must_be_nil
103
+ end
85
104
 
86
- logger = mock
87
- logger.expects(:debug).never
105
+ describe 'logging' do
106
+ it 'should not log debug messages if debug option is false' do
107
+ app = mock
108
+ app.stubs(:call).returns(200, {}, [''])
88
109
 
89
- cors = Rack::Cors.new(app, :debug => false, :logger => logger) {}
90
- cors.send(:debug, {}, 'testing')
91
- end
110
+ logger = mock
111
+ logger.expects(:debug).never
112
+
113
+ cors = Rack::Cors.new(app, :debug => false, :logger => logger) {}
114
+ cors.send(:debug, {}, 'testing')
115
+ end
116
+
117
+ it 'should log debug messages if debug option is true' do
118
+ app = mock
119
+ app.stubs(:call).returns(200, {}, [''])
120
+
121
+ logger = mock
122
+ logger.expects(:debug)
123
+
124
+ cors = Rack::Cors.new(app, :debug => true, :logger => logger) {}
125
+ cors.send(:debug, {}, 'testing')
126
+ end
127
+
128
+ it 'should use rack.logger if available' do
129
+ app = mock
130
+ app.stubs(:call).returns([200, {}, ['']])
131
+
132
+ logger = mock
133
+ logger.expects(:debug).at_least_once
92
134
 
93
- should 'log debug messages if debug option is true' do
94
- app = mock
95
- app.stubs(:call).returns(200, {}, [''])
135
+ cors = Rack::Cors.new(app, :debug => true) {}
136
+ cors.call({'rack.logger' => logger, 'HTTP_ORIGIN' => 'test.com'})
137
+ end
138
+
139
+ it 'should use logger proc' do
140
+ app = mock
141
+ app.stubs(:call).returns([200, {}, ['']])
142
+
143
+ logger = mock
144
+ logger.expects(:debug)
145
+
146
+ cors = Rack::Cors.new(app, :debug => true, :logger => proc { logger }) {}
147
+ cors.call({'HTTP_ORIGIN' => 'test.com'})
148
+ end
149
+
150
+ describe 'with Rails setup' do
151
+ after do
152
+ ::Rails.logger = nil if defined?(::Rails)
153
+ end
154
+
155
+ it 'should use Rails.logger if available' do
156
+ app = mock
157
+ app.stubs(:call).returns([200, {}, ['']])
158
+
159
+ logger = mock
160
+ logger.expects(:debug)
96
161
 
97
- logger = mock
98
- logger.expects(:debug)
162
+ ::Rails = OpenStruct.new(:logger => logger)
99
163
 
100
- cors = Rack::Cors.new(app, :debug => true, :logger => logger) {}
101
- cors.send(:debug, {}, 'testing')
164
+ cors = Rack::Cors.new(app, :debug => true) {}
165
+ cors.call({'HTTP_ORIGIN' => 'test.com'})
166
+ end
167
+ end
102
168
  end
103
169
 
104
- context 'preflight requests' do
105
- should 'fail if origin is invalid' do
170
+ describe 'preflight requests' do
171
+ it 'should fail if origin is invalid' do
106
172
  preflight_request('http://allyourdataarebelongtous.com', '/')
107
- assert_cors_failure
173
+ should_render_cors_failure
174
+ cors_result.wont_be :hit
175
+ cors_result.must_be :preflight
108
176
  end
109
177
 
110
- should 'fail if Access-Control-Request-Method is not allowed' do
178
+ it 'should fail if Access-Control-Request-Method is not allowed' do
111
179
  preflight_request('http://localhost:3000', '/get-only', :method => :post)
112
- assert_cors_failure
180
+ should_render_cors_failure
113
181
  end
114
182
 
115
- should 'fail if header is not allowed' do
183
+ it 'should fail if header is not allowed' do
116
184
  preflight_request('http://localhost:3000', '/single_header', :headers => 'Fooey')
117
- assert_cors_failure
185
+ should_render_cors_failure
118
186
  end
119
187
 
120
- should 'allow any header if headers = :any' do
188
+ it 'should allow any header if headers = :any' do
121
189
  preflight_request('http://localhost:3000', '/', :headers => 'Fooey')
122
- assert_cors_success
190
+ should_render_cors_success
123
191
  end
124
192
 
125
- should 'allow header case insensitive match' do
193
+ it 'should allow header case insensitive match' do
126
194
  preflight_request('http://localhost:3000', '/single_header', :headers => 'X-Domain-Token')
127
- assert_cors_success
195
+ should_render_cors_success
128
196
  end
129
197
 
130
- should 'allow multiple headers match' do
198
+ it 'should allow multiple headers match' do
131
199
  # Webkit style
132
200
  preflight_request('http://localhost:3000', '/two_headers', :headers => 'X-Requested-With, X-Domain-Token')
133
- assert_cors_success
201
+ should_render_cors_success
134
202
 
135
203
  # Gecko style
136
204
  preflight_request('http://localhost:3000', '/two_headers', :headers => 'x-requested-with,x-domain-token')
137
- assert_cors_success
205
+ should_render_cors_success
138
206
  end
139
207
 
140
- should '* origin should allow any origin' do
208
+ it 'should * origin should allow any origin' do
141
209
  preflight_request('http://locohost:3000', '/public')
142
- assert_cors_success
143
- assert_equal 'http://locohost:3000', last_response.headers['Access-Control-Allow-Origin']
210
+ should_render_cors_success
211
+ last_response.headers['Access-Control-Allow-Origin'].must_equal 'http://locohost:3000'
144
212
  end
145
213
 
146
- should '* origin should allow any origin, and set * if no credentials required' do
214
+ it 'should * origin should allow any origin, and set * if no credentials required' do
147
215
  preflight_request('http://locohost:3000', '/public_without_credentials')
148
- assert_cors_success
149
- assert_equal '*', last_response.headers['Access-Control-Allow-Origin']
216
+ should_render_cors_success
217
+ last_response.headers['Access-Control-Allow-Origin'].must_equal '*'
150
218
  end
151
219
 
152
- should '"null" origin, allowed as "file://", returned as "null" in header' do
220
+ it 'should "null" origin, allowed as "file://", returned as "null" in header' do
153
221
  preflight_request('null', '/')
154
- assert_cors_success
155
- assert_equal 'null', last_response.headers['Access-Control-Allow-Origin']
222
+ should_render_cors_success
223
+ last_response.headers['Access-Control-Allow-Origin'].must_equal 'null'
224
+ end
225
+
226
+ it 'should return "file://" as header with "file://" as origin' do
227
+ preflight_request('file://', '/')
228
+ should_render_cors_success
229
+ last_response.headers['Access-Control-Allow-Origin'].must_equal 'file://'
156
230
  end
157
231
 
158
- should 'return a Content-Type' do
232
+ it 'should return a Content-Type' do
159
233
  preflight_request('http://localhost:3000', '/')
160
- assert_cors_success
161
- assert_not_nil last_response.headers['Content-Type']
234
+ should_render_cors_success
235
+ last_response.headers['Content-Type'].wont_be_nil
236
+ end
237
+ end
238
+
239
+ describe "with non HTTP config" do
240
+ let(:app) { load_app("non_http") }
241
+
242
+ it 'should support non http/https origins' do
243
+ cors_request '/public', origin: 'content://com.company.app'
162
244
  end
163
245
  end
164
246
 
@@ -170,8 +252,8 @@ class CorsTest < Test::Unit::TestCase
170
252
  opts.merge! args.last if args.last.is_a?(Hash)
171
253
 
172
254
  header 'Origin', opts[:origin]
173
- current_session.__send__ opts[:method], path
174
- assert_cors_success
255
+ current_session.__send__ opts[:method], path, {}, test: self
256
+ should_render_cors_success
175
257
  end
176
258
 
177
259
  def preflight_request(origin, path, opts = {})
@@ -185,11 +267,11 @@ class CorsTest < Test::Unit::TestCase
185
267
  options path
186
268
  end
187
269
 
188
- def assert_cors_success
189
- assert_not_nil last_response.headers['Access-Control-Allow-Origin'], 'missing Access-Control-Allow-Origin header'
270
+ def should_render_cors_success
271
+ last_response.headers['Access-Control-Allow-Origin'].wont_be_nil
190
272
  end
191
273
 
192
- def assert_cors_failure
193
- assert_nil last_response.headers['Access-Control-Allow-Origin'], 'no expecting Access-Control-Allow-Origin header'
274
+ def should_render_cors_failure
275
+ last_response.headers['Access-Control-Allow-Origin'].must_be_nil
194
276
  end
195
277
  end
@@ -1,11 +1,10 @@
1
1
  require 'rubygems'
2
- require 'test/unit'
2
+ require 'minitest/autorun'
3
3
  require 'rack/cors'
4
- require 'shoulda'
5
4
 
6
5
 
7
- class DSLTest < Test::Unit::TestCase
8
- should 'support explicit config object dsl mode' do
6
+ describe Rack::Cors, 'DSL' do
7
+ it 'should support explicit config object dsl mode' do
9
8
  cors = Rack::Cors.new(Proc.new {}) do |cfg|
10
9
  cfg.allow do |allow|
11
10
  allow.origins 'localhost:3000', '127.0.0.1:3000' do |source,env|
@@ -17,15 +16,15 @@ class DSLTest < Test::Unit::TestCase
17
16
  end
18
17
  end
19
18
  resources = cors.send :all_resources
20
- assert_equal 1, resources.length
21
- assert resources.first.allow_origin?('http://localhost:3000')
22
19
 
23
- assert resources.first.allow_origin?('http://10.10.10.10:3000',{"USER_AGENT" => "test-agent" })
24
- assert !resources.first.allow_origin?('http://10.10.10.10:3001',{"USER_AGENT" => "test-agent" })
25
- assert !resources.first.allow_origin?('http://10.10.10.10:3000',{"USER_AGENT" => "other-agent"})
20
+ resources.length.must_equal 1
21
+ resources.first.allow_origin?('http://localhost:3000').must_equal true
22
+ resources.first.allow_origin?('http://10.10.10.10:3000',{"USER_AGENT" => "test-agent" }).must_equal true
23
+ resources.first.allow_origin?('http://10.10.10.10:3001',{"USER_AGENT" => "test-agent" }).wont_equal true
24
+ resources.first.allow_origin?('http://10.10.10.10:3000',{"USER_AGENT" => "other-agent"}).wont_equal true
26
25
  end
27
26
 
28
- should 'support implicit config object dsl mode' do
27
+ it 'should support implicit config object dsl mode' do
29
28
  cors = Rack::Cors.new(Proc.new {}) do
30
29
  allow do
31
30
  origins 'localhost:3000', '127.0.0.1:3000' do |source,env|
@@ -37,15 +36,15 @@ class DSLTest < Test::Unit::TestCase
37
36
  end
38
37
  end
39
38
  resources = cors.send :all_resources
40
- assert_equal 1, resources.length
41
- assert resources.first.allow_origin?('http://localhost:3000')
42
39
 
43
- assert resources.first.allow_origin?('http://10.10.10.10:3000',{"USER_AGENT" => "test-agent" })
44
- assert !resources.first.allow_origin?('http://10.10.10.10:3001',{"USER_AGENT" => "test-agent" })
45
- assert !resources.first.allow_origin?('http://10.10.10.10:3000',{"USER_AGENT" => "other-agent"})
40
+ resources.length.must_equal 1
41
+ resources.first.allow_origin?('http://localhost:3000').must_equal true
42
+ resources.first.allow_origin?('http://10.10.10.10:3000',{"USER_AGENT" => "test-agent" }).must_equal true
43
+ resources.first.allow_origin?('http://10.10.10.10:3001',{"USER_AGENT" => "test-agent" }).wont_equal true
44
+ resources.first.allow_origin?('http://10.10.10.10:3000',{"USER_AGENT" => "other-agent"}).wont_equal true
46
45
  end
47
46
 
48
- should 'support "file://" origin' do
47
+ it 'should support "file://" origin' do
49
48
  cors = Rack::Cors.new(Proc.new {}) do
50
49
  allow do
51
50
  origins 'file://'
@@ -53,6 +52,7 @@ class DSLTest < Test::Unit::TestCase
53
52
  end
54
53
  end
55
54
  resources = cors.send :all_resources
56
- assert resources.first.allow_origin?('file://')
55
+
56
+ resources.first.allow_origin?('file://').must_equal true
57
57
  end
58
58
  end
@@ -0,0 +1,8 @@
1
+ require 'rack/cors'
2
+
3
+ use Rack::Cors do
4
+ allow do
5
+ origins 'com.company.app'
6
+ resource '/public'
7
+ end
8
+ end
@@ -41,7 +41,3 @@ use Rack::Cors do
41
41
  resource '/multi-allow-config', :max_age => 300, :credentials => false
42
42
  end
43
43
  end
44
-
45
- map '/' do
46
- run Proc.new { |env| [200, {'Content-Type' => 'text/html'}, ['success']] }
47
- end
metadata CHANGED
@@ -1,97 +1,98 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rack-cors
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.9
4
+ version: 0.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Calvin Yu
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2013-11-12 00:00:00.000000000 Z
11
+ date: 2014-12-21 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
- - - ~>
17
+ - - "~>"
18
18
  - !ruby/object:Gem::Version
19
19
  version: '1.3'
20
20
  type: :development
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
- - - ~>
24
+ - - "~>"
25
25
  - !ruby/object:Gem::Version
26
26
  version: '1.3'
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: rake
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
- - - ! '>='
31
+ - - ">="
32
32
  - !ruby/object:Gem::Version
33
33
  version: '0'
34
34
  type: :development
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
- - - ! '>='
38
+ - - ">="
39
39
  - !ruby/object:Gem::Version
40
40
  version: '0'
41
41
  - !ruby/object:Gem::Dependency
42
- name: shoulda
42
+ name: minitest
43
43
  requirement: !ruby/object:Gem::Requirement
44
44
  requirements:
45
- - - ! '>='
45
+ - - ">="
46
46
  - !ruby/object:Gem::Version
47
- version: '0'
47
+ version: 5.3.0
48
48
  type: :development
49
49
  prerelease: false
50
50
  version_requirements: !ruby/object:Gem::Requirement
51
51
  requirements:
52
- - - ! '>='
52
+ - - ">="
53
53
  - !ruby/object:Gem::Version
54
- version: '0'
54
+ version: 5.3.0
55
55
  - !ruby/object:Gem::Dependency
56
56
  name: mocha
57
57
  requirement: !ruby/object:Gem::Requirement
58
58
  requirements:
59
- - - ! '>='
59
+ - - ">="
60
60
  - !ruby/object:Gem::Version
61
61
  version: 0.14.0
62
62
  type: :development
63
63
  prerelease: false
64
64
  version_requirements: !ruby/object:Gem::Requirement
65
65
  requirements:
66
- - - ! '>='
66
+ - - ">="
67
67
  - !ruby/object:Gem::Version
68
68
  version: 0.14.0
69
69
  - !ruby/object:Gem::Dependency
70
70
  name: rack-test
71
71
  requirement: !ruby/object:Gem::Requirement
72
72
  requirements:
73
- - - ! '>='
73
+ - - ">="
74
74
  - !ruby/object:Gem::Version
75
75
  version: '0'
76
76
  type: :development
77
77
  prerelease: false
78
78
  version_requirements: !ruby/object:Gem::Requirement
79
79
  requirements:
80
- - - ! '>='
80
+ - - ">="
81
81
  - !ruby/object:Gem::Version
82
82
  version: '0'
83
- description: ! 'Middleware that will make Rack-based apps CORS compatible. Read more
83
+ description: 'Middleware that will make Rack-based apps CORS compatible. Read more
84
84
  here: http://blog.sourcebender.com/2010/06/09/introducin-rack-cors.html. Fork the
85
- project here: http://github.com/cyu/rack-cors'
85
+ project here: https://github.com/cyu/rack-cors'
86
86
  email:
87
87
  - me@sourcebender.com
88
88
  executables: []
89
89
  extensions: []
90
90
  extra_rdoc_files: []
91
91
  files:
92
+ - CHANGELOG
92
93
  - Gemfile
93
94
  - LICENSE.txt
94
- - README.rdoc
95
+ - README.md
95
96
  - Rakefile
96
97
  - lib/rack/cors.rb
97
98
  - lib/rack/cors/version.rb
@@ -104,8 +105,9 @@ files:
104
105
  - test/cors/test.cors.js
105
106
  - test/unit/cors_test.rb
106
107
  - test/unit/dsl_test.rb
108
+ - test/unit/non_http.ru
107
109
  - test/unit/test.ru
108
- homepage: http://github.com/cyu/rack-cors
110
+ homepage: https://github.com/cyu/rack-cors
109
111
  licenses:
110
112
  - MIT
111
113
  metadata: {}
@@ -115,17 +117,17 @@ require_paths:
115
117
  - lib
116
118
  required_ruby_version: !ruby/object:Gem::Requirement
117
119
  requirements:
118
- - - ! '>='
120
+ - - ">="
119
121
  - !ruby/object:Gem::Version
120
122
  version: '0'
121
123
  required_rubygems_version: !ruby/object:Gem::Requirement
122
124
  requirements:
123
- - - ! '>='
125
+ - - ">="
124
126
  - !ruby/object:Gem::Version
125
127
  version: '0'
126
128
  requirements: []
127
129
  rubyforge_project:
128
- rubygems_version: 2.1.9
130
+ rubygems_version: 2.2.2
129
131
  signing_key:
130
132
  specification_version: 4
131
133
  summary: Middleware for enabling Cross-Origin Resource Sharing in Rack apps
@@ -138,4 +140,5 @@ test_files:
138
140
  - test/cors/test.cors.js
139
141
  - test/unit/cors_test.rb
140
142
  - test/unit/dsl_test.rb
143
+ - test/unit/non_http.ru
141
144
  - test/unit/test.ru
@@ -1,66 +0,0 @@
1
- = Rack CORS Middleware
2
-
3
- Rack::Cors provides support for Cross-Origin Resource Sharing (CORS) for Rack compatible web applications. The CORS spec allows web applications to make cross domain AJAX calls without
4
- using workarounds such as JSONP. For a thorough write up on CORS, see this blog post:
5
-
6
- http://www.nczonline.net/blog/2010/05/25/cross-domain-ajax-with-cross-origin-resource-sharing/
7
-
8
- Or for all the gory details, you can read the spec here:
9
-
10
- http://www.w3.org/TR/access-control/#simple-cross-origin-request-and-actual-r
11
-
12
-
13
- Install the gem:
14
-
15
- gem install rack-cors
16
-
17
- In your Gemfile:
18
-
19
- gem 'rack-cors', :require => 'rack/cors'
20
-
21
-
22
- == Configuration
23
-
24
- You configure Rack::Cors by passing a block to the <tt>use</tt> command:
25
-
26
- use Rack::Cors do
27
- allow do
28
- origins 'localhost:3000', '127.0.0.1:3000',
29
- /http:\/\/192\.168\.0\.\d{1,3}(:\d+)?/
30
- # regular expressions can be used here
31
-
32
- resource '/file/list_all/', :headers => 'x-domain-token'
33
- resource '/file/at/*',
34
- :methods => [:get, :post, :put, :delete, :options],
35
- :headers => 'x-domain-token',
36
- :expose => ['Some-Custom-Response-Header'],
37
- :max_age => 600
38
- # headers to expose
39
- end
40
-
41
- allow do
42
- origins '*'
43
- resource '/public/*', :headers => :any, :methods => :get
44
- end
45
- end
46
-
47
- Put your code in "config/application.rb" on your rails application. For example, this will allow
48
- from any origins on any resource of your application, methods :get, :post and :options.
49
-
50
- module YourApp
51
- class Application < Rails::Application
52
-
53
- # ...
54
-
55
- config.middleware.use Rack::Cors do
56
- allow do
57
- origins '*'
58
- resource '*', :headers => :any, :methods => [:get, :post, :options]
59
- end
60
- end
61
-
62
- end
63
- end
64
-
65
- See http://guides.rubyonrails.org/rails_on_rack.html for more details on rack middlewares or
66
- http://railscasts.com/episodes/151-rack-middleware.