diff --git a/lib/grape/endpoint.rb b/lib/grape/endpoint.rb index 358cb6a79c..dd07c3293f 100644 --- a/lib/grape/endpoint.rb +++ b/lib/grape/endpoint.rb @@ -52,7 +52,9 @@ def prepare_routes anchor = options[:route_options][:anchor] anchor = anchor.nil? ? true : anchor - path = compile_path(prepared_path, anchor && !options[:app]) + requirements = options[:route_options][:requirements] || {} + + path = compile_path(prepared_path, anchor && !options[:app], requirements) regex = Rack::Mount::RegexpWithNamedGroups.new(path) path_params = {} # named parameters in the api path @@ -91,9 +93,10 @@ def namespace Rack::Mount::Utils.normalize_path(settings.stack.map{|s| s[:namespace]}.join('/')) end - def compile_path(prepared_path, anchor = true) + def compile_path(prepared_path, anchor = true, requirements = {}) endpoint_options = {} endpoint_options[:version] = /#{settings[:version].join('|')}/ if settings[:version] + endpoint_options.merge!(requirements) Rack::Mount::Strexp.compile(prepared_path, endpoint_options, %w( / . ? ), anchor) end diff --git a/lib/grape/middleware/formatter.rb b/lib/grape/middleware/formatter.rb index 96547011a4..ce8827757b 100644 --- a/lib/grape/middleware/formatter.rb +++ b/lib/grape/middleware/formatter.rb @@ -42,13 +42,12 @@ def before def format_from_extension parts = request.path.split('.') - hit = parts.last.to_sym - - if parts.size <= 1 - nil - else - hit + extension = parts.last.to_sym + + if parts.size > 1 && content_types.key?(extension) + return extension end + nil end def format_from_header diff --git a/spec/grape/endpoint_spec.rb b/spec/grape/endpoint_spec.rb index 9ba79d51a3..d4b9beb1c4 100644 --- a/spec/grape/endpoint_spec.rb +++ b/spec/grape/endpoint_spec.rb @@ -107,7 +107,7 @@ def app; subject end ] end end - + describe '#params' do it 'should be available to the caller' do subject.get('/hey') do @@ -134,6 +134,42 @@ def app; subject end get '/location?location[city]=Dallas' last_response.body.should == 'Dallas' end + + context 'with special requirements' do + it 'should parse email param with provided requirements for params' do + subject.get('/:person_email', :requirements => { :person_email => /.*/ }) do + params[:person_email] + end + + get '/rodzyn@grape.com' + last_response.body.should == 'rodzyn@grape.com' + + get 'rodzyn@grape.com.pl' + last_response.body.should == 'rodzyn@grape.com.pl' + end + + it 'should parse many params with provided regexps' do + subject.get('/:person_email/test/:number', + :requirements => { + :person_email => /rodzyn@(.*).com/, + :number => /[0-9]/ }) do + params[:person_email] << params[:number] + end + + get '/rodzyn@grape.com/test/1' + last_response.body.should == 'rodzyn@grape.com1' + + get '/rodzyn@testing.wrong/test/1' + last_response.status.should == 404 + + get 'rodzyn@test.com/test/wrong_number' + last_response.status.should == 404 + + get 'rodzyn@test.com/wrong_middle/1' + last_response.status.should == 404 + + end + end end describe '#error!' do @@ -309,4 +345,4 @@ def memoized end end end -end +end \ No newline at end of file diff --git a/spec/grape/middleware/formatter_spec.rb b/spec/grape/middleware/formatter_spec.rb index 440c111650..0f030d387f 100644 --- a/spec/grape/middleware/formatter_spec.rb +++ b/spec/grape/middleware/formatter_spec.rb @@ -82,11 +82,6 @@ def to_xml subject.call({'PATH_INFO' => '/info.txt', 'HTTP_ACCEPT' => 'application/json'}) subject.env['api.format'].should == :txt end - - it 'should throw an error on an unrecognized format' do - err = catch(:error){ subject.call({'PATH_INFO' => '/info.barklar'}) } - err.should == {:status => 406, :message => "The requested format is not supported."} - end end context 'Accept header detection' do