org.http4s.HttpApp Scala Examples
The following examples show how to use org.http4s.HttpApp.
You can vote up the ones you like or vote down the ones you don't like,
and go to the original project or source file by following the links above each example.
Example 1
Source File: CORSMiddleware.scala From iotchain with MIT License | 5 votes |
package jbok.network.http.server.middleware import cats.effect.ConcurrentEffect import org.http4s.HttpApp import org.http4s.server.middleware.{CORS, CORSConfig} import scala.concurrent.duration._ object CORSMiddleware { val defaultConfig: CORSConfig = CORSConfig( anyOrigin = true, allowCredentials = true, maxAge = 1.day.toSeconds, anyMethod = true ) private def corsConfig(allowedOriginsList: List[String]) = if (allowedOriginsList.isEmpty) { defaultConfig } else { defaultConfig.copy(anyOrigin = false, allowedOrigins = allowedOriginsList.toSet) } def apply[F[_]](http: HttpApp[F], allowedOrigins: List[String])(implicit F: ConcurrentEffect[F]): HttpApp[F] = CORS(http, corsConfig(allowedOrigins)) }
Example 2
Source File: Http4sClientSpec.scala From canoe with MIT License | 5 votes |
package canoe.api.clients import canoe.api._ import canoe.methods.Method import canoe.models.InputFile import cats.effect.IO import io.circe.{Decoder, Encoder} import org.http4s.HttpApp import org.http4s.client.Client import org.http4s.dsl.io._ import io.circe.Json import io.chrisdavenport.log4cats.slf4j.Slf4jLogger import org.scalatest.freespec.AnyFreeSpec class Http4sClientSpec extends AnyFreeSpec { private case class TestMethod(name: String = "test", encoder: Encoder[String] = Encoder.encodeString, decoder: Decoder[String] = Decoder.decodeString, files: List[InputFile] = Nil) extends Method[String, String] { def attachments(request: String): List[(String, InputFile)] = files.map("" -> _) } private implicit val testMethod = TestMethod() private def response(s: String) = s"""{"ok" : true, "result" : "$s"}""" private implicit val logger = Slf4jLogger.getLogger[IO] "Client" - { "sends" - { "to correct Telegram endpoint" in { val client: Client[IO] = Client.fromHttpApp(HttpApp(r => Ok(response(r.uri.toString)))) val tgClient = new Http4sTelegramClient("token", client) assert(tgClient.execute("any").unsafeRunSync() == s"https://api.telegram.org/bottoken/${testMethod.name}") } val tgClient = new Http4sTelegramClient("", Client.fromHttpApp(HttpApp[IO] { r => Ok(response(r.headers.get(org.http4s.headers.`Content-Type`).map(_.value.replace("\"", "''")).getOrElse(""))) })) "json POST request if attachments contain file upload" in { assert(tgClient.execute("any").unsafeRunSync() == "application/json") } "multipart POST request if attachments contain file upload" in { val resp = tgClient.execute("any")(testMethod.copy(files = List(InputFile.Upload("", Array.emptyByteArray)))) assert(resp.unsafeRunSync().startsWith("multipart/form-data")) } } "encodes/decodes" - { "request entity with method encoder" in { val tgClient = new Http4sTelegramClient( "", Client.fromHttpApp(HttpApp[IO](_.bodyAsText.compile.string.flatMap(s => Ok(response(s.replace("\"", "'")))))) ) val res = tgClient.execute("")(testMethod.copy(encoder = Encoder.instance(_ => Json.fromString("encoded")))) assert(res.unsafeRunSync() == "'encoded'") } "result entity with method decoder" in { val tgClient = new Http4sTelegramClient("", Client.fromHttpApp(HttpApp[IO](_ => Ok(response(""))))) val res = tgClient.execute("")(testMethod.copy(decoder = Decoder.const("decoded"))) assert(res.unsafeRunSync() == "decoded") } } "handles" - { "decode failure as ResponseDecodingError" in { val tgClient = new Http4sTelegramClient("", Client.fromHttpApp(HttpApp[IO](_ => Ok("{}")))) assertThrows[ResponseDecodingError](tgClient.execute("any").unsafeRunSync()) } "unsuccessful result as FailedMethod" in { val response = """{"ok" : false, "result" : "any"}""" val tgClient = new Http4sTelegramClient("", Client.fromHttpApp(HttpApp[IO](_ => Ok(response)))) assertThrows[FailedMethod[String, String]](tgClient.execute("any").unsafeRunSync()) } } } }
Example 3
Source File: JoexServer.scala From docspell with GNU General Public License v3.0 | 5 votes |
package docspell.joex import cats.effect._ import cats.effect.concurrent.Ref import fs2.Stream import fs2.concurrent.SignallingRef import docspell.common.Pools import docspell.joex.routes._ import org.http4s.HttpApp import org.http4s.implicits._ import org.http4s.server.Router import org.http4s.server.blaze.BlazeServerBuilder import org.http4s.server.middleware.Logger object JoexServer { private case class App[F[_]]( httpApp: HttpApp[F], termSig: SignallingRef[F, Boolean], exitRef: Ref[F, ExitCode] ) def stream[F[_]: ConcurrentEffect: ContextShift]( cfg: Config, pools: Pools )(implicit T: Timer[F]): Stream[F, Nothing] = { val app = for { signal <- Resource.liftF(SignallingRef[F, Boolean](false)) exitCode <- Resource.liftF(Ref[F].of(ExitCode.Success)) joexApp <- JoexAppImpl .create[F](cfg, signal, pools.connectEC, pools.httpClientEC, pools.blocker) httpApp = Router( "/api/info" -> InfoRoutes(), "/api/v1" -> JoexRoutes(joexApp) ).orNotFound // With Middlewares in place finalHttpApp = Logger.httpApp(false, false)(httpApp) } yield App(finalHttpApp, signal, exitCode) Stream .resource(app) .flatMap(app => BlazeServerBuilder[F](pools.restEC) .bindHttp(cfg.bind.port, cfg.bind.address) .withHttpApp(app.httpApp) .withoutBanner .serveWhile(app.termSig, app.exitRef) ) }.drain }
Example 4
Source File: Tracer.scala From http4s-tracer with Apache License 2.0 | 5 votes |
package dev.profunktor.tracer import cats.Applicative import cats.data.Kleisli import cats.effect.Sync import cats.syntax.all._ import org.http4s.syntax.StringSyntax import org.http4s.{Header, HttpApp, Request} object Tracer extends StringSyntax { private[tracer] val DefaultTraceIdHeader = "Trace-Id" final case class TraceId(value: String) extends AnyVal { override def toString = s"[Trace-Id] - [$value]" } def apply[F[_]](implicit ev: Tracer[F]): Tracer[F] = ev def create[F[_]](headerName: String = DefaultTraceIdHeader): Tracer[F] = new Tracer[F](headerName) } class Tracer[F[_]] private (headerName: String) { import Trace._, Tracer._ def middleware( http: HttpApp[F], logRequest: Boolean = false, logResponse: Boolean = false )(implicit F: Sync[F], L: TracerLog[Trace[F, ?]]): HttpApp[F] = Kleisli { req => val createId: F[(Request[F], TraceId)] = for { id <- GenUUID.make[F] tr <- F.delay(req.putHeaders(Header(headerName, id.value))) } yield (tr, id) for { mi <- getTraceId(req) (tr, id) <- mi.fold(createId)(id => (req, id).pure[F]) _ <- if (logRequest) L.info[Tracer[F]](s"$req").run(id) else F.unit rs <- http(tr).map(_.putHeaders(Header(headerName, id.value))) _ <- if (logResponse) L.info[Tracer[F]](s"$rs").run(id) else F.unit } yield rs } def loggingMiddleware( http: HttpApp[F] )(implicit F: Sync[F], L: TracerLog[Trace[F, ?]]): HttpApp[F] = middleware(http, logRequest = true, logResponse = true) def getTraceId(request: Request[F])(implicit F: Applicative[F]): F[Option[TraceId]] = F.pure(request.headers.get(headerName.ci).map(h => TraceId(h.value))) }
Example 5
Source File: SparqlClientSpec.scala From nexus with Apache License 2.0 | 5 votes |
package ch.epfl.bluebrain.nexus.cli.clients import cats.effect.IO import cats.implicits._ import ch.epfl.bluebrain.nexus.cli.{AbstractCliSpec, Console} import ch.epfl.bluebrain.nexus.cli.CliError.ClientError.{ClientStatusError, ServerStatusError} import ch.epfl.bluebrain.nexus.cli.config.{AppConfig, EnvConfig} import ch.epfl.bluebrain.nexus.cli.sse._ import ch.epfl.bluebrain.nexus.cli.utils.Http4sExtras import izumi.distage.model.definition.ModuleDef import org.http4s.circe.CirceEntityEncoder._ import org.http4s.client.Client import org.http4s.dsl.io._ import org.http4s.headers.`Content-Type` import org.http4s.{HttpApp, Response, Status, Uri} import org.scalatest.OptionValues class SparqlClientSpec extends AbstractCliSpec with Http4sExtras with OptionValues { private val sparqlResultsJson = jsonContentOf("/templates/sparql-results.json") private val sparqlResults = sparqlResultsJson.as[SparqlResults].toOption.value private val query = "SELECT * {?s ?p ?o} LIMIT 10" override def overrides: ModuleDef = new ModuleDef { include(defaultModules) make[Client[IO]].from { cfg: AppConfig => val token = cfg.env.token val ct = `Content-Type`(SparqlClient.`application/sparql-query`) val view = cfg.env.defaultSparqlView.renderString val httpApp = HttpApp[IO] { // success case req @ POST -> `v1` / "views" / OrgLabelVar(`orgLabel`) / ProjectLabelVar( `projectLabel` ) / `view` / "sparql" contentType `ct` optbearer `token` => req.as[String].flatMap { case `query` => Response[IO](Status.Ok).withEntity(sparqlResultsJson).pure[IO] case _ => Response[IO](Status.BadRequest).pure[IO] } // unknown view id case req @ POST -> `v1` / "views" / OrgLabelVar(`orgLabel`) / ProjectLabelVar( `projectLabel` ) / (_: String) / "sparql" contentType `ct` optbearer `token` => req.as[String].flatMap { case `query` => Response[IO](Status.NotFound).withEntity(notFoundJson).pure[IO] case _ => Response[IO](Status.BadRequest).pure[IO] } // unknown token case req @ POST -> `v1` / "views" / OrgLabelVar(`orgLabel`) / ProjectLabelVar( `projectLabel` ) / `view` / "sparql" contentType `ct` optbearer (_: Option[ BearerToken ]) => req.as[String].flatMap { case `query` => Response[IO](Status.Forbidden).withEntity(authFailedJson).pure[IO] case _ => Response[IO](Status.BadRequest).pure[IO] } // other - internal error case req @ POST -> "v1" /: (_: Path) contentType `ct` optbearer `token` => req.as[String].flatMap { case `query` => Response[IO](Status.InternalServerError).withEntity(internalErrorJson).pure[IO] case _ => Response[IO](Status.BadRequest).pure[IO] } } Client.fromHttpApp(httpApp) } } "A SparqlClient" should { "return sparql results" in { (client: Client[IO], console: Console[IO], env: EnvConfig) => val cl = SparqlClient(client, env, console) for { results <- cl.query(orgLabel, projectLabel, query) _ = results shouldEqual Right(sparqlResults) } yield () } "return not found" in { (client: Client[IO], console: Console[IO], env: EnvConfig) => val cl = SparqlClient(client, env, console) for { results <- cl.query(orgLabel, projectLabel, Uri.unsafeFromString(genString()), query) _ = results shouldEqual Left(ClientStatusError(Status.NotFound, notFoundJson.noSpaces)) } yield () } "return internal error" in { (client: Client[IO], console: Console[IO], env: EnvConfig) => val cl = SparqlClient(client, env, console) for { results <- cl.query(orgLabel, ProjectLabel(genString()), Uri.unsafeFromString(genString()), query) _ = results shouldEqual Left(ServerStatusError(Status.InternalServerError, internalErrorJson.noSpaces)) } yield () } "return bad token" in { (client: Client[IO], console: Console[IO], env: EnvConfig) => val cl = SparqlClient(client, env.copy(token = Some(BearerToken("bad"))), console) for { results <- cl.query(orgLabel, projectLabel, query) _ = results shouldEqual Left(ClientStatusError(Status.Forbidden, authFailedJson.noSpaces)) } yield () } } }
Example 6
Source File: ProjectClientSpec.scala From nexus with Apache License 2.0 | 5 votes |
package ch.epfl.bluebrain.nexus.cli.clients import java.util.UUID import cats.effect.IO import cats.effect.concurrent.Ref import cats.implicits._ import ch.epfl.bluebrain.nexus.cli.{AbstractCliSpec, Console} import ch.epfl.bluebrain.nexus.cli.CliError.ClientError.ClientStatusError import ch.epfl.bluebrain.nexus.cli.config.{AppConfig, EnvConfig} import ch.epfl.bluebrain.nexus.cli.sse._ import ch.epfl.bluebrain.nexus.cli.utils.Http4sExtras import izumi.distage.model.definition.ModuleDef import org.http4s.circe.CirceEntityEncoder._ import org.http4s.client.Client import org.http4s.dsl.io._ import org.http4s.{HttpApp, Response, Status} class ProjectClientSpec extends AbstractCliSpec with Http4sExtras { private val projectJson = jsonContentOf("/templates/project.json", replacements) type Cache = Map[(OrgUuid, ProjectUuid), (OrgLabel, ProjectLabel)] type CacheRef = Ref[IO, Cache] override def overrides: ModuleDef = new ModuleDef { include(defaultModules) make[Client[IO]].from { cfg: AppConfig => val token = cfg.env.token val httpApp = HttpApp[IO] { case GET -> `v1` / "projects" / OrgUuidVar(`orgUuid`) / ProjectUuidVar(`projectUuid`) optbearer `token` => Response[IO](Status.Ok).withEntity(projectJson).pure[IO] case GET -> `v1` / "projects" / OrgUuidVar(_) / ProjectUuidVar(_) optbearer `token` => Response[IO](Status.NotFound).withEntity(notFoundJson).pure[IO] case GET -> `v1` / "projects" / OrgUuidVar(_) / ProjectUuidVar(_) bearer (_: BearerToken) => Response[IO](Status.Forbidden).withEntity(authFailedJson).pure[IO] } Client.fromHttpApp(httpApp) } make[CacheRef].fromEffect { Ref.of[IO, Cache](Map.empty) } } "A ProjectClient" should { "resolve a known (orgUuid, projUuid) pair" in { (client: Client[IO], console: Console[IO], cache: CacheRef, env: EnvConfig) => val cl = ProjectClient[IO](client, env, cache, console) for { labels <- cl.labels(orgUuid, projectUuid) _ = labels shouldEqual Right((orgLabel, projectLabel)) } yield () } "resolve from cache a known (orgUuid, projUuid) pair" in { (client: Client[IO], console: Console[IO], cache: CacheRef, env: EnvConfig) => val errClient = Client.fromHttpApp(HttpApp[IO] { case GET -> Root => IO.pure(Response[IO](Status.NotFound)) }) for { _ <- ProjectClient[IO](client, env, cache, console).labels(orgUuid, projectUuid) labels <- ProjectClient[IO](errClient, env, cache, console).labels(orgUuid, projectUuid) _ = labels shouldEqual Right((orgLabel, projectLabel)) } yield () } "fail to resolve an unknown (orgUuid, projUuid) pair" in { (client: Client[IO], console: Console[IO], cache: CacheRef, env: EnvConfig) => val cl = ProjectClient[IO](client, env, cache, console) for { labels <- cl.labels(OrgUuid(UUID.randomUUID()), projectUuid) _ = labels shouldEqual Left(ClientStatusError(Status.NotFound, notFoundJson.noSpaces)) } yield () } "fail to resolve a known (orgUuid, projUuid) pair with bad credentials" in { (client: Client[IO], console: Console[IO], cache: CacheRef, env: EnvConfig) => val cl = ProjectClient[IO](client, env.copy(token = Some(BearerToken("bad"))), cache, console) for { labels <- cl.labels(orgUuid, projectUuid) _ = labels shouldEqual Left(ClientStatusError(Status.Forbidden, authFailedJson.noSpaces)) } yield () } } }
Example 7
Source File: SagaEndpoint.scala From zio-saga with MIT License | 5 votes |
package com.vladkopanev.zio.saga.example.endpoint import com.vladkopanev.zio.saga.example.{ OrderSagaCoordinator, TaskC } import com.vladkopanev.zio.saga.example.model.OrderInfo import org.http4s.circe._ import org.http4s.dsl.Http4sDsl import org.http4s.implicits._ import org.http4s.{ HttpApp, HttpRoutes } import zio.interop.catz._ final class SagaEndpoint(orderSagaCoordinator: OrderSagaCoordinator) extends Http4sDsl[TaskC] { private implicit val decoder = jsonOf[TaskC, OrderInfo] val service: HttpApp[TaskC] = HttpRoutes .of[TaskC] { case req @ POST -> Root / "saga" / "finishOrder" => for { OrderInfo(userId, orderId, money, bonuses) <- req.as[OrderInfo] resp <- orderSagaCoordinator .runSaga(userId, orderId, money, bonuses, None) .foldM(fail => InternalServerError(fail.getMessage), _ => Ok("Saga submitted")) } yield resp } .orNotFound }
Example 8
Source File: LoginTest.scala From scala-pet-store with Apache License 2.0 | 5 votes |
package io.github.pauljamescleary.petstore package infrastructure.endpoint import cats.data.Kleisli import cats.effect.IO import domain.authentication.{LoginRequest, SignupRequest} import domain.users.{Role, User} import org.http4s.circe.{jsonEncoderOf, jsonOf} import org.http4s.client.dsl.Http4sClientDsl import org.http4s.{EntityDecoder, EntityEncoder, HttpApp, Request, Response} import org.http4s.implicits._ import org.http4s.headers.Authorization import io.circe.generic.auto._ import org.http4s.dsl.Http4sDsl trait LoginTest extends Http4sClientDsl[IO] with Http4sDsl[IO] { implicit val userEnc: EntityEncoder[IO, User] = jsonEncoderOf implicit val userDec: EntityDecoder[IO, User] = jsonOf implicit val signUpRequestEnc: EntityEncoder[IO, SignupRequest] = jsonEncoderOf implicit val signUpRequestDec: EntityDecoder[IO, SignupRequest] = jsonOf implicit val loginRequestEnc: EntityEncoder[IO, LoginRequest] = jsonEncoderOf implicit val loginRequestDec: EntityDecoder[IO, LoginRequest] = jsonOf def signUpAndLogIn( userSignUp: SignupRequest, userEndpoint: HttpApp[IO], ): IO[(User, Option[Authorization])] = for { signUpRq <- POST(userSignUp, uri"/users") signUpResp <- userEndpoint.run(signUpRq) user <- signUpResp.as[User] loginBody = LoginRequest(userSignUp.userName, userSignUp.password) loginRq <- POST(loginBody, uri"/users/login") loginResp <- userEndpoint.run(loginRq) } yield { user -> loginResp.headers.get(Authorization) } def signUpAndLogInAsAdmin( userSignUp: SignupRequest, userEndpoint: Kleisli[IO, Request[IO], Response[IO]], ): IO[(User, Option[Authorization])] = signUpAndLogIn(userSignUp.copy(role = Role.Admin), userEndpoint) def signUpAndLogInAsCustomer( userSignUp: SignupRequest, userEndpoint: Kleisli[IO, Request[IO], Response[IO]], ): IO[(User, Option[Authorization])] = signUpAndLogIn(userSignUp.copy(role = Role.Customer), userEndpoint) }
Example 9
Source File: BidderHttpAppBuilder.scala From scala-openrtb with Apache License 2.0 | 5 votes |
package com.powerspace.openrtb.examples.rtb.http4s.bidder import com.google.openrtb.BidRequest import com.powerspace.openrtb.examples.rtb.http4s.common.ExampleSerdeModule import io.circe.Decoder import monix.eval.Task import org.http4s.dsl.Http4sDsl import org.http4s.{EntityDecoder, HttpApp} object BidderHttpAppBuilder { private val bidder = new Bidder[Task] private val dsl = Http4sDsl[Task] private val serdeModule = ExampleSerdeModule private def handleBid(bidRequest: BidRequest) = { import dsl._ import org.http4s.circe._ bidder .bidOn(bidRequest) .flatMap { case Some(bidResponse) => // encode the bidResponse to a json object as part of the http response body Ok(serdeModule.bidResponseEncoder(bidResponse)) case None => Ok() } } }
Example 10
Source File: Main.scala From http4s-poc-api with MIT License | 5 votes |
package server import java.util.concurrent.Executors import com.github.ghik.silencer.silent import external.{TeamOneHttpApi, TeamThreeCacheApi, TeamTwoHttpApi} import io.circe.generic.auto._ import log.effect.zio.ZioLogWriter._ import model.DomainModel._ import org.http4s.circe._ import org.http4s.server.Router import org.http4s.server.blaze.BlazeServerBuilder import org.http4s.syntax.kleisli._ import org.http4s.{EntityDecoder, EntityEncoder, HttpApp} import service.PriceService import zio.interop.catz._ import zio.interop.catz.implicits._ import zio.{ExitCode, RIO, Task, ZEnv, ZIO} import scala.concurrent.ExecutionContext import model.DomainModelCodecs._ @silent object Main extends zio.interop.catz.CatsApp with Pools with Codecs { private[this] val priceService: RIO[String, PriceService[Task]] = log4sFromName map { log => PriceService[Task]( TeamThreeCacheApi.productCache, TeamOneHttpApi(), TeamTwoHttpApi(), log ) } private[this] val httpApp: RIO[PriceService[Task], HttpApp[Task]] = ZIO.access { ps => Router( "/pricing-api/prices" -> PriceRoutes[Task].make(ps), "/pricing-api/health-check" -> HealthCheckRoutes[Task].make(ps.logger) ).orNotFound } private[this] val runningServer: RIO[HttpApp[Task], Unit] = ZIO.accessM { app => BlazeServerBuilder[Task](serverPool) .bindHttp(17171, "0.0.0.0") .withConnectorPoolSize(connectorPoolSize) .enableHttp2(true) .withHttpApp(app) .serve .compile .drain } private[this] val serviceRuntime: RIO[String, Unit] = priceService >>> httpApp >>> runningServer def run(args: List[String]): ZIO[ZEnv, Nothing, ExitCode] = serviceRuntime.fold(_ => ExitCode.failure, _ => ExitCode.success) provide "App log" } sealed trait Pools { protected val connectorPoolSize = Runtime.getRuntime.availableProcessors() * 2 protected val mainThreadNumber = Runtime.getRuntime.availableProcessors() + 1 protected val serverPool = ExecutionContext.fromExecutor( Executors.newWorkStealingPool(mainThreadNumber) ) } sealed trait Codecs { implicit val priceRequestPayloadDecoder: EntityDecoder[Task, PricesRequestPayload] = jsonOf[Task, PricesRequestPayload] implicit val priceResponsePayloadEncoder: EntityEncoder[Task, List[Price]] = jsonEncoderOf[Task, List[Price]] implicit val healthCheckResponsePayloadEncoder: EntityEncoder[Task, ServiceSignature] = jsonEncoderOf[Task, ServiceSignature] }
Example 11
Source File: Http4sRoutingModule.scala From scala-server-toolkit with MIT License | 5 votes |
package com.avast.sst.example.module import cats.implicits._ import com.avast.sst.example.service.RandomService import com.avast.sst.http4s.server.Http4sRouting import com.avast.sst.http4s.server.micrometer.MicrometerHttp4sServerMetricsModule import org.http4s.client.Client import org.http4s.dsl.Http4sDsl import org.http4s.{HttpApp, HttpRoutes} import zio.Task import zio.interop.catz._ class Http4sRoutingModule( randomService: RandomService, client: Client[Task], serverMetricsModule: MicrometerHttp4sServerMetricsModule[Task] ) extends Http4sDsl[Task] { import serverMetricsModule._ private val helloWorldRoute = routeMetrics.wrap("hello")(Ok("Hello World!")) private val routes = HttpRoutes.of[Task] { case GET -> Root / "hello" => helloWorldRoute case GET -> Root / "random" => randomService.randomNumber.map(_.show).flatMap(Ok(_)) case GET -> Root / "circuit-breaker" => client.expect[String]("https://httpbin.org/status/500").flatMap(Ok(_)) } val router: HttpApp[Task] = Http4sRouting.make { serverMetrics { routes } } }
Example 12
Source File: Http4sBlazeServerModule.scala From scala-server-toolkit with MIT License | 5 votes |
package com.avast.sst.http4s.server import java.net.{InetSocketAddress, StandardSocketOptions} import cats.effect.{ConcurrentEffect, Resource, Timer} import org.http4s.HttpApp import org.http4s.server.Server import org.http4s.server.blaze.BlazeServerBuilder import scala.concurrent.ExecutionContext import scala.concurrent.duration.Duration object Http4sBlazeServerModule { def make[F[_]: ConcurrentEffect: Timer]( config: Http4sBlazeServerConfig, httpApp: HttpApp[F], executionContext: ExecutionContext ): Resource[F, Server[F]] = { for { inetSocketAddress <- Resource.liftF( ConcurrentEffect[F].delay( InetSocketAddress.createUnresolved(config.listenAddress, config.listenPort) ) ) server <- BlazeServerBuilder[F](executionContext) .bindSocketAddress(inetSocketAddress) .withHttpApp(httpApp) .withoutBanner .withNio2(config.nio2Enabled) .withWebSockets(config.webSocketsEnabled) .enableHttp2(config.http2Enabled) .withResponseHeaderTimeout(Duration.fromNanos(config.responseHeaderTimeout.toNanos)) .withIdleTimeout(Duration.fromNanos(config.idleTimeout.toNanos)) .withBufferSize(config.bufferSize) .withMaxRequestLineLength(config.maxRequestLineLength) .withMaxHeadersLength(config.maxHeadersLength) .withChunkBufferMaxSize(config.chunkBufferMaxSize) .withConnectorPoolSize(config.connectorPoolSize) .withChannelOption[java.lang.Boolean](StandardSocketOptions.TCP_NODELAY, config.socketOptions.tcpNoDelay) .resource } yield server } }