Skip to content

Commit 725c6cc

Browse files
committed
fix: correct logic for filtering ui/api requests
1 parent 3d5a538 commit 725c6cc

File tree

2 files changed

+42
-16
lines changed

2 files changed

+42
-16
lines changed

lib/rack/pact_broker/ui_request_filter.rb

+30-13
Original file line numberDiff line numberDiff line change
@@ -1,36 +1,53 @@
11
# Decides whether this is a request for the UI or a request for the API
2+
# This is only needed so that the correct authentication method is applied (UI or API auth)
23

34
module Rack
45
module PactBroker
56
class UIRequestFilter
7+
WEB_EXTENSIONS = %w[.js .woff .woff2 .css .png .html .map .ttf .ico].freeze
8+
API_CONTENT_TYPES = %w[application/hal+json application/json text/csv application/yaml].freeze
9+
610
def initialize app
711
@app = app
812
end
913

1014
def call env
11-
if request_for_ui_resource? env
12-
@app.call(env)
13-
else
15+
if request_for_api(env) || (accept_all(env) && !is_web_extension(env))
16+
# send the request on to the next app in the Rack::Cascade
1417
[404, {},[]]
18+
else
19+
@app.call(env)
1520
end
1621
end
1722

1823
private
1924

20-
def request_for_ui_resource? env
21-
request_for_file?(env) || accepts_html?(env)
25+
def body_is_json(env)
26+
env['CONTENT_TYPE'] && env['CONTENT_TYPE'].include?("json")
2227
end
2328

24-
def request_for_file?(env)
25-
if last_segment = env['PATH_INFO'].split("/").last
26-
last_segment.include?(".")
27-
else
28-
false
29-
end
29+
def request_for_api(env)
30+
accepts_api_content_type(env) || body_is_api_content_type(env)
31+
end
32+
33+
def accepts_api_content_type(env)
34+
is_api_content_type((env['HTTP_ACCEPT'] && env['HTTP_ACCEPT'].downcase) || "")
35+
end
36+
37+
def body_is_api_content_type(env)
38+
is_api_content_type((env['CONTENT_TYPE'] && env['CONTENT_TYPE'].downcase) || "")
39+
end
40+
41+
def is_api_content_type(header)
42+
API_CONTENT_TYPES.any?{ |content_type| header.include?(content_type) }
43+
end
44+
45+
def accept_all(env)
46+
env['HTTP_ACCEPT'] == "*/*"
3047
end
3148

32-
def accepts_html?(env)
33-
(env['HTTP_ACCEPT'] || '').include?("text/html")
49+
def is_web_extension(env)
50+
env['PATH_INFO'].end_with?(*WEB_EXTENSIONS)
3451
end
3552
end
3653
end

spec/lib/rack/pact_broker/ui_request_filter_spec.rb

+12-3
Original file line numberDiff line numberDiff line change
@@ -21,17 +21,26 @@ module PactBroker
2121
end
2222
end
2323

24-
context "when the request is for a file" do
24+
context "when the request is for a web file with an Accept header of */*" do
2525
let(:path) { "/blah/foo.css" }
26+
let(:accept) { "*/*" }
2627

2728
it "forwards the request to the target app" do
2829
expect(target_app).to receive(:call)
2930
subject
3031
end
3132
end
3233

33-
context "when the request is not for a file, and the Accept header does not include text/html" do
34-
let(:accept) { "application/hal+json, */*" }
34+
context "when the request is for a content type served by the API (HAL browser request)" do
35+
let(:accept) { "application/hal+json, application/json, */*; q=0.01" }
36+
37+
it "returns a 404" do
38+
expect(subject.status).to eq 404
39+
end
40+
end
41+
42+
context "when the request is for an API resource and the Accept headers is */* (default Accept header from curl request)" do
43+
let(:accept) { "*/*" }
3544

3645
it "returns a 404" do
3746
expect(subject.status).to eq 404

0 commit comments

Comments
 (0)