All Downloads are FREE. Search and download functionalities are using the official Maven repository.

zhttp.service.server.WebSocketUpgrade.scala Maven / Gradle / Ivy

There is a newer version: 2.0.0-RC11
Show newest version
package zhttp.service.server

import io.netty.channel.{ChannelHandler, ChannelHandlerContext}
import io.netty.handler.codec.http._
import io.netty.handler.codec.http.websocketx.WebSocketServerProtocolHandler
import zhttp.http.{Response, Status}
import zhttp.service.{HttpRuntime, WEB_SOCKET_HANDLER, WebSocketAppHandler}

import scala.annotation.tailrec

/**
 * Module to switch protocol to websockets
 */
trait WebSocketUpgrade[R] { self: ChannelHandler =>
  val runtime: HttpRuntime[R]

  final def isWebSocket(res: Response): Boolean =
    res.status.asJava.code() == Status.SwitchingProtocols.asJava.code() && res.attribute.socketApp.nonEmpty

  /**
   * Checks if the response requires to switch protocol to websocket. Returns
   * true if it can, otherwise returns false
   */
  @tailrec
  final def upgradeToWebSocket(jReq: HttpRequest, res: Response)(implicit ctx: ChannelHandlerContext): Unit = {
    val app = res.attribute.socketApp

    jReq match {
      case jReq: FullHttpRequest =>
        ctx
          .channel()
          .pipeline()
          .addLast(new WebSocketServerProtocolHandler(app.get.protocol.serverBuilder.build()))
          .addLast(WEB_SOCKET_HANDLER, new WebSocketAppHandler(runtime, app.get))
        ctx.channel().eventLoop().submit(() => ctx.fireChannelRead(jReq)): Unit

      case jReq: HttpRequest =>
        val fullRequest = new DefaultFullHttpRequest(jReq.protocolVersion(), jReq.method(), jReq.uri())
        fullRequest.headers().setAll(jReq.headers())
        self.upgradeToWebSocket(fullRequest, res)
    }
  }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy