When I was using SseEventBuilder in spring mvc 5.3.x, I noticed that no spaces were added when constructing "data:" in the data method of the SseEventBuilderImpl implementation class. As a result, when the output is in markdown format, when the content that starts with a space appears in the segmented interception, the space will be lost on the front end. When reviewing the protocol standards of SSE, it was found that when a space appears after ":" in the content, the space is removed. See server-sent-events 9.2.6, which references

If the line starts with a U+003A COLON character (:) Ignore the line. If the line contains a U+003A COLON character (:) Collect the characters on the line before the first U+003A COLON character (:), and let be that string.field Collect the characters on the line after the first U+003A COLON character (:), and let be that string. If starts with a U+0020 SPACE character, remove it from .valuevaluevalue

So I suggest modifying append("data:") in the SseEventBuilderImpl.data method of spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/method/annotation/SseEmitter.java to append("data: "); The other versions are modified in the same way

Comment From: quaff

According to the reference, data:value is same to data: value, why do you think data:value is not standards compliant?

Comment From: bclozel

Spring Framework is sending valid SSE chunks. In this case, I think the application is responsible for encoding/escaping the payloads to account for this.

Comment From: icguy

the application is responsible for encoding/escaping the payloads to account for this

I believe this is incorrect. Spring is sending valid SSE chunks but they do not contain the supplied payload. I've implemented a minimal reproduction: https://github.com/icguy/spring33963

val payloads = listOf("These", " words", " should", " arrive", " with", " spaces", " between", " them")
val emitter = SseEmitter()
thread {
    for (p in payloads) {
        val event = SseEmitter.event().data(p).build()
        emitter.send(event)
    }
    emitter.complete()
}
return emitter

As you can see the payload for most events starts with a space character.

This is the raw response:

data:These

data: words

data: should

data: arrive

data: with

data: spaces

data: between

data: them


But according to the spec during parsing on the client side if value starts with a U+0020 SPACE character, remove it from value.

This is the behavior of the minimal client I wrote to demonstrate the issue (also in the repository) which simply concatenates the values received via an EventSource object:

Image

So in conclusion: no, Spring doesn't send the payload in a standard compliant manner unless the intention was to implicitly drop a leading space from the payload.

Comment From: bclozel

@icguy SseEmitter can accept many types as data. If you are providing such strings directly, I would argue that managing the space character here should be done by your implementation.