Missing Set-Cookie header for WebSocket connection


(Pascal H.) #1

Using Lagom 1.4.2, I’ve got a strange behavior with a WebSocket connection: the Set-Cookie is missing (everything is ok for GET requests).

My WebSocket code in the web gateway (play) is very trivial

  def ws: WebSocket = WebSocket.acceptOrResult[String, String] {
    r: RequestHeader =>
      {
        println(s"Request Headers : ${r.headers}")
        r match { /* process request */ }
     }
  }

I test this WebSocket using wscat where I add extra headers:

wscat -H "Set-Cookie:COOKIE=VALUE" -H "X-Auth-Token: token" -H "MyHeader: dummy" -c ws://localhost:9000/ws

What I expect is to simply get all my headers (cookie and custom headers) in the request header of my WebSocket.

Unfortunately, if I use the following main Loader with Lagom components

abstract class WebGateway(context: Context) extends BuiltInComponentsFromContext(context)
   /* other traits : implementation details */
  with LagomConfigComponent
  with LagomServiceClientComponents { /* ... */ }

class WebGatewayLoader extends ApplicationLoader with utils.Logger {
  override def load(context: Context): Application = {
    (new WebGateway(context) with LagomDevModeComponents).application
  }
}

Header Set-Cookie is missing but the 2 others are there:

Request Headers : List((Remote-Address,127.0.0.1:65182), (UpgradeToWebSocket,), (Raw-Request-URI,/ws), (Tls-Session-Info,[Session-1, SSL_NULL_WITH_NULL_NULL]), (Upgrade,websocket), (Connection,upgrade), (Sec-WebSocket-Key,+4sAzV9rzXRlPDDqmsS05g==), (Sec-WebSocket-Version,13), (X-Auth-Token,token), (MyHeader,dummy), (Origin,ws://localhost:9000), (Host,localhost:9000), (User-Agent,akka-http/10.0.11), (Timeout-Access,<function1>))

If I use the following main Loader without Lagom components

class WebGateway(context: Context) extends BuiltInComponentsFromContext(context)
   /* other traits : implementation details */
   { /* ... */ }

class WebGatewayLoader extends ApplicationLoader with utils.Logger {
  override def load(context: Context): Application = {
    (new WebGateway(context)).application
  }
}

Header “Set-Cookie” is there with the 2 others:

List((Remote-Address,127.0.0.1:65472), (UpgradeToWebSocket,), (Raw-Request-URI,/ws), (Tls-Session-Info,[Session-1, SSL_NULL_WITH_NULL_NULL]), (Sec-WebSocket-Version,13), (Sec-WebSocket-Key,Rg3CBczx0wKPWRB+8S8GIg==), (Connection,Upgrade), (Upgrade,websocket), (Set-Cookie,COOKIE=VALUE), (X-Auth-Token,token), (MyHeader,dummy), (Sec-WebSocket-Extensions,permessage-deflate; client_max_window_bits), (Origin,ws://localhost:9000), (Host,localhost:9000), (Timeout-Access,<function1>))

Obviously, to be able to do so, all services have been removed.

Do you have an explanation or a workaround?


(Tim Moore) #2

@hpwxf do you see the same behaviour when you bypass the service gateway and send the request directly to the port the application is listening to? My guess is that this is a bug in the gateway (that it doesn’t forward the header to the backing service).

Can you publish a reproduction to GitHub?


(Pascal H.) #3

I published a reproducer in https://github.com/hpwxf/reproducer-lagom-discuss514.

While I was working to create a minimalistic reproducer, I understood that this problem with Set-Cookie header occurs also for a standard request (GET in my reproducer – only with Lagom components).

It is possible that my idea to use Set-Cookie to do what I mean is a bad idea or a bad practice.
Is it possible that a component in Lagom used to manage requests filters out this header? (as a preventive approach)


(Tim Moore) #4

My apologies… just returning to this now. I suspect that the difference is whether you’re going through the service gateway or not. I expect that the service gateway is not forwarding cookies in this case.

Are you able to verify this by testing against the service port directly?

It’s not really clear to me whether or not this is really a bug. Set-Cookie is not a valid request header (it’s only valid on responses) so this could be why it’s filtered out.

What is the higher-level goal you’re trying to achieve with this header? Maybe there’s a better alternative approach.