Skip to content

Commit 0660ae7

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

File tree

4 files changed

+36
-33
lines changed

4 files changed

+36
-33
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
* [#2605](https://github.com/ruby-grape/grape/pull/2605): Add Rack 3.2 support with new gemfile and CI integration - [@ericproulx](https://github.com/ericproulx).
2222
* [#2607](https://github.com/ruby-grape/grape/pull/2607): Remove namespace_stackable and namespace_inheritable from public API - [@ericproulx](https://github.com/ericproulx).
2323
* Your contribution here.
24+
* [#2612](https://github.com/ruby-grape/grape/pull/2612): Avoid multiple mount pollution - [@alexanderadam](https://github.com/alexanderadam).
2425

2526
#### Fixes
2627

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: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,4 +71,37 @@
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+
it 'does not retain namespace after being mounted' do
91+
api_to_mount = api_class
92+
93+
parent_api = Class.new(Grape::API) do
94+
format :json
95+
namespace '/api' do
96+
mount api_to_mount
97+
end
98+
end
99+
100+
parent_api.call(Rack::MockRequest.env_for('/v1/api/system/ping', method: 'GET'))
101+
env = Rack::MockRequest.env_for('/v1/system/ping', method: 'GET')
102+
status, _headers, _body = api_class.call(env)
103+
104+
expect(status).to eq(200), 'Mounted API should not be polluted with parent namespace'
105+
end
106+
end
74107
end

0 commit comments

Comments
 (0)