Browse Source

Merge pull request #2010 from dimitrisli/SPR-17459

pull/2017/head
Rossen Stoyanchev 6 years ago
parent
commit
7bbd4c681f
  1. 49
      spring-core/src/main/java/org/springframework/util/MimeTypeUtils.java
  2. 20
      spring-core/src/test/java/org/springframework/util/MimeTypeTests.java
  3. 10
      spring-web/src/main/java/org/springframework/http/MediaType.java

49
spring-core/src/main/java/org/springframework/util/MimeTypeUtils.java

@ -28,6 +28,7 @@ import java.util.LinkedHashMap; @@ -28,6 +28,7 @@ import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Random;
import java.util.stream.Collectors;
import org.springframework.lang.Nullable;
import org.springframework.util.MimeType.SpecificityComparator;
@ -37,6 +38,7 @@ import org.springframework.util.MimeType.SpecificityComparator; @@ -37,6 +38,7 @@ import org.springframework.util.MimeType.SpecificityComparator;
*
* @author Arjen Poutsma
* @author Rossen Stoyanchev
* @author Dimitrios Liapis
* @since 4.0
*/
public abstract class MimeTypeUtils {
@ -248,21 +250,54 @@ public abstract class MimeTypeUtils { @@ -248,21 +250,54 @@ public abstract class MimeTypeUtils {
}
/**
* Parse the given, comma-separated string into a list of {@code MimeType} objects.
* Parse the comma-separated string into a list of {@code MimeType} objects.
* @param mimeTypes the string to parse
* @return the list of mime types
* @throws IllegalArgumentException if the string cannot be parsed
* @throws InvalidMimeTypeException if the string cannot be parsed
*/
public static List<MimeType> parseMimeTypes(String mimeTypes) {
if (!StringUtils.hasLength(mimeTypes)) {
return Collections.emptyList();
}
String[] tokens = StringUtils.tokenizeToStringArray(mimeTypes, ",");
List<MimeType> result = new ArrayList<>(tokens.length);
for (String token : tokens) {
result.add(parseMimeType(token));
return tokenize(mimeTypes).stream()
.map(MimeTypeUtils::parseMimeType).collect(Collectors.toList());
}
/**
* Tokenize the given comma-separated string of {@code MimeType} objects
* into a {@code List<String>}. Unlike simple tokenization by ",", this
* method takes into account quoted parameters.
* @param mimeTypes the string to tokenize
* @return the list of tokens
* @since 5.1.3
*/
public static List<String> tokenize(String mimeTypes) {
if (!StringUtils.hasLength(mimeTypes)) {
return Collections.emptyList();
}
List<String> tokens = new ArrayList<>();
boolean inQuotes = false;
int startIndex = 0;
int i = 0;
while (i < mimeTypes.length()) {
switch (mimeTypes.charAt(i)) {
case '"':
inQuotes = !inQuotes;
break;
case ',':
if (!inQuotes) {
tokens.add(mimeTypes.substring(startIndex, i));
startIndex = i + 1;
}
break;
case '\\':
i++;
break;
}
i++;
}
return result;
tokens.add(mimeTypes.substring(startIndex));
return tokens;
}
/**

20
spring-core/src/test/java/org/springframework/util/MimeTypeTests.java

@ -36,6 +36,7 @@ import static org.junit.Assert.*; @@ -36,6 +36,7 @@ import static org.junit.Assert.*;
* @author Arjen Poutsma
* @author Juergen Hoeller
* @author Sam Brannen
* @author Dimitrios Liapis
*/
public class MimeTypeTests {
@ -276,6 +277,25 @@ public class MimeTypeTests { @@ -276,6 +277,25 @@ public class MimeTypeTests {
assertEquals("Invalid amount of mime types", 0, mimeTypes.size());
}
@Test // SPR-17459
public void parseMimeTypesWithQuotedParameters() {
testWithQuotedParameters("foo/bar;param=\",\"");
testWithQuotedParameters("foo/bar;param=\"s,a,\"");
testWithQuotedParameters("foo/bar;param=\"s,\"", "text/x-c");
testWithQuotedParameters("foo/bar;param=\"a\\\"b,c\"");
testWithQuotedParameters("foo/bar;param=\"\\\\\"");
testWithQuotedParameters("foo/bar;param=\"\\,\\\"");
}
private void testWithQuotedParameters(String... mimeTypes) {
String s = String.join(",", mimeTypes);
List<MimeType> actual = MimeTypeUtils.parseMimeTypes(s);
assertEquals(mimeTypes.length, actual.size());
for (int i=0; i < mimeTypes.length; i++) {
assertEquals(mimeTypes[i], actual.get(i).toString());
}
}
@Test
public void compareTo() {
MimeType audioBasic = new MimeType("audio", "basic");

10
spring-web/src/main/java/org/springframework/http/MediaType.java

@ -542,7 +542,7 @@ public class MediaType extends MimeType implements Serializable { @@ -542,7 +542,7 @@ public class MediaType extends MimeType implements Serializable {
}
/**
* Parse the given comma-separated string into a list of {@code MediaType} objects.
* Parse the comma-separated string into a list of {@code MediaType} objects.
* <p>This method can be used to parse an Accept or Content-Type header.
* @param mediaTypes the string to parse
* @return the list of media types
@ -552,12 +552,8 @@ public class MediaType extends MimeType implements Serializable { @@ -552,12 +552,8 @@ public class MediaType extends MimeType implements Serializable {
if (!StringUtils.hasLength(mediaTypes)) {
return Collections.emptyList();
}
String[] tokens = StringUtils.tokenizeToStringArray(mediaTypes, ",");
List<MediaType> result = new ArrayList<>(tokens.length);
for (String token : tokens) {
result.add(parseMediaType(token));
}
return result;
return MimeTypeUtils.tokenize(mediaTypes).stream()
.map(MediaType::parseMediaType).collect(Collectors.toList());
}
/**

Loading…
Cancel
Save