Skip to content

Commit

Permalink
Fix issue with passed routes and provides
Browse files Browse the repository at this point in the history
  • Loading branch information
mwpastore committed Feb 12, 2016
1 parent fdd17eb commit 8e84e0c
Show file tree
Hide file tree
Showing 2 changed files with 33 additions and 2 deletions.
13 changes: 11 additions & 2 deletions lib/sinatra/base.rb
Expand Up @@ -882,6 +882,7 @@ def initialize(app = nil)
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

Expand Down Expand Up @@ -956,15 +957,21 @@ def forward
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, keys, conditions, block|
@response['Content-Type'] = nil unless @pinned_response

returned_pass_block = process_route(pattern, keys, conditions) do |*args|
env['sinatra.route'] = block.instance_variable_get(:@route_name)
route_eval { block[*args] }
Expand Down Expand Up @@ -1080,7 +1087,9 @@ def invoke
def dispatch!
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
Expand Down
22 changes: 22 additions & 0 deletions test/routing_test.rb
Expand Up @@ -1063,6 +1063,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']

Expand Down

0 comments on commit 8e84e0c

Please sign in to comment.