Skip to content

Commit 2cd43bb

Browse files
committed
Avoid multiple mount pollution
refs #2576 #1893 refs d29eb79
1 parent 2cbeeac commit 2cd43bb

File tree

3 files changed

+34
-33
lines changed

3 files changed

+34
-33
lines changed

lib/grape/api.rb

Lines changed: 2 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -22,14 +22,13 @@ class << self
2222
attr_accessor :base_instance, :instances
2323

2424
delegate_missing_to :base_instance
25-
def_delegators :base_instance, :new, :configuration
2625

2726
# This is the interface point between Rack and Grape; it accepts a request
2827
# from Rack and ultimately returns an array of three values: the status,
2928
# the headers, and the body. See [the rack specification]
30-
# (http://www.rubydoc.info/github/rack/rack/master/file/SPEC) for more.
29+
# (https://github.com/rack/rack/blob/main/SPEC.rdoc) for more.
3130
# NOTE: This will only be called on an API directly mounted on RACK
32-
def_delegators :instance_for_rack, :call, :compile!
31+
def_delegators :base_instance, :new, :configuration, :call, :compile!
3332

3433
# When inherited, will create a list of all instances (times the API was mounted)
3534
# It will listen to the setup required to mount that endpoint, and replicate it on any new instance
@@ -95,14 +94,6 @@ def replay_setup_on(instance)
9594
end
9695
end
9796

98-
def instance_for_rack
99-
if never_mounted?
100-
base_instance
101-
else
102-
mounted_instances.first
103-
end
104-
end
105-
10697
# Adds a new stage to the set up require to get a Grape::API up and running
10798
def add_setup(step)
10899
@setup << step

spec/grape/api_spec.rb

Lines changed: 0 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1055,28 +1055,6 @@ def to_txt
10551055
end
10561056
end
10571057

1058-
# NOTE: this method is required to preserve the ability of pre-mounting
1059-
# the root API into a namespace, it may be deprecated in the future.
1060-
describe 'instance_for_rack' do
1061-
context 'when the app was not mounted' do
1062-
it 'returns the base_instance' do
1063-
expect(app.__send__(:instance_for_rack)).to eq app.base_instance
1064-
end
1065-
end
1066-
1067-
context 'when the app was mounted' do
1068-
it 'returns the first mounted instance' do
1069-
mounted_app = app
1070-
Class.new(described_class) do
1071-
namespace 'new_namespace' do
1072-
mount mounted_app
1073-
end
1074-
end
1075-
expect(app.__send__(:instance_for_rack)).to eq app.__send__(:mounted_instances).first
1076-
end
1077-
end
1078-
end
1079-
10801058
describe 'filters' do
10811059
it 'adds a before filter' do
10821060
subject.before { @foo = 'first' }

spec/grape/integration/rack_spec.rb

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,4 +71,36 @@
7171
expect(last_response).to be_successful
7272
end
7373
end
74+
75+
# Regression test for issue #2576
76+
describe 'Rack interface and namespace pollution' do
77+
let(:api_class) do
78+
Class.new(Grape::API) do
79+
format :json
80+
version 'v1', using: :path
81+
82+
resource :system do
83+
get :ping do
84+
{ message: 'pong' }
85+
end
86+
end
87+
end
88+
end
89+
90+
# Issue #2576: Mounting under namespace must not pollute the mounted API
91+
it 'does not retain namespace after being mounted' do
92+
parent_api = Class.new(Grape::API) do
93+
format :json
94+
namespace '/api' do
95+
mount api_class
96+
end
97+
end
98+
99+
parent_api.call(Rack::MockRequest.env_for('/v1/api/system/ping', method: 'GET'))
100+
env = Rack::MockRequest.env_for('/v1/system/ping', method: 'GET')
101+
status, _headers, _body = api_class.call(env)
102+
103+
expect(status).to eq(200), 'Mounted API should not be polluted with parent namespace'
104+
end
105+
end
74106
end

0 commit comments

Comments
 (0)