support browser cors request
This commit is contained in:
@@ -9,14 +9,16 @@ module Middleware
|
|||||||
|
|
||||||
def call(env)
|
def call(env)
|
||||||
if allow_cors_for?(env)
|
if allow_cors_for?(env)
|
||||||
return preflight_response(env["HTTP_ORIGIN"]) if env["REQUEST_METHOD"] == "OPTIONS"
|
if env["REQUEST_METHOD"] == "OPTIONS"
|
||||||
|
return preflight_response(env["HTTP_ORIGIN"], allowed_request_headers(env))
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
status, headers, body = @app.call(env)
|
status, headers, body = @app.call(env)
|
||||||
if allow_cors_for?(env)
|
if allow_cors_for?(env)
|
||||||
apply_cors_headers(headers, env["HTTP_ORIGIN"])
|
apply_cors_headers(headers, env["HTTP_ORIGIN"])
|
||||||
end
|
end
|
||||||
[status, headers, body]
|
[ status, headers, body ]
|
||||||
end
|
end
|
||||||
|
|
||||||
private
|
private
|
||||||
@@ -25,25 +27,60 @@ module Middleware
|
|||||||
origin = env["HTTP_ORIGIN"].to_s
|
origin = env["HTTP_ORIGIN"].to_s
|
||||||
return false if origin.empty?
|
return false if origin.empty?
|
||||||
|
|
||||||
|
if env["REQUEST_METHOD"] == "OPTIONS"
|
||||||
|
return preflight_includes_app_id_header?(env)
|
||||||
|
end
|
||||||
|
|
||||||
app_id = env[APP_ID_HEADER].to_s
|
app_id = env[APP_ID_HEADER].to_s
|
||||||
return false if app_id.empty?
|
return false if app_id.empty?
|
||||||
|
|
||||||
app_id == ALLOWED_APP_ID
|
app_id == ALLOWED_APP_ID
|
||||||
end
|
end
|
||||||
|
|
||||||
def preflight_response(origin)
|
def preflight_includes_app_id_header?(env)
|
||||||
headers = {}
|
access_control_headers = env["HTTP_ACCESS_CONTROL_REQUEST_HEADERS"].to_s
|
||||||
apply_cors_headers(headers, origin)
|
return false if access_control_headers.empty?
|
||||||
headers["Access-Control-Max-Age"] = "86400"
|
|
||||||
[204, headers, []]
|
access_control_headers
|
||||||
|
.split(",")
|
||||||
|
.map { |header_name| header_name.strip.downcase }
|
||||||
|
.include?("x-sanasto-app")
|
||||||
end
|
end
|
||||||
|
|
||||||
def apply_cors_headers(headers, origin)
|
def allowed_request_headers(env)
|
||||||
|
access_control_headers = env["HTTP_ACCESS_CONTROL_REQUEST_HEADERS"].to_s
|
||||||
|
return default_allowed_headers if access_control_headers.empty?
|
||||||
|
|
||||||
|
sanitized = access_control_headers
|
||||||
|
.split(",")
|
||||||
|
.map { |header_name| header_name.strip }
|
||||||
|
.reject(&:empty?)
|
||||||
|
.join(", ")
|
||||||
|
|
||||||
|
sanitized.empty? ? default_allowed_headers : sanitized
|
||||||
|
end
|
||||||
|
|
||||||
|
def preflight_response(origin, allowed_headers)
|
||||||
|
headers = {}
|
||||||
|
apply_cors_headers(headers, origin, allowed_headers)
|
||||||
|
headers["Access-Control-Max-Age"] = "86400"
|
||||||
|
headers["Vary"] = [
|
||||||
|
headers["Vary"],
|
||||||
|
"Access-Control-Request-Headers",
|
||||||
|
"Access-Control-Request-Method"
|
||||||
|
].compact.join(", ")
|
||||||
|
[ 204, headers, [] ]
|
||||||
|
end
|
||||||
|
|
||||||
|
def apply_cors_headers(headers, origin, allowed_headers = default_allowed_headers)
|
||||||
headers["Access-Control-Allow-Origin"] = origin
|
headers["Access-Control-Allow-Origin"] = origin
|
||||||
headers["Access-Control-Allow-Methods"] = "GET, POST, PUT, PATCH, DELETE, OPTIONS"
|
headers["Access-Control-Allow-Methods"] = "GET, POST, PUT, PATCH, DELETE, OPTIONS"
|
||||||
headers["Access-Control-Allow-Headers"] =
|
headers["Access-Control-Allow-Headers"] = allowed_headers
|
||||||
|
headers["Vary"] = [ headers["Vary"], "Origin, X-Sanasto-App" ].compact.join(", ")
|
||||||
|
end
|
||||||
|
|
||||||
|
def default_allowed_headers
|
||||||
"Origin, Content-Type, Accept, Authorization, X-Sanasto-App"
|
"Origin, Content-Type, Accept, Authorization, X-Sanasto-App"
|
||||||
headers["Vary"] = [headers["Vary"], "Origin, X-Sanasto-App"].compact.join(", ")
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
Reference in New Issue
Block a user