Fix issue with passed routes and provides #1097
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.
GitHub won't let me reopen #1095, so this replaces that PR.
This patch addresses an oddball issue. 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
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:
Clearrequest['Content-Type']
when throwing or catching:pass
Clearrequest['Content-Type']
in-between route iterations (calls toprocess_route
)It seems as though "pinning" the Content-Type of the response in
before
filters is a documented (or at least test-driven) feature, so clearing the Content-Type in-between calls toprocess_route
or while throwing or catching apass
is not a solution to this problem.This PR implements a compromise solution where if the Content-Type is set while the
before
filters are being applied, use it as the Content-Type of the response (i.e. it becomes a route selector), otherwise clear the Content-Type in-between calls toprocess_route
.