diff --git a/CHANGES b/CHANGES index b26530f3..eb736710 100644 --- a/CHANGES +++ b/CHANGES @@ -5,6 +5,9 @@ * Add :status option support to send_file. (Konstantin Haase) + * The `provides` condition now respects an earlier set content type. + (Konstantin Haase) + * Exception#code is only used when :use_code is enabled and displays a warning. Moreover, it will be ignored if the value is not between 400 and 599. You should use Exception#http_status instead. (Konstantin Haase) diff --git a/lib/sinatra/base.rb b/lib/sinatra/base.rb index 11fd038e..4770ce90 100644 --- a/lib/sinatra/base.rb +++ b/lib/sinatra/base.rb @@ -1163,7 +1163,9 @@ module Sinatra types.map! { |t| mime_types(t) } types.flatten! condition do - if type = request.preferred_type(types) + if type = response['Content-Type'] + types.include? type or types.include? type[/^[^;]+/] + elsif type = request.preferred_type(types) content_type(type) true else diff --git a/test/filter_test.rb b/test/filter_test.rb index fd9958d6..534fd5ff 100644 --- a/test/filter_test.rb +++ b/test/filter_test.rb @@ -425,4 +425,15 @@ class AfterFilterTest < Test::Unit::TestCase get '/foo', {}, { 'HTTP_USER_AGENT' => 'foo' } assert ran end + + it 'only triggeres provides condition if conforms with current Content-Type' do + mock_app do + before(:provides => :txt) { @type = 'txt' } + before(:provides => :html) { @type = 'html' } + get('/') { @type } + end + + get '/', {}, { 'HTTP_ACCEPT' => '*' } + assert_body 'txt' + end end diff --git a/test/routing_test.rb b/test/routing_test.rb index e3f4d0be..28541ad9 100644 --- a/test/routing_test.rb +++ b/test/routing_test.rb @@ -718,6 +718,31 @@ class RoutingTest < Test::Unit::TestCase assert !ok? end + it "filters by current Content-Type" do + mock_app do + before('/txt') { content_type :txt } + get('*', :provides => :txt) { 'txt' } + + before('/html') { content_type :html } + get('*', :provides => :html) { 'html' } + end + + get '/', {}, { 'HTTP_ACCEPT' => '*' } + assert ok? + assert_equal 'text/plain;charset=utf-8', response.headers['Content-Type'] + assert_body 'txt' + + get '/txt', {}, { 'HTTP_ACCEPT' => 'text/plain' } + assert ok? + assert_equal 'text/plain;charset=utf-8', response.headers['Content-Type'] + assert_body 'txt' + + get '/', {}, { 'HTTP_ACCEPT' => 'text/html' } + assert ok? + assert_equal 'text/html;charset=utf-8', response.headers['Content-Type'] + assert_body 'html' + end + it "allows multiple mime types for accept header" do types = ['image/jpeg', 'image/pjpeg']