11/*
2- * Copyright 2002-2019 the original author or authors.
2+ * Copyright 2002-2020 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.
2727
2828import org .springframework .core .ResolvableType ;
2929import org .springframework .core .io .buffer .DataBuffer ;
30+ import org .springframework .core .io .buffer .DataBufferLimitException ;
3031import org .springframework .core .testfixture .io .buffer .AbstractLeakCheckingTests ;
3132import org .springframework .http .MediaType ;
3233import org .springframework .http .codec .json .Jackson2JsonDecoder ;
4243 */
4344public class ServerSentEventHttpMessageReaderTests extends AbstractLeakCheckingTests {
4445
45- private ServerSentEventHttpMessageReader messageReader =
46- new ServerSentEventHttpMessageReader (new Jackson2JsonDecoder ());
46+ private Jackson2JsonDecoder jsonDecoder = new Jackson2JsonDecoder ();
47+
48+ private ServerSentEventHttpMessageReader reader = new ServerSentEventHttpMessageReader (this .jsonDecoder );
4749
4850
4951 @ Test
5052 public void cantRead () {
51- assertThat (messageReader .canRead (ResolvableType .forClass (Object .class ), new MediaType ("foo" , "bar" ))).isFalse ();
52- assertThat (messageReader .canRead (ResolvableType .forClass (Object .class ), null )).isFalse ();
53+ assertThat (reader .canRead (ResolvableType .forClass (Object .class ), new MediaType ("foo" , "bar" ))).isFalse ();
54+ assertThat (reader .canRead (ResolvableType .forClass (Object .class ), null )).isFalse ();
5355 }
5456
5557 @ Test
5658 public void canRead () {
57- assertThat (messageReader .canRead (ResolvableType .forClass (Object .class ), new MediaType ("text" , "event-stream" ))).isTrue ();
58- assertThat (messageReader .canRead (ResolvableType .forClass (ServerSentEvent .class ), new MediaType ("foo" , "bar" ))).isTrue ();
59+ assertThat (reader .canRead (ResolvableType .forClass (Object .class ), new MediaType ("text" , "event-stream" ))).isTrue ();
60+ assertThat (reader .canRead (ResolvableType .forClass (ServerSentEvent .class ), new MediaType ("foo" , "bar" ))).isTrue ();
5961 }
6062
6163 @ Test
@@ -66,7 +68,7 @@ public void readServerSentEvents() {
6668 "id:c42\n event:foo\n retry:123\n :bla\n :bla bla\n :bla bla bla\n data:bar\n \n " +
6769 "id:c43\n event:bar\n retry:456\n data:baz\n \n " )));
6870
69- Flux <ServerSentEvent > events = this .messageReader
71+ Flux <ServerSentEvent > events = this .reader
7072 .read (ResolvableType .forClassWithGenerics (ServerSentEvent .class , String .class ),
7173 request , Collections .emptyMap ()).cast (ServerSentEvent .class );
7274
@@ -98,7 +100,7 @@ public void readServerSentEventsWithMultipleChunks() {
98100 stringBuffer ("ent:foo\n retry:123\n :bla\n :bla bla\n :bla bla bla\n data:" ),
99101 stringBuffer ("bar\n \n id:c43\n event:bar\n retry:456\n data:baz\n \n " )));
100102
101- Flux <ServerSentEvent > events = messageReader
103+ Flux <ServerSentEvent > events = reader
102104 .read (ResolvableType .forClassWithGenerics (ServerSentEvent .class , String .class ),
103105 request , Collections .emptyMap ()).cast (ServerSentEvent .class );
104106
@@ -126,7 +128,7 @@ public void readString() {
126128 MockServerHttpRequest request = MockServerHttpRequest .post ("/" )
127129 .body (Mono .just (stringBuffer ("data:foo\n data:bar\n \n data:baz\n \n " )));
128130
129- Flux <String > data = messageReader .read (ResolvableType .forClass (String .class ),
131+ Flux <String > data = reader .read (ResolvableType .forClass (String .class ),
130132 request , Collections .emptyMap ()).cast (String .class );
131133
132134 StepVerifier .create (data )
@@ -143,7 +145,7 @@ public void readPojo() {
143145 "data:{\" foo\" : \" foofoo\" , \" bar\" : \" barbar\" }\n \n " +
144146 "data:{\" foo\" : \" foofoofoo\" , \" bar\" : \" barbarbar\" }\n \n " )));
145147
146- Flux <Pojo > data = messageReader .read (ResolvableType .forClass (Pojo .class ), request ,
148+ Flux <Pojo > data = reader .read (ResolvableType .forClass (Pojo .class ), request ,
147149 Collections .emptyMap ()).cast (Pojo .class );
148150
149151 StepVerifier .create (data )
@@ -165,7 +167,7 @@ public void decodeFullContentAsString() {
165167 MockServerHttpRequest request = MockServerHttpRequest .post ("/" )
166168 .body (Mono .just (stringBuffer (body )));
167169
168- String actual = messageReader
170+ String actual = reader
169171 .readMono (ResolvableType .forClass (String .class ), request , Collections .emptyMap ())
170172 .cast (String .class )
171173 .block (Duration .ZERO );
@@ -182,7 +184,7 @@ public void readError() {
182184 MockServerHttpRequest request = MockServerHttpRequest .post ("/" )
183185 .body (body );
184186
185- Flux <String > data = messageReader .read (ResolvableType .forClass (String .class ),
187+ Flux <String > data = reader .read (ResolvableType .forClass (String .class ),
186188 request , Collections .emptyMap ()).cast (String .class );
187189
188190 StepVerifier .create (data )
@@ -192,6 +194,54 @@ public void readError() {
192194 .verify ();
193195 }
194196
197+ @ Test
198+ public void maxInMemoryLimit () {
199+
200+ this .reader .setMaxInMemorySize (17 );
201+
202+ MockServerHttpRequest request = MockServerHttpRequest .post ("/" )
203+ .body (Flux .just (stringBuffer ("data:\" TOO MUCH DATA\" \n data:bar\n \n data:baz\n \n " )));
204+
205+ Flux <String > data = this .reader .read (ResolvableType .forClass (String .class ),
206+ request , Collections .emptyMap ()).cast (String .class );
207+
208+ StepVerifier .create (data )
209+ .expectError (DataBufferLimitException .class )
210+ .verify ();
211+ }
212+
213+ @ Test // gh-24312
214+ public void maxInMemoryLimitAllowsReadingPojoLargerThanDefaultSize () {
215+
216+ int limit = this .jsonDecoder .getMaxInMemorySize ();
217+
218+ String fooValue = getStringOfSize (limit ) + "and then some more" ;
219+ String content = "data:{\" foo\" : \" " + fooValue + "\" }\n \n " ;
220+ MockServerHttpRequest request = MockServerHttpRequest .post ("/" ).body (Mono .just (stringBuffer (content )));
221+
222+ Jackson2JsonDecoder jacksonDecoder = new Jackson2JsonDecoder ();
223+ ServerSentEventHttpMessageReader messageReader = new ServerSentEventHttpMessageReader (jacksonDecoder );
224+
225+ jacksonDecoder .setMaxInMemorySize (limit + 1024 );
226+ messageReader .setMaxInMemorySize (limit + 1024 );
227+
228+ Flux <Pojo > data = messageReader .read (ResolvableType .forClass (Pojo .class ), request ,
229+ Collections .emptyMap ()).cast (Pojo .class );
230+
231+ StepVerifier .create (data )
232+ .consumeNextWith (pojo -> assertThat (pojo .getFoo ()).isEqualTo (fooValue ))
233+ .expectComplete ()
234+ .verify ();
235+ }
236+
237+ private static String getStringOfSize (long size ) {
238+ StringBuilder content = new StringBuilder ("Aa" );
239+ while (content .length () < size ) {
240+ content .append (content );
241+ }
242+ return content .toString ();
243+ }
244+
195245 private DataBuffer stringBuffer (String value ) {
196246 byte [] bytes = value .getBytes (StandardCharsets .UTF_8 );
197247 DataBuffer buffer = this .bufferFactory .allocateBuffer (bytes .length );
0 commit comments