1
1
/*
2
- * Copyright 2002-2019 the original author or authors.
2
+ * Copyright 2002-2020 the original author or authors.
3
3
*
4
4
* Licensed under the Apache License, Version 2.0 (the "License");
5
5
* you may not use this file except in compliance with the License.
27
27
28
28
import org .springframework .core .ResolvableType ;
29
29
import org .springframework .core .io .buffer .DataBuffer ;
30
+ import org .springframework .core .io .buffer .DataBufferLimitException ;
30
31
import org .springframework .core .testfixture .io .buffer .AbstractLeakCheckingTests ;
31
32
import org .springframework .http .MediaType ;
32
33
import org .springframework .http .codec .json .Jackson2JsonDecoder ;
42
43
*/
43
44
public class ServerSentEventHttpMessageReaderTests extends AbstractLeakCheckingTests {
44
45
45
- private ServerSentEventHttpMessageReader messageReader =
46
- new ServerSentEventHttpMessageReader (new Jackson2JsonDecoder ());
46
+ private Jackson2JsonDecoder jsonDecoder = new Jackson2JsonDecoder ();
47
+
48
+ private ServerSentEventHttpMessageReader reader = new ServerSentEventHttpMessageReader (this .jsonDecoder );
47
49
48
50
49
51
@ Test
50
52
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 ();
53
55
}
54
56
55
57
@ Test
56
58
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 ();
59
61
}
60
62
61
63
@ Test
@@ -66,7 +68,7 @@ public void readServerSentEvents() {
66
68
"id:c42\n event:foo\n retry:123\n :bla\n :bla bla\n :bla bla bla\n data:bar\n \n " +
67
69
"id:c43\n event:bar\n retry:456\n data:baz\n \n " )));
68
70
69
- Flux <ServerSentEvent > events = this .messageReader
71
+ Flux <ServerSentEvent > events = this .reader
70
72
.read (ResolvableType .forClassWithGenerics (ServerSentEvent .class , String .class ),
71
73
request , Collections .emptyMap ()).cast (ServerSentEvent .class );
72
74
@@ -98,7 +100,7 @@ public void readServerSentEventsWithMultipleChunks() {
98
100
stringBuffer ("ent:foo\n retry:123\n :bla\n :bla bla\n :bla bla bla\n data:" ),
99
101
stringBuffer ("bar\n \n id:c43\n event:bar\n retry:456\n data:baz\n \n " )));
100
102
101
- Flux <ServerSentEvent > events = messageReader
103
+ Flux <ServerSentEvent > events = reader
102
104
.read (ResolvableType .forClassWithGenerics (ServerSentEvent .class , String .class ),
103
105
request , Collections .emptyMap ()).cast (ServerSentEvent .class );
104
106
@@ -126,7 +128,7 @@ public void readString() {
126
128
MockServerHttpRequest request = MockServerHttpRequest .post ("/" )
127
129
.body (Mono .just (stringBuffer ("data:foo\n data:bar\n \n data:baz\n \n " )));
128
130
129
- Flux <String > data = messageReader .read (ResolvableType .forClass (String .class ),
131
+ Flux <String > data = reader .read (ResolvableType .forClass (String .class ),
130
132
request , Collections .emptyMap ()).cast (String .class );
131
133
132
134
StepVerifier .create (data )
@@ -143,7 +145,7 @@ public void readPojo() {
143
145
"data:{\" foo\" : \" foofoo\" , \" bar\" : \" barbar\" }\n \n " +
144
146
"data:{\" foo\" : \" foofoofoo\" , \" bar\" : \" barbarbar\" }\n \n " )));
145
147
146
- Flux <Pojo > data = messageReader .read (ResolvableType .forClass (Pojo .class ), request ,
148
+ Flux <Pojo > data = reader .read (ResolvableType .forClass (Pojo .class ), request ,
147
149
Collections .emptyMap ()).cast (Pojo .class );
148
150
149
151
StepVerifier .create (data )
@@ -165,7 +167,7 @@ public void decodeFullContentAsString() {
165
167
MockServerHttpRequest request = MockServerHttpRequest .post ("/" )
166
168
.body (Mono .just (stringBuffer (body )));
167
169
168
- String actual = messageReader
170
+ String actual = reader
169
171
.readMono (ResolvableType .forClass (String .class ), request , Collections .emptyMap ())
170
172
.cast (String .class )
171
173
.block (Duration .ZERO );
@@ -182,7 +184,7 @@ public void readError() {
182
184
MockServerHttpRequest request = MockServerHttpRequest .post ("/" )
183
185
.body (body );
184
186
185
- Flux <String > data = messageReader .read (ResolvableType .forClass (String .class ),
187
+ Flux <String > data = reader .read (ResolvableType .forClass (String .class ),
186
188
request , Collections .emptyMap ()).cast (String .class );
187
189
188
190
StepVerifier .create (data )
@@ -192,6 +194,54 @@ public void readError() {
192
194
.verify ();
193
195
}
194
196
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
+
195
245
private DataBuffer stringBuffer (String value ) {
196
246
byte [] bytes = value .getBytes (StandardCharsets .UTF_8 );
197
247
DataBuffer buffer = this .bufferFactory .allocateBuffer (bytes .length );
0 commit comments