Skip to content

Commit c8d49ed

Browse files
committed
Fix EncoderHttpMessageWriter.isStreamingMediaType()
Closes gh-22936
1 parent 484ec64 commit c8d49ed

File tree

2 files changed

+32
-8
lines changed

2 files changed

+32
-8
lines changed

spring-web/src/main/java/org/springframework/http/codec/EncoderHttpMessageWriter.java

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@
3838
import org.springframework.http.server.reactive.ServerHttpResponse;
3939
import org.springframework.lang.Nullable;
4040
import org.springframework.util.Assert;
41+
import org.springframework.util.StringUtils;
4142

4243
/**
4344
* {@code HttpMessageWriter} that wraps and delegates to an {@link Encoder}.
@@ -166,19 +167,29 @@ private static MediaType addDefaultCharset(MediaType main, @Nullable MediaType d
166167
return main;
167168
}
168169

169-
private boolean isStreamingMediaType(@Nullable MediaType contentType) {
170-
if (contentType == null || !(this.encoder instanceof HttpMessageEncoder)) {
170+
private boolean isStreamingMediaType(@Nullable MediaType mediaType) {
171+
if (mediaType == null || !(this.encoder instanceof HttpMessageEncoder)) {
171172
return false;
172173
}
173-
for (MediaType mediaType : ((HttpMessageEncoder<?>) this.encoder).getStreamingMediaTypes()) {
174-
if (contentType.isCompatibleWith(mediaType) &&
175-
contentType.getParameters().keySet().containsAll(mediaType.getParameters().keySet())) {
174+
for (MediaType streamingMediaType : ((HttpMessageEncoder<?>) this.encoder).getStreamingMediaTypes()) {
175+
if (mediaType.isCompatibleWith(streamingMediaType) && matchParameters(mediaType, streamingMediaType)) {
176176
return true;
177177
}
178178
}
179179
return false;
180180
}
181181

182+
private boolean matchParameters(MediaType streamingMediaType, MediaType mediaType) {
183+
for (String name : streamingMediaType.getParameters().keySet()) {
184+
String s1 = streamingMediaType.getParameter(name);
185+
String s2 = mediaType.getParameter(name);
186+
if (StringUtils.hasText(s1) && StringUtils.hasText(s2) && !s1.equalsIgnoreCase(s2)) {
187+
return false;
188+
}
189+
}
190+
return true;
191+
}
192+
182193

183194
// Server side only...
184195

spring-web/src/test/java/org/springframework/http/codec/EncoderHttpMessageWriterTests.java

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2018 the original author or authors.
2+
* Copyright 2002-2019 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -16,6 +16,8 @@
1616

1717
package org.springframework.http.codec;
1818

19+
import java.lang.reflect.InvocationTargetException;
20+
import java.lang.reflect.Method;
1921
import java.nio.charset.StandardCharsets;
2022
import java.util.Arrays;
2123
import java.util.Collections;
@@ -31,13 +33,13 @@
3133
import reactor.core.publisher.Mono;
3234
import reactor.test.StepVerifier;
3335

34-
import org.springframework.core.codec.Encoder;
3536
import org.springframework.core.io.buffer.DataBuffer;
3637
import org.springframework.core.io.buffer.DefaultDataBufferFactory;
3738
import org.springframework.http.MediaType;
3839
import org.springframework.mock.http.server.reactive.test.MockServerHttpResponse;
3940
import org.springframework.util.MimeType;
4041
import org.springframework.util.MimeTypeUtils;
42+
import org.springframework.util.ReflectionUtils;
4143

4244
import static java.nio.charset.StandardCharsets.*;
4345
import static org.junit.Assert.*;
@@ -59,7 +61,7 @@ public class EncoderHttpMessageWriterTests {
5961

6062

6163
@Mock
62-
private Encoder<String> encoder;
64+
private HttpMessageEncoder<String> encoder;
6365

6466
private ArgumentCaptor<MediaType> mediaTypeCaptor;
6567

@@ -172,6 +174,17 @@ public void emptyBodyWritten() {
172174
assertEquals(0, this.response.getHeaders().getContentLength());
173175
}
174176

177+
@Test // gh-22936
178+
public void isStreamingMediaType() throws InvocationTargetException, IllegalAccessException {
179+
HttpMessageWriter<String> writer = getWriter(TEXT_HTML);
180+
MediaType streamingMediaType = new MediaType(TEXT_PLAIN, Collections.singletonMap("streaming", "true"));
181+
when(this.encoder.getStreamingMediaTypes()).thenReturn(Arrays.asList(streamingMediaType));
182+
Method method = ReflectionUtils.findMethod(writer.getClass(), "isStreamingMediaType", MediaType.class);
183+
ReflectionUtils.makeAccessible(method);
184+
assertTrue((Boolean) method.invoke(writer, streamingMediaType));
185+
assertFalse((Boolean) method.invoke(writer, new MediaType(TEXT_PLAIN, Collections.singletonMap("streaming", "false"))));
186+
assertFalse((Boolean) method.invoke(writer, TEXT_HTML));
187+
}
175188

176189
private HttpMessageWriter<String> getWriter(MimeType... mimeTypes) {
177190
return getWriter(Flux.empty(), mimeTypes);

0 commit comments

Comments
 (0)