Skip to content

Commit e51e83c

Browse files
committed
Preserve Accept header order in Quarkus REST
Fixes: quarkusio#51078
1 parent 7e5adfb commit e51e83c

File tree

3 files changed

+64
-19
lines changed

3 files changed

+64
-19
lines changed

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

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -287,7 +287,24 @@ 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
290291
MediaTypeHelper.sortByWeight(list);
292+
293+
// The returned acceptable media types must not include the quality factor parameter ("q").
294+
// Strip any present "q" from the parameters while keeping other parameters (e.g., charset).
295+
for (int i = 0; i < list.size(); i++) {
296+
MediaType mt = list.get(i);
297+
Map<String, String> params = mt.getParameters();
298+
if (params != null && params.containsKey("q")) {
299+
if (params.size() == 1) {
300+
list.set(i, new MediaType(mt.getType(), mt.getSubtype()));
301+
} else {
302+
Map<String, String> copy = new java.util.LinkedHashMap<>(params);
303+
copy.remove("q");
304+
list.set(i, new MediaType(mt.getType(), mt.getSubtype(), copy));
305+
}
306+
}
307+
}
291308
return list;
292309
}
293310

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)