quarkusio / quarkus

Quarkus: Supersonic Subatomic Java.
https://quarkus.io
Apache License 2.0
13.77k stars 2.68k forks source link

JAX-RS `@Produces` annotation gets ignored for `Response` objects #42729

Open overheadhunter opened 2 months ago

overheadhunter commented 2 months ago

Describe the bug

When a method returns a jakarta.ws.rs.core.Response object that does not explicitly set its mimetype, the method's @Produces annotation is ignored, potentially resulting in an incorrect mime type.

Expected behavior

testcode (see below) produces Content-Type: text/plain in http response

Actual behavior

testcode (see below) produces Content-Type: text/html in http response

How to Reproduce?

  1. in application.properties set a global default: quarkus.http.header."Content-Type".value=text/html
  2. add a JAX-RS method annotated with @Produces(MediaType.TEXT_PLAIN):
    @GET
    @Produces(MediaType.TEXT_PLAIN)
    @Path("/demo")
    public Response demo() {
        return Response.ok("Hello, World!").build();
    }
  3. GET it, pay attention to http response headers

Output of uname -a or ver

Darwin MacBook.local 23.6.0 Darwin Kernel Version 23.6.0: Mon Jul 29 21:14:30 PDT 2024; root:xnu-10063.141.2~1/RELEASE_ARM64_T6030 arm64

Output of java -version

openjdk version "21.0.3" 2024-04-16 LTS

Quarkus version or git rev

3.8.5

Build tool (ie. output of mvnw --version or gradlew --version)

Apache Maven 3.9.6 (bc0240f3c744dd6b6ec2920b3cd08dcc295161ae)

Additional information

Explicitly specifying the mime type in the Response builder mitigates the issue:

Response.ok("Hello, World!", MediaType.TEXT_PLAIN_TYPE).build();
gsmet commented 2 months ago

If you can prepare us a small Maven reproducer. That would be helpful.

(Typically we don’t know if you’re using Quarkus REST or RESTEasy Classic.

Thanks!

overheadhunter commented 2 months ago

Sure: https://github.com/overheadhunter/quarkus-issue-42729

Note that I used the Quarkus scaffolding tool, hence this is a different version than mentioned above. But the issue seems to persist in the latest version.

Apparently the content type header gets added twice in this minimal example. I am not sure what causes the wrong one to survive in a more complex scenario. Originally our downstream issue was also titled "duplicate content-type header".

One way or the other, the behaviour is odd.

geoand commented 2 months ago

I'm pretty sure this behavior in line with that the Jakarta REST spec says.

@FroMage do you remember perhaps?

FroMage commented 2 months ago

I don't think quarkus.http.header is mandated by the spec, I think it's our addition. Remains to be decided how precedence works then. Does the config override defaults? Does it override explicit overrides via annotations?

https://quarkus.io/guides/rest does not even mention quarkus.http.header and https://quarkus.io/guides/http-reference#additional-http-headers does not explain how it composes.