Browse Source

Fix EncoderHttpMessageWriter.isStreamingMediaType()

Closes gh-22936
pull/23050/head
Sebastien Deleuze 6 years ago
parent
commit
c8d49ed284
  1. 21
      spring-web/src/main/java/org/springframework/http/codec/EncoderHttpMessageWriter.java
  2. 19
      spring-web/src/test/java/org/springframework/http/codec/EncoderHttpMessageWriterTests.java

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

@ -38,6 +38,7 @@ import org.springframework.http.server.reactive.ServerHttpRequest; @@ -38,6 +38,7 @@ import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.http.server.reactive.ServerHttpResponse;
import org.springframework.lang.Nullable;
import org.springframework.util.Assert;
import org.springframework.util.StringUtils;
/**
* {@code HttpMessageWriter} that wraps and delegates to an {@link Encoder}.
@ -166,19 +167,29 @@ public class EncoderHttpMessageWriter<T> implements HttpMessageWriter<T> { @@ -166,19 +167,29 @@ public class EncoderHttpMessageWriter<T> implements HttpMessageWriter<T> {
return main;
}
private boolean isStreamingMediaType(@Nullable MediaType contentType) {
if (contentType == null || !(this.encoder instanceof HttpMessageEncoder)) {
private boolean isStreamingMediaType(@Nullable MediaType mediaType) {
if (mediaType == null || !(this.encoder instanceof HttpMessageEncoder)) {
return false;
}
for (MediaType mediaType : ((HttpMessageEncoder<?>) this.encoder).getStreamingMediaTypes()) {
if (contentType.isCompatibleWith(mediaType) &&
contentType.getParameters().keySet().containsAll(mediaType.getParameters().keySet())) {
for (MediaType streamingMediaType : ((HttpMessageEncoder<?>) this.encoder).getStreamingMediaTypes()) {
if (mediaType.isCompatibleWith(streamingMediaType) && matchParameters(mediaType, streamingMediaType)) {
return true;
}
}
return false;
}
private boolean matchParameters(MediaType streamingMediaType, MediaType mediaType) {
for (String name : streamingMediaType.getParameters().keySet()) {
String s1 = streamingMediaType.getParameter(name);
String s2 = mediaType.getParameter(name);
if (StringUtils.hasText(s1) && StringUtils.hasText(s2) && !s1.equalsIgnoreCase(s2)) {
return false;
}
}
return true;
}
// Server side only...

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

@ -1,5 +1,5 @@ @@ -1,5 +1,5 @@
/*
* Copyright 2002-2018 the original author or authors.
* Copyright 2002-2019 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -16,6 +16,8 @@ @@ -16,6 +16,8 @@
package org.springframework.http.codec;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.nio.charset.StandardCharsets;
import java.util.Arrays;
import java.util.Collections;
@ -31,13 +33,13 @@ import reactor.core.publisher.Flux; @@ -31,13 +33,13 @@ import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;
import reactor.test.StepVerifier;
import org.springframework.core.codec.Encoder;
import org.springframework.core.io.buffer.DataBuffer;
import org.springframework.core.io.buffer.DefaultDataBufferFactory;
import org.springframework.http.MediaType;
import org.springframework.mock.http.server.reactive.test.MockServerHttpResponse;
import org.springframework.util.MimeType;
import org.springframework.util.MimeTypeUtils;
import org.springframework.util.ReflectionUtils;
import static java.nio.charset.StandardCharsets.*;
import static org.junit.Assert.*;
@ -59,7 +61,7 @@ public class EncoderHttpMessageWriterTests { @@ -59,7 +61,7 @@ public class EncoderHttpMessageWriterTests {
@Mock
private Encoder<String> encoder;
private HttpMessageEncoder<String> encoder;
private ArgumentCaptor<MediaType> mediaTypeCaptor;
@ -172,6 +174,17 @@ public class EncoderHttpMessageWriterTests { @@ -172,6 +174,17 @@ public class EncoderHttpMessageWriterTests {
assertEquals(0, this.response.getHeaders().getContentLength());
}
@Test // gh-22936
public void isStreamingMediaType() throws InvocationTargetException, IllegalAccessException {
HttpMessageWriter<String> writer = getWriter(TEXT_HTML);
MediaType streamingMediaType = new MediaType(TEXT_PLAIN, Collections.singletonMap("streaming", "true"));
when(this.encoder.getStreamingMediaTypes()).thenReturn(Arrays.asList(streamingMediaType));
Method method = ReflectionUtils.findMethod(writer.getClass(), "isStreamingMediaType", MediaType.class);
ReflectionUtils.makeAccessible(method);
assertTrue((Boolean) method.invoke(writer, streamingMediaType));
assertFalse((Boolean) method.invoke(writer, new MediaType(TEXT_PLAIN, Collections.singletonMap("streaming", "false"))));
assertFalse((Boolean) method.invoke(writer, TEXT_HTML));
}
private HttpMessageWriter<String> getWriter(MimeType... mimeTypes) {
return getWriter(Flux.empty(), mimeTypes);

Loading…
Cancel
Save