Netflix/zuul

Zuul Push Server SSE protocol not working

dkublik opened this issue · 3 comments

When Running Zuul Push Server in SSE (Server Sent Events), Push Protocol is not working correctly.

Problem Description

Messages mentioned below are never received by the client:

  1. com.netflix.zuul.netty.server.push.PushProtocol.SSE
  • goAwayMessage()
  • serverClosingConnectionMessage()
  1. all the calls of
    com.netflix.zuul.netty.server.push.PushProtocol.sendErrorAndClose()

  2. retry message from com.netflix.zuul.sample.push.SampleSSEPushClientProtocolHandler.channelRead()

String reconnectInterval = "retry: " + SSE_RETRY_BASE_INTERVAL.get() + "\r\n\r\n";
ctx.writeAndFlush(reconnectInterval);
  1. more over:
    com.netflix.zuul.netty.server.push.PushRegistrationHandler.keepAlive() will work only for websockets:
if (KEEP_ALIVE_ENABLED.get()) {
    this.ctx.writeAndFlush(new PingWebSocketFrame());
}

Cause Explanation

This is because all of theses message are sent as String messages, and as such will be ignored by HttpObjectEncoder.write()
(which is called by io.netty.handler.codec.http.HttpServerCodec set in com.netflix.zuul.netty.server.push.PushChannelInitializer)

HttpObjectEncoder.write() accepts only following types

io.netty.handler.codec.http.FullHttpMessage
io.netty.handler.codec.http.HttpMessage
io.netty.handler.codec.http.LastHttpContent
io.netty.handler.codec.http.HttpContent
io.netty.buffer.ByteBuf
io.netty.channel.FileRegion

so all not working protocol messages should be probably sent as ByteBuf
(just like com.netflix.zuul.netty.server.push.PushProtocol.SSE.sendPushMessage() which works)

How to Replicate

  1. Launch Zuul Push Server
  1. In first terminal window register to the Push Server with user ala:
curl -v "http://localhost:7001/sse" \
--header 'Accept: text/event-stream' \
-b 'userAuthCookie=ala'
  1. In the second terminal window send message to user ala:
curl -v http://localhost:7008/push \
--header 'X-CUSTOMER_ID: ala' \
-d 'message to ala'

observe (in first terminal window) that no protocol messages are received (for example missing message "retry" below):

kublikd@J4MJ4HHYH3 push-server % curl -v "http://localhost:7001/sse" \
--header 'Accept: text/event-stream' \
-b 'userAuthCookie=ala'
* Host localhost:7001 was resolved.
* IPv6: ::1
* IPv4: 127.0.0.1
*   Trying [::1]:7001...
* Connected to localhost (::1) port 7001
> GET /sse HTTP/1.1
> Host: localhost:7001
> User-Agent: curl/8.6.0
> Cookie: userAuthCookie=ala
> Accept: text/event-stream
> 
< HTTP/1.1 200 OK
< Connection: keep-alive
< Content-Type: text/event-stream
< Transfer-Encoding: chunked
< 
event: push
data: message to alice

should be:

kublikd@J4MJ4HHYH3 push-server % curl -v "http://localhost:7001/sse" \
--header 'Accept: text/event-stream' \
-b 'userAuthCookie=ala'
* Host localhost:7001 was resolved.
* IPv6: ::1
* IPv4: 127.0.0.1
*   Trying [::1]:7001...
* Connected to localhost (::1) port 7001
> GET /sse HTTP/1.1
> Host: localhost:7001
> User-Agent: curl/8.6.0
> Cookie: userAuthCookie=ala
> Accept: text/event-stream
> 
< HTTP/1.1 200 OK
< Connection: keep-alive
< Content-Type: text/event-stream
< Transfer-Encoding: chunked
< 

retry: 5000

event: push
data: message to alice

other messages (mentioned in the first paragraph will also be missing)

created PR for this here -> #1811