Fix issue with passed routes and provides (#1606)

This commit is contained in:
Jordan Owens 2020-03-16 15:18:58 -04:00 committed by GitHub
parent 00bdf4faee
commit ecf687d9f1
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 33 additions and 2 deletions

View File

@ -924,6 +924,7 @@ module Sinatra
super()
@app = app
@template_cache = Tilt::Cache.new
@pinned_response = nil # whether a before! filter pinned the content-type
yield self if block_given?
end
@ -997,15 +998,21 @@ module Sinatra
private
# Run filters defined on the class and all superclasses.
# Accepts an optional block to call after each filter is applied.
def filter!(type, base = settings)
filter! type, base.superclass if base.superclass.respond_to?(:filters)
base.filters[type].each { |args| process_route(*args) }
base.filters[type].each do |args|
result = process_route(*args)
yield result if block_given?
end
end
# Run routes defined on the class and all superclasses.
def route!(base = settings, pass_block = nil)
if routes = base.routes[@request.request_method]
routes.each do |pattern, conditions, block|
@response['Content-Type'] = nil unless @pinned_response
returned_pass_block = process_route(pattern, conditions) do |*args|
env['sinatra.route'] = "#{@request.request_method} #{pattern}"
route_eval { block[*args] }
@ -1121,7 +1128,9 @@ module Sinatra
invoke do
static! if settings.static? && (request.get? || request.head?)
filter! :before
filter! :before do
@pinned_response = !@response['Content-Type'].nil?
end
route!
end
rescue ::Exception => boom

View File

@ -1212,6 +1212,28 @@ class RoutingTest < Minitest::Test
assert_body 'html'
end
it "doesn't allow provides of passed routes to interfere with provides of other routes" do
mock_app do
get('/:foo', :provides => :txt) do
pass if params[:foo] != 'foo'
'foo'
end
get('/bar', :provides => :html) { 'bar' }
end
get '/foo', {}, { 'HTTP_ACCEPT' => '*/*' }
assert ok?
assert_equal 'text/plain;charset=utf-8', response.headers['Content-Type']
assert_body 'foo'
get '/bar', {}, { 'HTTP_ACCEPT' => '*/*' }
assert ok?
assert_equal 'text/html;charset=utf-8', response.headers['Content-Type']
assert_body 'bar'
end
it "allows multiple mime types for accept header" do
types = ['image/jpeg', 'image/pjpeg']