Skip to content

Commit 9194e1b

Browse files
authored
Merge pull request #1465 from jsteinberg/better-fix-method-not-allowed
Fix filters being called multiple times, consistent intialization for…
2 parents 7ce046d + 2d8ef47 commit 9194e1b

File tree

4 files changed

+37
-19
lines changed

4 files changed

+37
-19
lines changed

CHANGELOG.md

+1
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414

1515
#### Fixes
1616

17+
* [#1465](https://github.com/ruby-grape/grape/pull/1465): Fix 'before' being called twice when using not allowed method - [@jsteinberg](https://github.com/jsteinberg).
1718
* [#1446](https://github.com/ruby-grape/grape/pull/1446): Fix for `env` inside `before` when using not allowed method - [@leifg](https://github.com/leifg).
1819
* [#1438](https://github.com/ruby-grape/grape/pull/1439): Try to dup non-frozen default params with each use - [@jlfaber](https://github.com/jlfaber).
1920
* [#1430](https://github.com/ruby-grape/grape/pull/1430): Fix for `declared(params)` inside `route_param` - [@Arkanain](https://github.com/Arkanain).

lib/grape/endpoint.rb

+4-1
Original file line numberDiff line numberDiff line change
@@ -248,9 +248,12 @@ def run
248248

249249
run_filters befores, :before
250250

251+
allowed_methods = env[Grape::Env::GRAPE_METHOD_NOT_ALLOWED]
252+
raise Grape::Exceptions::MethodNotAllowed, header.merge('Allow' => allowed_methods) if allowed_methods
253+
251254
run_filters before_validations, :before_validation
252255

253-
run_validators validations, request unless env[Grape::Env::GRAPE_METHOD_NOT_ALLOWED]
256+
run_validators validations, request
254257

255258
run_filters after_validations, :after_validation
256259

lib/grape/router.rb

+2-18
Original file line numberDiff line numberDiff line change
@@ -133,24 +133,8 @@ def greedy_match?(input)
133133
end
134134

135135
def method_not_allowed(env, methods, endpoint)
136-
env[Grape::Env::GRAPE_METHOD_NOT_ALLOWED] = true
137-
current = endpoint.dup
138-
current.instance_eval do
139-
@env = env
140-
@header = {}
141-
142-
@request = Grape::Request.new(env)
143-
@params = @request.params
144-
@headers = @request.headers
145-
146-
@lazy_initialized = false
147-
lazy_initialize!
148-
run_filters befores, :before
149-
@block = proc do
150-
raise Grape::Exceptions::MethodNotAllowed, header.merge('Allow' => methods)
151-
end
152-
end
153-
current.call(env)
136+
env[Grape::Env::GRAPE_METHOD_NOT_ALLOWED] = methods
137+
endpoint.call(env)
154138
end
155139

156140
def cascade?(response)

spec/grape/api_spec.rb

+30
Original file line numberDiff line numberDiff line change
@@ -543,6 +543,36 @@ class DummyFormatClass
543543
expect(last_response.headers['X-Custom-Header']).to eql 'foo'
544544
end
545545

546+
it 'runs only the before filter on 405 bad method' do
547+
subject.namespace :example do
548+
before { header 'X-Custom-Header', 'foo' }
549+
before_validation { raise 'before_validation filter should not run' }
550+
after_validation { raise 'after_validation filter should not run' }
551+
after { raise 'after filter should not run' }
552+
get
553+
end
554+
555+
post '/example'
556+
expect(last_response.status).to eql 405
557+
expect(last_response.headers['X-Custom-Header']).to eql 'foo'
558+
end
559+
560+
it 'runs before filter exactly once on 405 bad method' do
561+
already_run = false
562+
subject.namespace :example do
563+
before do
564+
raise 'before filter ran twice' if already_run
565+
already_run = true
566+
header 'X-Custom-Header', 'foo'
567+
end
568+
get
569+
end
570+
571+
post '/example'
572+
expect(last_response.status).to eql 405
573+
expect(last_response.headers['X-Custom-Header']).to eql 'foo'
574+
end
575+
546576
context 'when format is xml' do
547577
it 'returns a 405 for an unsupported method' do
548578
subject.format :xml

0 commit comments

Comments
 (0)