Skip to content

Commit dd5bcd4

Browse files
authored
Ignore media ranges when parsing (#64721)
Browsers are sending media ranges with quality factors on Accept header. We should ignore the value and respond with applicaiton/json closes #64689 relates #51816
1 parent 9b07042 commit dd5bcd4

File tree

2 files changed

+21
-13
lines changed

2 files changed

+21
-13
lines changed

libs/x-content/src/main/java/org/elasticsearch/common/xcontent/ParsedMediaType.java

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -33,11 +33,6 @@
3333
* @see MediaTypeRegistry
3434
*/
3535
public class ParsedMediaType {
36-
// TODO this should be removed once strict parsing is implemented https://github.com/elastic/elasticsearch/issues/63080
37-
// sun.net.www.protocol.http.HttpURLConnection sets a default Accept header if it was not provided on a request.
38-
// For this value Parsing returns null.
39-
public static final String DEFAULT_ACCEPT_STRING = "text/html, image/gif, image/jpeg, *; q=.2, */*; q=.2";
40-
4136
private final String type;
4237
private final String subType;
4338
private final Map<String, String> parameters;
@@ -63,18 +58,19 @@ public Map<String, String> getParameters() {
6358

6459
/**
6560
* Parses a header value into it's parts.
66-
* follows https://tools.ietf.org/html/rfc7231#section-3.1.1.1 but allows only single media type and do not support quality factors
61+
* follows https://tools.ietf.org/html/rfc7231#section-3.1.1.1
62+
* but allows only single media type. Media ranges will be ignored (treated as not provided)
6763
* Note: parsing can return null, but it will throw exceptions once https://github.com/elastic/elasticsearch/issues/63080 is done
68-
* Do not rely on nulls
64+
* TODO Do not rely on nulls
6965
*
7066
* @return a {@link ParsedMediaType} if the header could be parsed.
7167
* @throws IllegalArgumentException if the header is malformed
7268
*/
7369
public static ParsedMediaType parseMediaType(String headerValue) {
74-
if (DEFAULT_ACCEPT_STRING.equals(headerValue) || "*/*".equals(headerValue)) {
75-
return null;
76-
}
7770
if (headerValue != null) {
71+
if (isMediaRange(headerValue) || "*/*".equals(headerValue)) {
72+
return null;
73+
}
7874
final String[] elements = headerValue.toLowerCase(Locale.ROOT).split("[\\s\\t]*;");
7975

8076
final String[] splitMediaType = elements[0].split("/");
@@ -107,6 +103,11 @@ public static ParsedMediaType parseMediaType(String headerValue) {
107103
return null;
108104
}
109105

106+
// simplistic check for media ranges. do not validate if this is a correct header
107+
private static boolean isMediaRange(String headerValue) {
108+
return headerValue.contains(",");
109+
}
110+
110111
private static boolean hasTrailingSpace(String s) {
111112
return s.length() == 0 || Character.isWhitespace(s.charAt(s.length()-1));
112113
}

libs/x-content/src/test/java/org/elasticsearch/common/xcontent/ParsedMediaTypeTests.java

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -111,14 +111,21 @@ public void testMalformedParameters() {
111111
expectThrows(IllegalArgumentException.class, () -> ParsedMediaType.parseMediaType(mediaType + ";k="));
112112
}
113113

114-
public void testDefaultAcceptHeader() {
114+
public void testIgnoredMediaTypes() {
115+
// When using curl */* is used a default Accept header when not specified by a user
116+
assertThat(ParsedMediaType.parseMediaType("*/*"), is(nullValue()));
117+
118+
115119
// This media type is defined in sun.net.www.protocol.http.HttpURLConnection as a default Accept header
116120
// and used when a header was not set on a request
117121
// It should be treated as if a user did not specify a header value
118122
String mediaType = "text/html, image/gif, image/jpeg, *; q=.2, */*; q=.2";
119123
assertThat(ParsedMediaType.parseMediaType(mediaType), is(nullValue()));
120124

121-
// When using curl */* is used a default Accept header when not specified by a user
122-
assertThat(ParsedMediaType.parseMediaType("*/*"), is(nullValue()));
125+
//example accept header used by a browser
126+
mediaType = "text/html,application/xhtml+xml,application/xml;q=0.9," +
127+
"image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9";
128+
ParsedMediaType parsedMediaType = ParsedMediaType.parseMediaType(mediaType);
129+
assertThat(parsedMediaType, equalTo(null));
123130
}
124131
}

0 commit comments

Comments
 (0)