Fix issue with passed routes and provides #1095
Closed
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
This patch addresses an oddball issue that was the source of much hair-pulling this evening. Because the
provides
condition both branches on and mutatesresponse['Content-Type']
, a passed route with aprovides
condition can interfere with theprovides
condition of a later route (assuming both the initial and later routes match the requested path).Consider an example:
A
GET
request to/foo
with anAccept
header ofapplication/json,text/plain
will always return 404. Why? Because the compiledprovides
condition of the first route will setresponse['Content-Type']
toapplication/json
(here), and subsequent compiledprovides
conditions will short-circuit any attempts to re-examine the preferred types (here).Workarounds:
:provides
condition; instead, useSinatra::Request#preferred_type
to inspect theAccept
header on the request andSinatra::Base#content_type
to set theContent-Type
header on the response.params['captures']
(or a block parameter) instead of regular route parameters.request['Content-Type']
before callingpass
.Solutions:
request['Content-Type']
when throwing:pass
request['Content-Type']
when catching:pass
request['Content-Type']
in-between route iterations (maybe?)This patch implements solution 1 but I'm interested in your feedback.
Thank you in advance!