Skip to content

Commit c4e4f07

Browse files
author
Jeremy Steinberg
committed
Fix filters being called multiple times, consistent intialization for method_not_found errors
1 parent 5804b28 commit c4e4f07

File tree

4 files changed

+35
-18
lines changed

4 files changed

+35
-18
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

+2
Original file line numberDiff line numberDiff line change
@@ -248,6 +248,8 @@ def run
248248

249249
run_filters befores, :before
250250

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

253255
run_validators validations, request unless env[Grape::Env::GRAPE_METHOD_NOT_ALLOWED]

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
@@ -538,6 +538,36 @@ def subject.enable_root_route!
538538
expect(last_response.headers['X-Custom-Header']).to eql 'foo'
539539
end
540540

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

0 commit comments

Comments
 (0)