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.

Comment From: icguy

I don't think it's unreasonable for an API consumer to expect to receive on the client side exactly what they specified on the server side.

Is there a particular reason against the originally proposed solution of replacing data: with data:?

Comment From: bclozel

I'd say that both are completely standard, but if we make this behavior change we might break existing applications that already take this into account. Other contributors could say that data: is perfectly valid and is the minimum that the server side should do, and by forcing data: we take away an application choice.