Render a redirect message as the plain text it claims to be - #2845
Open
ericproulx wants to merge 1 commit into
Open
Render a redirect message as the plain text it claims to be#2845ericproulx wants to merge 1 commit into
ericproulx wants to merge 1 commit into
Conversation
#redirect announces its message as text/plain and has done since it was
introduced in 2015 ("Redirect as plain text with optional message override"),
but it only set the header. The body was still handed to the API's own
formatter, so on a JSON API the sentence came back JSON-encoded:
format :json
get('/r') { redirect '/there' }
Content-Type: text/plain
"This resource has been moved temporarily to /there."
quotes included -- neither valid plain text nor something a client reading the
content type would expect. The existing specs missed it because they run on
the default :txt format, where the formatter is a no-op.
Set api.format alongside the header, the same lever an endpoint already has
via #api_format, so the message is rendered by the txt formatter whatever the
API declares. It is per-request env, so other routes on the same API are
untouched.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
ericproulx
force-pushed
the
fix/redirect-plain-text-body
branch
from
August 1, 2026 11:46
63cf9a3 to
4e7d9d5
Compare
Danger ReportNo issues found. |
4 tasks
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
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.
Summary
#redirectannounces its message astext/plain— and has since it was introduced in 2015, in a commit literally titled "Redirect as plain text with optional message override" — but it only ever set the header. The body was still handed to the API's own formatter:Quotes included. That is neither valid plain text nor what a client reading the content type would expect, and the header and body contradict each other.
format :jsontext/plain+"…moved temporarily to /there."(quoted)text/plain+…moved temporarily to /there.format :txtformat :xmlThe existing
#redirectspecs missed it because they run on the default:txtformat, where the formatter is a no-op.Approach
Set
api.formatalongside the header — the same lever an endpoint already has via#api_format(spec'd atapi_spec.rb:4494) — so the message is rendered by the txt formatter whatever the API declares.:txtis always resolvable:Grape::Formatter.formatter_forfalls back to the built-in registry, which is not narrowed by the API'sformat.It is per-request rack env, so other routes on the same API are unaffected — there is a spec pinning that.
Backward compatibility
No UPGRADING entry. The
Content-Typewas alreadytext/plain; only the body changes, and only for APIs whose format is not:txt— from an encoded form that contradicted the header to the plain text it always claimed to be. Redirect bodies are informational; clients followLocation.Longstanding rather than a regression: present since v0.14.0 (
d1bba79d, 2015) and identical in 3.3.4.Test plan
endpoint_spec.rbunder#redirect: plain-text body on a JSON API, an overridden body likewise, and a guard that other routes keep the API's format. Verified 2 of them fail without thelib/change.🤖 Generated with Claude Code