res.redirect() throws Not Acceptable when client doesn’t accept text/html or text/plain
Describe the bug
res.redirect() uses formatResponse() to try and return an appropriate response based on the Accept header. However, it should be expected that not all requests will be from a browser, and some clients may supply an Accept header where no text/ mime types or */* wildcard are declared.
In our case, we’re finding that a mobile app client sends requests with an Accept header containing only image/ mime types, causing tinyhttp to throw “Not Acceptable” and return a malformed response where the Location header is set, yet the status code is 406. This is despite that the response would have been accepted by the client if it were returned with a 30x status code.
To Reproduce
Steps to reproduce the behavior:
- Run a server with:
app.get("/", (req, res) => {
res.redirect("/awesome");
});
- Test it with:
curl -i localhost:3000
curl -i localhost:3000 -H 'Accept: text/html'
curl -i localhost:3000 -H 'Accept: image/heic,image/webp'
Expected behavior
Example 1: Returns 302 with body Found. Redirecting to /awesome
Example 2: Returns 302 with body <p>Found. Redirecting to <a href="/awesome">/awesome</a></p>
Example 3: Returns 302 with no body (or just the plain body) because no supported types were listed
Versions
-
node: 16.14.0 -
@tinyhttp/app: 2.0.16
Additional context
None
would you like to submit a PR to fix this? (and a little test too)
Hey @talentlessguy, I'd like to give it a shot, can you assign it to me?
@xanaDev done