Skip to content

Commit 855fd83

Browse files
committed
fix: return Access-Control-Allow-Headers=* for OPTIONS requests with no Access-Control-Request-Headers
Closes: pact-foundation/pact-js#195
1 parent db72b4d commit 855fd83

File tree

2 files changed

+74
-7
lines changed

2 files changed

+74
-7
lines changed

lib/pact/mock_service/request_handlers/options.rb

+19-7
Original file line numberDiff line numberDiff line change
@@ -7,32 +7,44 @@ class Options < BaseRequestHandler
77

88
attr_reader :name, :logger, :cors_enabled
99

10+
HTTP_ACCESS_CONTROL_REQUEST_METHOD = "HTTP_ACCESS_CONTROL_REQUEST_METHOD".freeze
11+
HTTP_ACCESS_CONTROL_REQUEST_HEADERS = "HTTP_ACCESS_CONTROL_REQUEST_HEADERS".freeze
12+
ACCESS_CONTROL_ALLOW_ORIGIN = "Access-Control-Allow-Origin".freeze
13+
ACCESS_CONTROL_ALLOW_METHODS = "Access-Control-Allow-Methods".freeze
14+
ACCESS_CONTROL_ALLOW_HEADERS = "Access-Control-Allow-Headers".freeze
15+
HTTP_ORIGIN = "HTTP_ORIGIN".freeze
16+
ALL_METHODS = "DELETE, POST, GET, HEAD, PUT, TRACE, CONNECT, PATCH".freeze
17+
REQUEST_METHOD = "REQUEST_METHOD".freeze
18+
OPTIONS = "OPTIONS".freeze
19+
X_PACT_MOCK_SERVICE_REGEXP = /x-pact-mock-service/i
20+
1021
def initialize name, logger, cors_enabled
1122
@name = name
1223
@logger = logger
1324
@cors_enabled = cors_enabled
1425
end
1526

1627
def match? env
17-
is_options_request?(env) && (cors_enabled || is_administration_request?(env))
28+
is_options_request?(env) && (cors_enabled || is_administration_request?(env))
1829
end
1930

2031
def respond env
2132
cors_headers = {
22-
'Access-Control-Allow-Origin' => env.fetch('HTTP_ORIGIN','*'),
23-
'Access-Control-Allow-Headers' => headers_from(env)["Access-Control-Request-Headers"],
24-
'Access-Control-Allow-Methods' => 'DELETE, POST, GET, HEAD, PUT, TRACE, CONNECT, PATCH'
33+
ACCESS_CONTROL_ALLOW_ORIGIN => env.fetch(HTTP_ORIGIN,'*'),
34+
ACCESS_CONTROL_ALLOW_HEADERS => env.fetch(HTTP_ACCESS_CONTROL_REQUEST_HEADERS, '*'),
35+
ACCESS_CONTROL_ALLOW_METHODS => ALL_METHODS
2536
}
26-
logger.info "Received OPTIONS request for mock service administration endpoint #{env['HTTP_ACCESS_CONTROL_REQUEST_METHOD']} #{env['PATH_INFO']}. Returning CORS headers: #{cors_headers.to_json}."
37+
38+
logger.info "Received OPTIONS request for mock service administration endpoint #{env[HTTP_ACCESS_CONTROL_REQUEST_METHOD]} #{env['PATH_INFO']}. Returning CORS headers: #{cors_headers}."
2739
[200, cors_headers, []]
2840
end
2941

3042
def is_options_request? env
31-
env['REQUEST_METHOD'] == 'OPTIONS'
43+
env[REQUEST_METHOD] == OPTIONS
3244
end
3345

3446
def is_administration_request? env
35-
(env["HTTP_ACCESS_CONTROL_REQUEST_HEADERS"] || '').match(/x-pact-mock-service/i)
47+
(env[HTTP_ACCESS_CONTROL_REQUEST_HEADERS] || '').match(X_PACT_MOCK_SERVICE_REGEXP)
3648
end
3749
end
3850
end
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
require 'pact/mock_service/request_handlers/options'
2+
3+
module Pact
4+
module MockService
5+
module RequestHandlers
6+
describe Options do
7+
subject { }
8+
9+
let(:logger) { Logger.new(StringIO.new) }
10+
let(:cors_enabled) { true }
11+
12+
describe "respond" do
13+
let(:response) { Options.new('provider', logger, cors_enabled).respond(env) }
14+
15+
describe "response headers" do
16+
let(:env) do
17+
{
18+
'HTTP_ORIGIN' => 'foo.com',
19+
'HTTP_ACCESS_CONTROL_REQUEST_HEADERS' => 'foo'
20+
}
21+
end
22+
23+
subject { response[1] }
24+
25+
it { is_expected.to include 'Access-Control-Allow-Methods' => 'DELETE, POST, GET, HEAD, PUT, TRACE, CONNECT, PATCH' }
26+
27+
context "with Origin" do
28+
it { is_expected.to include 'Access-Control-Allow-Origin' => 'foo.com' }
29+
end
30+
31+
context "with no Origin" do
32+
let(:env) { {} }
33+
34+
it { is_expected.to include 'Access-Control-Allow-Origin' => '*' }
35+
end
36+
37+
context "with no Access-Control-Request-Headers" do
38+
it { is_expected.to_not include 'Access-Control-Allow-Headers' => '*' }
39+
end
40+
41+
context "with Access-Control-Request-Headers" do
42+
it { is_expected.to include 'Access-Control-Allow-Headers' => 'foo' }
43+
end
44+
45+
context "with no Access-Control-Request-Headers" do
46+
let(:env) { {} }
47+
48+
it { is_expected.to include 'Access-Control-Allow-Headers' => '*' }
49+
end
50+
end
51+
end
52+
end
53+
end
54+
end
55+
end

0 commit comments

Comments
 (0)