diff --git a/CHANGELOG.md b/CHANGELOG.md index 1c5a3feb85..0177ac299b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -26,6 +26,7 @@ Next Release * [#503](/~https://github.com/intridea/grape/pull/503): Calling declared(params) from child namespace fails to include parent namespace defined params - [@myitcv](/~https://github.com/myitcv). * [#512](/~https://github.com/intridea/grape/pull/512): Don't create `Grape::Request` multiple times - [@dblock](/~https://github.com/dblock). * [#538](/~https://github.com/intridea/grape/pull/538): Fixed default values for grouped params - [@dm1try](/~https://github.com/dm1try). +* [#549](/~https://github.com/intridea/grape/pull/549): Fixed handling of invalid version headers to return 406 if a header cannot be parsed - [@bwalex](/~https://github.com/bwalex). 0.6.1 diff --git a/README.md b/README.md index 7ea79f1222..192bc1cf3b 100644 --- a/README.md +++ b/README.md @@ -231,6 +231,10 @@ supplied. This behavior is similar to routing in Rails. To circumvent this defau one could use the `:strict` option. When this option is set to `true`, a `406 Not Acceptable` error is returned when no correct `Accept` header is supplied. +When an invalid `Accept` header is supplied, a `406 Not Acceptable` error is returned if the `:cascade` +option is set to `false`. Otherwise a `404 Not Found` error is returned by Rack if no other route +matches. + ### Accept-Version Header ```ruby diff --git a/lib/grape/middleware/versioner/header.rb b/lib/grape/middleware/versioner/header.rb index 57124b2f33..231148f6c8 100644 --- a/lib/grape/middleware/versioner/header.rb +++ b/lib/grape/middleware/versioner/header.rb @@ -23,7 +23,11 @@ module Versioner # route. class Header < Base def before - header = Rack::Accept::MediaType.new env['HTTP_ACCEPT'] + begin + header = Rack::Accept::MediaType.new env['HTTP_ACCEPT'] + rescue RuntimeError => e + throw :error, status: 406, headers: error_headers, message: e.message + end if strict? # If no Accept header: diff --git a/spec/grape/endpoint_spec.rb b/spec/grape/endpoint_spec.rb index b225333112..16793a7b4d 100644 --- a/spec/grape/endpoint_spec.rb +++ b/spec/grape/endpoint_spec.rb @@ -732,4 +732,23 @@ def memoized end end + context 'version headers' do + before do + # NOTE: a 404 is returned instead of the 406 if cascade: false is not set. + subject.version 'v1', using: :header, vendor: 'ohanapi', cascade: false + subject.get '/test' do + "Hello!" + end + end + + it 'result in a 406 response if they are invalid' do + get '/test', {}, 'HTTP_ACCEPT' => 'application/vnd.ohanapi.v1+json' + last_response.status.should == 406 + end + + it 'result in a 406 response if they cannot be parsed by rack-accept' do + get '/test', {}, 'HTTP_ACCEPT' => 'application/vnd.ohanapi.v1+json; version=1' + last_response.status.should == 406 + end + end end