Closed vmmello closed 3 months ago
I don't quite see the bug i'm afraid, the logic seems to follow the documentation in the precedence order it is described. https://docs.mojolicious.org/Mojolicious/Guides/Rendering#Content-negotiation
From the documentation you pointed, I imagine you're referring to this phrase as the precedence order:
The best possible representation will be automatically selected from the _format GET/POST parameter,
format stash value or Accept request header and stored in the format stash value.
If so, ok, it looks like the correct behavior.
But then, what would be the correct way to change a single endpoint to a fallback response format using content negotiation? (it seems to me that Accept: */*
header doesn't match the any
format).
I'm trying to change the default response type of an endpoint to
text/plain
, so that when a user runscurl /
and the app receives the headerAccept: */*
it will reply with atxt
, not html.A simplified sample code of how I'm trying it:
The above looks right to me. But it completely breaks content negotiation, replying all requests with the default format. For example, when running:
$ ./app.pl get -H 'Accept: text/html' /
$ ./app.pl get -H 'Accept: application/json' /
But if I remove the
txt => {}
line (line 4) fromrespond_to()
, lettingtext/plain
be catched by theany
format, it works as expected (i.e. content negotiation throughAccept
header works, and it correctly fallsback unknowns totxt
format). If I omit theany
format it replies with204 No Content
fortxt
and other formats (other than the ones listed inrespond_to()
).So I believe this is a subtle bug in content negotiation, the fact that when you explicitly specify a default format and include it in a
respond_to()
method call, it breaks content negotiation through theAccept
header.This same problem happens when the default format is explicitly specified as
html
, e.g.:get '/' => { format => "html" } => sub { ... };
so it's not the case of changing the response format to something other thanhtml
.