Skip to content

Commit b13040b

Browse files
committed
Preserve Accept header order in Quarkus REST
Fixes: #51078
1 parent 583c6fa commit b13040b

File tree

3 files changed

+50
-19
lines changed

3 files changed

+50
-19
lines changed

independent-projects/resteasy-reactive/common/runtime/src/main/java/org/jboss/resteasy/reactive/common/headers/HeaderUtil.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -287,6 +287,9 @@ public static List<MediaType> getAcceptableMediaTypes(MultivaluedMap<String, ? e
287287
list.add(MediaTypeHelper.valueOf(accept.trim()));
288288
}
289289
}
290+
// Sort by weight (q) while preserving header-provided order on total ties
291+
// Keep the q parameter present for visibility (TCK expects it), but do not
292+
// rely on it downstream for matching; matching logic uses MediaTypeHelper.
290293
MediaTypeHelper.sortByWeight(list);
291294
return list;
292295
}

independent-projects/resteasy-reactive/common/runtime/src/main/java/org/jboss/resteasy/reactive/common/util/MediaTypeHelper.java

Lines changed: 0 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -127,25 +127,6 @@ public int compare(MediaType mediaType2, MediaType mediaType) {
127127
if (!isWildcardCompositeSubtype(mediaType.getSubtype()) && isWildcardCompositeSubtype(mediaType2.getSubtype()))
128128
return 1;
129129

130-
int numNonQ = 0;
131-
if (mediaType.getParameters() != null) {
132-
numNonQ = mediaType.getParameters().size();
133-
if (wasQ)
134-
numNonQ--;
135-
}
136-
137-
int numNonQ2 = 0;
138-
if (mediaType2.getParameters() != null) {
139-
numNonQ2 = mediaType2.getParameters().size();
140-
if (wasQ2)
141-
numNonQ2--;
142-
}
143-
144-
if (numNonQ < numNonQ2)
145-
return -1;
146-
if (numNonQ > numNonQ2)
147-
return 1;
148-
149130
return 0;
150131
}
151132
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
package org.jboss.resteasy.reactive.server.vertx.test.resource.basic;
2+
3+
import static io.restassured.RestAssured.given;
4+
import static org.junit.jupiter.api.Assertions.assertEquals;
5+
6+
import java.util.stream.Collectors;
7+
8+
import jakarta.ws.rs.GET;
9+
import jakarta.ws.rs.Path;
10+
import jakarta.ws.rs.core.Context;
11+
import jakarta.ws.rs.core.HttpHeaders;
12+
import jakarta.ws.rs.core.MediaType;
13+
14+
import org.jboss.resteasy.reactive.server.vertx.test.framework.ResteasyReactiveUnitTest;
15+
import org.jboss.shrinkwrap.api.ShrinkWrap;
16+
import org.jboss.shrinkwrap.api.spec.JavaArchive;
17+
import org.junit.jupiter.api.Test;
18+
import org.junit.jupiter.api.extension.RegisterExtension;
19+
20+
public class AcceptHeaderOrderTest {
21+
22+
@RegisterExtension
23+
static ResteasyReactiveUnitTest test = new ResteasyReactiveUnitTest()
24+
.setArchiveProducer(() -> ShrinkWrap.create(JavaArchive.class).addClasses(Resource.class));
25+
26+
@Path("/headers")
27+
public static class Resource {
28+
@GET
29+
@Path("/amt")
30+
public String amt(@Context HttpHeaders hs) {
31+
return hs.getAcceptableMediaTypes().stream().map(MediaType::toString).collect(Collectors.joining(","));
32+
}
33+
}
34+
35+
@Test
36+
public void preservesOrderOnTies() {
37+
String response = given()
38+
.header("Accept",
39+
"application/json,text/html; charset=UTF-8,text/plain; charset=UTF-8,*/*;q=0.8")
40+
.get("/headers/amt")
41+
.then()
42+
.statusCode(200)
43+
.extract()
44+
.asString();
45+
assertEquals("application/json,text/html;charset=UTF-8,text/plain;charset=UTF-8,*/*", response);
46+
}
47+
}

0 commit comments

Comments
 (0)