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

sss.openstar.http.TLSWebSocketServer.scala Maven / Gradle / Ivy

package sss.openstar.http

import akka.actor.ActorSystem
import akka.http.scaladsl.server.Route
import akka.http.scaladsl.{ConnectionContext, Http, HttpsConnectionContext}
import com.typesafe.config.Config
import sss.ancillary.Logging
import sss.openstar.http.TLSWebSocketServer.TLSWebSocketServerConfig

import java.io.{File, FileInputStream, InputStream}
import java.security.{KeyStore, SecureRandom}
import javax.net.ssl.{KeyManagerFactory, SSLContext, TrustManagerFactory}
import scala.concurrent.ExecutionContext.Implicits.global
import scala.util.{Failure, Success}

object TLSWebSocketServer {

  case class TLSWebSocketServerConfig(
                                       httpsEnabled: Boolean,
                                       keyStorePassword: String,
                                       keyStorePath: String,
                                       bindToIp: String,
                                       bindToPort: Int,
                                       keyStoreType: String = "PKCS12",
                                       keyFactoryType:String = "SunX509")

  def apply(route: Route, config: Config)(implicit actorSystem: ActorSystem): TLSWebSocketServer = {
    val c = TLSWebSocketServerConfig(
      config.getBoolean("httpsEnabled"),
      config.getString("keyStorePassword"),
      config.getString("keyStorePath"),
      config.getString("bindToIp"),
      config.getInt("bindToPort"),
      config.getString("keyStoreType"),
      config.getString("keyFactoryType")
    )
    new TLSWebSocketServer(route, c)
  }


}
class TLSWebSocketServer(
                       route: Route,
                       tlsConfig: TLSWebSocketServerConfig,
                     )(implicit actorSystem: ActorSystem) extends Logging {

  import tlsConfig._

  private lazy val password: Array[Char] = keyStorePassword.toCharArray

  private lazy val ks: KeyStore = KeyStore.getInstance(keyStoreType)

  private lazy val keystore: InputStream = {
    val attempt1 = new FileInputStream(new File(keyStorePath))
    Option(attempt1).getOrElse {
      val attempt2 = getClass.getClassLoader.getResourceAsStream(keyStorePath)
      Option(attempt2).getOrElse(
        throw new IllegalArgumentException(s"Cannot load keystore $keyStorePath")
      )
    }
  }

  ks.load(keystore, password)

  private lazy val keyManagerFactory: KeyManagerFactory = KeyManagerFactory.getInstance(keyFactoryType) // "SunX509"
  keyManagerFactory.init(ks, password)

  private lazy val tmf: TrustManagerFactory = TrustManagerFactory.getInstance(keyFactoryType) // "SunX509"
  tmf.init(ks)

  private lazy val sslContext: SSLContext = SSLContext.getInstance("TLS")
  sslContext.init(keyManagerFactory.getKeyManagers, tmf.getTrustManagers, new SecureRandom)
  private lazy val https: HttpsConnectionContext = ConnectionContext.httpsServer(sslContext)

  lazy val start = if(httpsEnabled) {
    Http()
      .newServerAt(bindToIp, bindToPort)
      .enableHttps(https)
      .bindFlow(route)

  } else {
    Http()
      .newServerAt(bindToIp, bindToPort)
      .bindFlow(route)

  }.onComplete {
    case Success(value) => log.info(value.toString)
    case Failure(err) => log.error(err.toString)
  }

}






© 2015 - 2024 Weber Informatics LLC | Privacy Policy