rack-cors 1.0.5 → 2.0.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +30 -0
- data/README.md +54 -35
- data/lib/rack/cors/resource.rb +142 -0
- data/lib/rack/cors/resources/cors_misconfiguration_error.rb +14 -0
- data/lib/rack/cors/resources.rb +62 -0
- data/lib/rack/cors/result.rb +63 -0
- data/lib/rack/cors/version.rb +3 -1
- data/lib/rack/cors.rb +105 -346
- metadata +52 -46
- data/.travis.yml +0 -8
- data/Gemfile +0 -6
- data/Rakefile +0 -21
- data/rack-cors.gemspec +0 -27
- data/test/cors/expect.js +0 -1286
- data/test/cors/mocha.css +0 -250
- data/test/cors/mocha.js +0 -5373
- data/test/cors/runner.html +0 -20
- data/test/cors/test.cors.coffee +0 -47
- data/test/cors/test.cors.js +0 -75
- data/test/unit/cors_test.rb +0 -522
- data/test/unit/dsl_test.rb +0 -69
- data/test/unit/insecure.ru +0 -8
- data/test/unit/non_http.ru +0 -8
- data/test/unit/test.ru +0 -62
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 14eb27e856c7cdd90b79cfc7236f3b71e10cfdcb2e282bb1a93546b8a97a053e
|
4
|
+
data.tar.gz: c9a2d87407a44c7df88129ece2d8ac5b8f5f6c46414b742c762d63cb99ae2278
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: e7a4136f89a39be61d5d1c7cdc1d5d4c85a883ee72f9a0f16c13fdd0218918d9c67a379974bae60271f3a7b1e2aebdaf8c187aa65c9e97b4d12427a9c606af60
|
7
|
+
data.tar.gz: a6798527bc3b3463f93d63bb42e901ff11de4512c63e10baf2ccb413526fff0cbee04bd9c2c38025b840c5ce9281fd60cd473d4dd0631a1cb6ba704d7d4d28f0
|
data/CHANGELOG.md
CHANGED
@@ -1,6 +1,36 @@
|
|
1
1
|
# Change Log
|
2
2
|
All notable changes to this project will be documented in this file.
|
3
3
|
|
4
|
+
## 2.0.2 - 2024-03-04
|
5
|
+
### Changed
|
6
|
+
- Fix file permission issues with 2.0.1 release
|
7
|
+
|
8
|
+
## 2.0.1 - 2023-02-17
|
9
|
+
### Changed
|
10
|
+
- Use Rack::Utils::HeaderHash when Rack 2.x is detected
|
11
|
+
|
12
|
+
## 2.0.0 - 2023-02-14
|
13
|
+
### Changed
|
14
|
+
- Refactored codebase
|
15
|
+
- Support declaring custom protocols in origin
|
16
|
+
- Lowercased header names as defined by Rack spec
|
17
|
+
- Fix issue with duplicate headers because of header name case
|
18
|
+
|
19
|
+
## 1.1.1 - 2019-12-29
|
20
|
+
### Changed
|
21
|
+
- Allow /<resource>/* to match /<resource>/ and /<resource> paths
|
22
|
+
|
23
|
+
## 1.1.0 - 2019-11-19
|
24
|
+
### Changed
|
25
|
+
- Use Rack::Utils.escape_path instead of Rack::Utils.escape
|
26
|
+
- Require Rack 2.0 for escape_path method
|
27
|
+
- Don't try to clean path if invalid.
|
28
|
+
- Return 400 (Bad Request) on preflights with invalid path
|
29
|
+
|
30
|
+
## 1.0.6 - 2019-11-14
|
31
|
+
### Changed
|
32
|
+
- Use Rack::Utils.escape to make compat with Rack 1.6.0
|
33
|
+
|
4
34
|
## 1.0.5 - 2019-11-14
|
5
35
|
### Changed
|
6
36
|
- Update Gem spec to require rack >= 1.6.0
|
data/README.md
CHANGED
@@ -1,8 +1,8 @@
|
|
1
|
-
# Rack CORS Middleware [![Build Status](https://
|
1
|
+
# Rack CORS Middleware [![Build Status](https://github.com/cyu/rack-cors/actions/workflows/ci.yaml/badge.svg)](https://github.com/cyu/rack-cors/actions)
|
2
2
|
|
3
3
|
`Rack::Cors` provides support for Cross-Origin Resource Sharing (CORS) for Rack compatible web applications.
|
4
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 [
|
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 [further explanations on MDN](https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS)
|
6
6
|
|
7
7
|
## Installation
|
8
8
|
|
@@ -20,41 +20,30 @@ gem 'rack-cors'
|
|
20
20
|
## Configuration
|
21
21
|
|
22
22
|
### Rails Configuration
|
23
|
-
|
23
|
+
For Rails, you'll need to add this middleware on application startup. A practical way to do this is with an initializer file. For example, the following will allow GET, POST, PATCH, or PUT requests from any origin on any resource:
|
24
24
|
|
25
25
|
```ruby
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
config.middleware.insert_before 0, Rack::Cors do
|
33
|
-
allow do
|
34
|
-
origins '*'
|
35
|
-
resource '*', headers: :any, methods: [:get, :post, :options]
|
36
|
-
end
|
37
|
-
end
|
38
|
-
|
39
|
-
# Rails 3/4
|
40
|
-
|
41
|
-
config.middleware.insert_before 0, "Rack::Cors" do
|
42
|
-
allow do
|
43
|
-
origins '*'
|
44
|
-
resource '*', headers: :any, methods: [:get, :post, :options]
|
45
|
-
end
|
46
|
-
end
|
26
|
+
# config/initializers/cors.rb
|
27
|
+
|
28
|
+
Rails.application.config.middleware.insert_before 0, Rack::Cors do
|
29
|
+
allow do
|
30
|
+
origins '*'
|
31
|
+
resource '*', headers: :any, methods: [:get, :post, :patch, :put]
|
47
32
|
end
|
48
33
|
end
|
49
34
|
```
|
50
35
|
|
51
|
-
|
36
|
+
NOTE: If you create application with `--api` option, configuration is automatically generated in `config/initializers/cors.rb`.
|
37
|
+
|
38
|
+
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). Basic setup examples for Rails 5 & Rails 6 can be found in the examples/ directory.
|
52
39
|
|
53
40
|
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).
|
54
41
|
|
42
|
+
Read more about it here in the [Rails Guides](https://guides.rubyonrails.org/configuring.html#configuring-middleware)
|
43
|
+
|
55
44
|
### Rack Configuration
|
56
45
|
|
57
|
-
NOTE: If you're running Rails,
|
46
|
+
NOTE: If you're running Rails, adding `config/initializers/cors.rb` should be enough. There is no need to update `config.ru` as well.
|
58
47
|
|
59
48
|
In `config.ru`, configure `Rack::Cors` by passing a block to the `use` command:
|
60
49
|
|
@@ -96,14 +85,14 @@ end
|
|
96
85
|
#### Origin
|
97
86
|
Origins can be specified as a string, a regular expression, or as '\*' to allow all origins.
|
98
87
|
|
99
|
-
**\*SECURITY NOTE:** Be careful when using regular expressions to not accidentally be too inclusive. For example, the expression `/https:\/\/example\.com/` will match the domain *example.com.randomdomainname.co.uk*. It is recommended that any regular expression be enclosed with start & end string anchors
|
88
|
+
**\*SECURITY NOTE:** Be careful when using regular expressions to not accidentally be too inclusive. For example, the expression `/https:\/\/example\.com/` will match the domain *example.com.randomdomainname.co.uk*. It is recommended that any regular expression be enclosed with start & end string anchors, like `\Ahttps:\/\/example\.com\z`.
|
100
89
|
|
101
90
|
Additionally, origins can be specified dynamically via a block of the following form:
|
102
91
|
```ruby
|
103
92
|
origins { |source, env| true || false }
|
104
93
|
```
|
105
94
|
|
106
|
-
A Resource path can be specified as exact string match (`/path/to/file.txt`) or with a '\*' wildcard (`/all/files/in/*`).
|
95
|
+
A Resource path can be specified as exact string match (`/path/to/file.txt`) or with a '\*' wildcard (`/all/files/in/*`). A resource can take the following options:
|
107
96
|
|
108
97
|
* **methods** (string or array or `:any`): The HTTP methods allowed for the resource.
|
109
98
|
* **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.
|
@@ -116,24 +105,54 @@ A Resource path can be specified as exact string match (`/path/to/file.txt`) or
|
|
116
105
|
|
117
106
|
## Common Gotchas
|
118
107
|
|
119
|
-
|
108
|
+
### Origin Matching
|
109
|
+
|
110
|
+
When specifying an origin, make sure that it does not have a trailing slash.
|
111
|
+
|
112
|
+
### Testing Postman and/or cURL
|
113
|
+
|
114
|
+
* Make sure you're passing in an `Origin:` header. That header is required to trigger a CORS response. Here's [a good SO post](https://stackoverflow.com/questions/12173990/how-can-you-debug-a-cors-request-with-curl) about using cURL for testing CORS.
|
115
|
+
* Make sure your origin does not have a trailing slash.
|
116
|
+
|
117
|
+
### Positioning in the Middleware Stack
|
118
|
+
|
119
|
+
Positioning of `Rack::Cors` in the middleware stack is very important. In the Rails example above we put it above all other middleware which, in our experience, provides the most consistent results.
|
120
120
|
|
121
|
-
Here are some
|
121
|
+
Here are some scenarios where incorrect positioning have created issues:
|
122
122
|
|
123
|
-
* **Serving static files.** Insert
|
123
|
+
* **Serving static files.** Insert before `ActionDispatch::Static` so that static files are served with the proper CORS headers. **NOTE:** this might not work in production as static files are usually served from the web server (Nginx, Apache) and not the Rails container.
|
124
124
|
|
125
|
-
* **Caching in the middleware.** Insert
|
125
|
+
* **Caching in the middleware.** Insert before `Rack::Cache` so that the proper CORS headers are written and not cached ones.
|
126
126
|
|
127
|
-
* **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.
|
127
|
+
* **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.
|
128
128
|
|
129
|
-
|
129
|
+
You can run the following command to see what the middleware stack looks like:
|
130
130
|
|
131
131
|
```bash
|
132
132
|
bundle exec rake middleware
|
133
133
|
```
|
134
134
|
|
135
|
-
|
135
|
+
Note that the middleware stack is different in production. For example, the `ActionDispatch::Static` middleware will not be part of the stack if `config.serve_static_assets = false`. You can run this to see what your middleware stack looks like in production:
|
136
136
|
|
137
137
|
```bash
|
138
138
|
RAILS_ENV=production bundle exec rake middleware
|
139
139
|
```
|
140
|
+
|
141
|
+
### Serving static files
|
142
|
+
|
143
|
+
If you trying to serve CORS headers on static assets (like CSS, JS, Font files), keep in mind that static files are usually served directly from web servers and never runs through the Rails container (including the middleware stack where `Rack::Cors` resides).
|
144
|
+
|
145
|
+
In Heroku, you can serve static assets through the Rails container by setting `config.serve_static_assets = true` in `production.rb`.
|
146
|
+
|
147
|
+
### Custom Protocols (chrome-extension://, ionic://, etc.)
|
148
|
+
|
149
|
+
Prior to 2.0.0, `http://`, `https://`, and `file://` are the only protocols supported in the `origins` list. If you wish to specify an origin that
|
150
|
+
has a custom protocol (`chrome-extension://`, `ionic://`, etc.) simply exclude the protocol. [See issue.](https://github.com/cyu/rack-cors/issues/100)
|
151
|
+
|
152
|
+
For example, instead of specifying `chrome-extension://aomjjhallfgjeglblehebfpbcfeobpga` specify `aomjjhallfgjeglblehebfpbcfeobpga` in `origins`.
|
153
|
+
|
154
|
+
As of 2.0.0 (currently in RC1), you can specify origins with a custom protocol.
|
155
|
+
|
156
|
+
### Rails 6 Host Matching
|
157
|
+
|
158
|
+
Rails 6 will block requests from unauthorized hosts, and this issue can be confused as a CORS related error. So in development, if you're making requests using something other than localhost or 127.0.0.1, make sure the server host has been authorized. [More info here](https://guides.rubyonrails.org/configuring.html#actiondispatch-hostauthorization)
|
@@ -0,0 +1,142 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Rack
|
4
|
+
class Cors
|
5
|
+
class Resource
|
6
|
+
# All CORS routes need to accept CORS simple headers at all times
|
7
|
+
# {https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Access-Control-Allow-Headers}
|
8
|
+
CORS_SIMPLE_HEADERS = %w[accept accept-language content-language content-type].freeze
|
9
|
+
|
10
|
+
attr_accessor :path, :methods, :headers, :expose, :max_age, :credentials, :pattern, :if_proc, :vary_headers
|
11
|
+
|
12
|
+
def initialize(public_resource, path, opts = {})
|
13
|
+
raise CorsMisconfigurationError if public_resource && opts[:credentials] == true
|
14
|
+
|
15
|
+
self.path = path
|
16
|
+
self.credentials = public_resource ? false : (opts[:credentials] == true)
|
17
|
+
self.max_age = opts[:max_age] || 7200
|
18
|
+
self.pattern = compile(path)
|
19
|
+
self.if_proc = opts[:if]
|
20
|
+
self.vary_headers = opts[:vary] && [opts[:vary]].flatten
|
21
|
+
@public_resource = public_resource
|
22
|
+
|
23
|
+
self.headers = case opts[:headers]
|
24
|
+
when :any then :any
|
25
|
+
when nil then nil
|
26
|
+
else
|
27
|
+
[opts[:headers]].flatten.collect(&:downcase)
|
28
|
+
end
|
29
|
+
|
30
|
+
self.methods = case opts[:methods]
|
31
|
+
when :any then %i[get head post put patch delete options]
|
32
|
+
else
|
33
|
+
ensure_enum(opts[:methods]) || [:get]
|
34
|
+
end.map(&:to_s)
|
35
|
+
|
36
|
+
self.expose = opts[:expose] ? [opts[:expose]].flatten : nil
|
37
|
+
end
|
38
|
+
|
39
|
+
def matches_path?(path)
|
40
|
+
pattern =~ path
|
41
|
+
end
|
42
|
+
|
43
|
+
def match?(path, env)
|
44
|
+
matches_path?(path) && (if_proc.nil? || if_proc.call(env))
|
45
|
+
end
|
46
|
+
|
47
|
+
def process_preflight(env, result)
|
48
|
+
headers = {}
|
49
|
+
|
50
|
+
request_method = env[Rack::Cors::HTTP_ACCESS_CONTROL_REQUEST_METHOD]
|
51
|
+
result.miss(Result::MISS_NO_METHOD) && (return headers) if request_method.nil?
|
52
|
+
result.miss(Result::MISS_DENY_METHOD) && (return headers) unless methods.include?(request_method.downcase)
|
53
|
+
|
54
|
+
request_headers = env[Rack::Cors::HTTP_ACCESS_CONTROL_REQUEST_HEADERS]
|
55
|
+
result.miss(Result::MISS_DENY_HEADER) && (return headers) if request_headers && !allow_headers?(request_headers)
|
56
|
+
|
57
|
+
result.hit = true
|
58
|
+
headers.merge(to_preflight_headers(env))
|
59
|
+
end
|
60
|
+
|
61
|
+
def to_headers(env)
|
62
|
+
h = {
|
63
|
+
'access-control-allow-origin' => origin_for_response_header(env[Rack::Cors::HTTP_ORIGIN]),
|
64
|
+
'access-control-allow-methods' => methods.collect { |m| m.to_s.upcase }.join(', '),
|
65
|
+
'access-control-expose-headers' => expose.nil? ? '' : expose.join(', '),
|
66
|
+
'access-control-max-age' => max_age.to_s
|
67
|
+
}
|
68
|
+
h['access-control-allow-credentials'] = 'true' if credentials
|
69
|
+
header_proc.call(h)
|
70
|
+
end
|
71
|
+
|
72
|
+
protected
|
73
|
+
|
74
|
+
def public_resource?
|
75
|
+
@public_resource
|
76
|
+
end
|
77
|
+
|
78
|
+
def origin_for_response_header(origin)
|
79
|
+
return '*' if public_resource?
|
80
|
+
|
81
|
+
origin
|
82
|
+
end
|
83
|
+
|
84
|
+
def to_preflight_headers(env)
|
85
|
+
h = to_headers(env)
|
86
|
+
h.merge!('access-control-allow-headers' => env[Rack::Cors::HTTP_ACCESS_CONTROL_REQUEST_HEADERS]) if env[Rack::Cors::HTTP_ACCESS_CONTROL_REQUEST_HEADERS]
|
87
|
+
h
|
88
|
+
end
|
89
|
+
|
90
|
+
def allow_headers?(request_headers)
|
91
|
+
headers = self.headers || []
|
92
|
+
return true if headers == :any
|
93
|
+
|
94
|
+
request_headers = request_headers.split(/,\s*/) if request_headers.is_a?(String)
|
95
|
+
request_headers.all? do |header|
|
96
|
+
header = header.downcase
|
97
|
+
CORS_SIMPLE_HEADERS.include?(header) || headers.include?(header)
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
101
|
+
def ensure_enum(var)
|
102
|
+
return nil if var.nil?
|
103
|
+
|
104
|
+
[var].flatten
|
105
|
+
end
|
106
|
+
|
107
|
+
def compile(path)
|
108
|
+
if path.respond_to? :to_str
|
109
|
+
special_chars = %w[. + ( ) $]
|
110
|
+
pattern =
|
111
|
+
path.to_str.gsub(%r{((:\w+)|/\*|[\*#{special_chars.join}])}) do |match|
|
112
|
+
case match
|
113
|
+
when '/*'
|
114
|
+
'\\/?(.*?)'
|
115
|
+
when '*'
|
116
|
+
'(.*?)'
|
117
|
+
when *special_chars
|
118
|
+
Regexp.escape(match)
|
119
|
+
else
|
120
|
+
'([^/?&#]+)'
|
121
|
+
end
|
122
|
+
end
|
123
|
+
/^#{pattern}$/
|
124
|
+
elsif path.respond_to? :match
|
125
|
+
path
|
126
|
+
else
|
127
|
+
raise TypeError, path
|
128
|
+
end
|
129
|
+
end
|
130
|
+
|
131
|
+
def header_proc
|
132
|
+
@header_proc ||= begin
|
133
|
+
if defined?(Rack::Headers)
|
134
|
+
->(h) { h }
|
135
|
+
else
|
136
|
+
->(h) { Rack::Utils::HeaderHash.new(h) }
|
137
|
+
end
|
138
|
+
end
|
139
|
+
end
|
140
|
+
end
|
141
|
+
end
|
142
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Rack
|
4
|
+
class Cors
|
5
|
+
class Resource
|
6
|
+
class CorsMisconfigurationError < StandardError
|
7
|
+
def message
|
8
|
+
'Allowing credentials for wildcard origins is insecure.' \
|
9
|
+
" Please specify more restrictive origins or set 'credentials' to false in your CORS configuration."
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
@@ -0,0 +1,62 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative 'resources/cors_misconfiguration_error'
|
4
|
+
|
5
|
+
module Rack
|
6
|
+
class Cors
|
7
|
+
class Resources
|
8
|
+
attr_reader :resources
|
9
|
+
|
10
|
+
def initialize
|
11
|
+
@origins = []
|
12
|
+
@resources = []
|
13
|
+
@public_resources = false
|
14
|
+
end
|
15
|
+
|
16
|
+
def origins(*args, &blk)
|
17
|
+
@origins = args.flatten.reject { |s| s == '' }.map do |n|
|
18
|
+
case n
|
19
|
+
when Proc, Regexp, %r{^[a-z][a-z0-9.+-]*://}
|
20
|
+
n
|
21
|
+
when '*'
|
22
|
+
@public_resources = true
|
23
|
+
n
|
24
|
+
else
|
25
|
+
Regexp.compile("^[a-z][a-z0-9.+-]*:\\\/\\\/#{Regexp.quote(n)}$")
|
26
|
+
end
|
27
|
+
end.flatten
|
28
|
+
@origins.push(blk) if blk
|
29
|
+
end
|
30
|
+
|
31
|
+
def resource(path, opts = {})
|
32
|
+
@resources << Resource.new(public_resources?, path, opts)
|
33
|
+
end
|
34
|
+
|
35
|
+
def public_resources?
|
36
|
+
@public_resources
|
37
|
+
end
|
38
|
+
|
39
|
+
def allow_origin?(source, env = {})
|
40
|
+
return true if public_resources?
|
41
|
+
|
42
|
+
!!@origins.detect do |origin|
|
43
|
+
if origin.is_a?(Proc)
|
44
|
+
origin.call(source, env)
|
45
|
+
elsif origin.is_a?(Regexp)
|
46
|
+
source =~ origin
|
47
|
+
else
|
48
|
+
source == origin
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
def match_resource(path, env)
|
54
|
+
@resources.detect { |r| r.match?(path, env) }
|
55
|
+
end
|
56
|
+
|
57
|
+
def resource_for_path(path)
|
58
|
+
@resources.detect { |r| r.matches_path?(path) }
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
@@ -0,0 +1,63 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Rack
|
4
|
+
class Cors
|
5
|
+
class Result
|
6
|
+
HEADER_KEY = 'x-rack-cors'
|
7
|
+
|
8
|
+
MISS_NO_ORIGIN = 'no-origin'
|
9
|
+
MISS_NO_PATH = 'no-path'
|
10
|
+
|
11
|
+
MISS_NO_METHOD = 'no-method'
|
12
|
+
MISS_DENY_METHOD = 'deny-method'
|
13
|
+
MISS_DENY_HEADER = 'deny-header'
|
14
|
+
|
15
|
+
attr_accessor :preflight, :hit, :miss_reason
|
16
|
+
|
17
|
+
def hit?
|
18
|
+
!!hit
|
19
|
+
end
|
20
|
+
|
21
|
+
def preflight?
|
22
|
+
!!preflight
|
23
|
+
end
|
24
|
+
|
25
|
+
def miss(reason)
|
26
|
+
self.hit = false
|
27
|
+
self.miss_reason = reason
|
28
|
+
end
|
29
|
+
|
30
|
+
def self.hit(env)
|
31
|
+
r = Result.new
|
32
|
+
r.preflight = false
|
33
|
+
r.hit = true
|
34
|
+
env[Rack::Cors::ENV_KEY] = r
|
35
|
+
end
|
36
|
+
|
37
|
+
def self.miss(env, reason)
|
38
|
+
r = Result.new
|
39
|
+
r.preflight = false
|
40
|
+
r.hit = false
|
41
|
+
r.miss_reason = reason
|
42
|
+
env[Rack::Cors::ENV_KEY] = r
|
43
|
+
end
|
44
|
+
|
45
|
+
def self.preflight(env)
|
46
|
+
r = Result.new
|
47
|
+
r.preflight = true
|
48
|
+
env[Rack::Cors::ENV_KEY] = r
|
49
|
+
end
|
50
|
+
|
51
|
+
def append_header(headers)
|
52
|
+
headers[HEADER_KEY] = if hit?
|
53
|
+
preflight? ? 'preflight-hit' : 'hit'
|
54
|
+
else
|
55
|
+
[
|
56
|
+
(preflight? ? 'preflight-miss' : 'miss'),
|
57
|
+
miss_reason
|
58
|
+
].join('; ')
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|