Skip to content

Commit 6b30522

Browse files
committed
Skip "data:" lines without content
Closes gh-27923
1 parent cf5b863 commit 6b30522

File tree

2 files changed

+27
-23
lines changed

2 files changed

+27
-23
lines changed

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

+12-10
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2021 the original author or authors.
2+
* Copyright 2002-2022 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.
@@ -42,6 +42,7 @@
4242
*
4343
* @author Sebastien Deleuze
4444
* @author Rossen Stoyanchev
45+
* @author Juergen Hoeller
4546
* @since 5.0
4647
*/
4748
public class ServerSentEventHttpMessageReader implements HttpMessageReader<Object> {
@@ -140,22 +141,23 @@ public Flux<Object> read(
140141
private Object buildEvent(List<String> lines, ResolvableType valueType, boolean shouldWrap,
141142
Map<String, Object> hints) {
142143

143-
ServerSentEvent.Builder<Object> sseBuilder = shouldWrap ? ServerSentEvent.builder() : null;
144+
ServerSentEvent.Builder<Object> sseBuilder = (shouldWrap ? ServerSentEvent.builder() : null);
144145
StringBuilder data = null;
145146
StringBuilder comment = null;
146147

147148
for (String line : lines) {
148149
if (line.startsWith("data:")) {
149-
data = (data != null ? data : new StringBuilder());
150-
if (line.charAt(5) != ' ') {
151-
data.append(line, 5, line.length());
150+
int length = line.length();
151+
if (length > 5) {
152+
int index = (line.charAt(5) != ' ' ? 5 : 6);
153+
if (length > index) {
154+
data = (data != null ? data : new StringBuilder());
155+
data.append(line, index, line.length());
156+
data.append('\n');
157+
}
152158
}
153-
else {
154-
data.append(line, 6, line.length());
155-
}
156-
data.append('\n');
157159
}
158-
if (shouldWrap) {
160+
else if (shouldWrap) {
159161
if (line.startsWith("id:")) {
160162
sseBuilder.id(line.substring(3).trim());
161163
}

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

+15-13
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2020 the original author or authors.
2+
* Copyright 2002-2022 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.
@@ -40,6 +40,7 @@
4040
* Unit tests for {@link ServerSentEventHttpMessageReader}.
4141
*
4242
* @author Sebastien Deleuze
43+
* @author Juergen Hoeller
4344
*/
4445
public class ServerSentEventHttpMessageReaderTests extends AbstractLeakCheckingTests {
4546

@@ -66,7 +67,7 @@ public void readServerSentEvents() {
6667
MockServerHttpRequest request = MockServerHttpRequest.post("/")
6768
.body(Mono.just(stringBuffer(
6869
"id:c42\nevent:foo\nretry:123\n:bla\n:bla bla\n:bla bla bla\ndata:bar\n\n" +
69-
"id:c43\nevent:bar\nretry:456\ndata:baz\n\n")));
70+
"id:c43\nevent:bar\nretry:456\ndata:baz\n\ndata:\n\ndata: \n\n")));
7071

7172
Flux<ServerSentEvent> events = this.reader
7273
.read(ResolvableType.forClassWithGenerics(ServerSentEvent.class, String.class),
@@ -87,6 +88,8 @@ public void readServerSentEvents() {
8788
assertThat(event.comment()).isNull();
8889
assertThat(event.data()).isEqualTo("baz");
8990
})
91+
.consumeNextWith(event -> assertThat(event.data()).isNull())
92+
.consumeNextWith(event -> assertThat(event.data()).isNull())
9093
.expectComplete()
9194
.verify();
9295
}
@@ -175,7 +178,7 @@ public void readPojo() {
175178
.verify();
176179
}
177180

178-
@Test // gh-24389
181+
@Test // gh-24389
179182
void readPojoWithCommentOnly() {
180183
MockServerHttpRequest request = MockServerHttpRequest.post("/")
181184
.body(Flux.just(stringBuffer(":ping\n"), stringBuffer("\n")));
@@ -221,7 +224,6 @@ public void readError() {
221224

222225
@Test
223226
public void maxInMemoryLimit() {
224-
225227
this.reader.setMaxInMemorySize(17);
226228

227229
MockServerHttpRequest request = MockServerHttpRequest.post("/")
@@ -235,9 +237,8 @@ public void maxInMemoryLimit() {
235237
.verify();
236238
}
237239

238-
@Test // gh-24312
240+
@Test // gh-24312
239241
public void maxInMemoryLimitAllowsReadingPojoLargerThanDefaultSize() {
240-
241242
int limit = this.jsonDecoder.getMaxInMemorySize();
242243

243244
String fooValue = getStringOfSize(limit) + "and then some more";
@@ -259,13 +260,6 @@ public void maxInMemoryLimitAllowsReadingPojoLargerThanDefaultSize() {
259260
.verify();
260261
}
261262

262-
private static String getStringOfSize(long size) {
263-
StringBuilder content = new StringBuilder("Aa");
264-
while (content.length() < size) {
265-
content.append(content);
266-
}
267-
return content.toString();
268-
}
269263

270264
private DataBuffer stringBuffer(String value) {
271265
byte[] bytes = value.getBytes(StandardCharsets.UTF_8);
@@ -274,4 +268,12 @@ private DataBuffer stringBuffer(String value) {
274268
return buffer;
275269
}
276270

271+
private static String getStringOfSize(long size) {
272+
StringBuilder content = new StringBuilder("Aa");
273+
while (content.length() < size) {
274+
content.append(content);
275+
}
276+
return content.toString();
277+
}
278+
277279
}

0 commit comments

Comments
 (0)