Improve MIME type subtype suffix handling

Prior to this commit, the subtype suffix of a MIME type (see RFC 6839)
was not properly taken into account when checking compatibility between
MIME types.

For example, `"application/*"` was not considered as compatible with
`"application/vnd.io.spring+json"`.

This commit adds a new `MimeType#getSubtypeSuffix()` method to easily
extract the subtype suffix information. This method is then reused in
the `isCompatibleWith` implementation to better handle these cases.

Fixes gh-25350
This commit is contained in:
Brian Clozel
2020-09-08 14:39:21 +02:00
parent 93f201a414
commit f7a014d7dc
2 changed files with 44 additions and 14 deletions

View File

@@ -284,6 +284,19 @@ public class MimeType implements Comparable<MimeType>, Serializable {
return this.subtype;
}
/**
* Return the subtype suffix as defined in RFC 6839.
* @since 5.3
*/
@Nullable
public String getSubtypeSuffix() {
int suffixIndex = this.subtype.lastIndexOf('+');
if (suffixIndex != -1 && this.subtype.length() > suffixIndex) {
return this.subtype.substring(suffixIndex + 1);
}
return null;
}
/**
* Return the character set, as indicated by a {@code charset} parameter, if any.
* @return the character set, or {@code null} if not available
@@ -377,22 +390,20 @@ public class MimeType implements Comparable<MimeType>, Serializable {
if (getSubtype().equals(other.getSubtype())) {
return true;
}
// Wildcard with suffix? e.g. application/*+xml
if (isWildcardSubtype() || other.isWildcardSubtype()) {
int thisPlusIdx = getSubtype().lastIndexOf('+');
int otherPlusIdx = other.getSubtype().lastIndexOf('+');
if (thisPlusIdx == -1 && otherPlusIdx == -1) {
String thisSuffix = getSubtypeSuffix();
String otherSuffix = other.getSubtypeSuffix();
if (getSubtype().equals(WILDCARD_TYPE)
|| other.getSubtype().equals(WILDCARD_TYPE)) {
return true;
}
else if (thisPlusIdx != -1 && otherPlusIdx != -1) {
String thisSubtypeNoSuffix = getSubtype().substring(0, thisPlusIdx);
String otherSubtypeNoSuffix = other.getSubtype().substring(0, otherPlusIdx);
String thisSubtypeSuffix = getSubtype().substring(thisPlusIdx + 1);
String otherSubtypeSuffix = other.getSubtype().substring(otherPlusIdx + 1);
if (thisSubtypeSuffix.equals(otherSubtypeSuffix) &&
(WILDCARD_TYPE.equals(thisSubtypeNoSuffix) || WILDCARD_TYPE.equals(otherSubtypeNoSuffix))) {
return true;
}
else if (isWildcardSubtype() && thisSuffix != null) {
return thisSuffix.equals(other.getSubtype())
|| thisSuffix.equals(otherSuffix);
}
else if (other.isWildcardSubtype() && otherSuffix != null) {
return this.getSubtype().equals(otherSuffix)
|| otherSuffix.equals(thisSuffix);
}
}
}