From 8c54426af53ebbd39cf12f679c71bfcfd44365a1 Mon Sep 17 00:00:00 2001 From: Adam Fraser Date: Wed, 14 Jun 2023 15:20:30 -0700 Subject: [PATCH] Scope Requests (#2252) * scope requests * more scopes * format * update documentation --- docs/dsl/body.md | 2 +- docs/dsl/headers.md | 2 +- docs/examples/basic/http-client.md | 2 +- docs/examples/basic/https-client.md | 1 + .../zio/http/endpoint/cli/HttpCliApp.scala | 2 +- .../scala/example/AuthenticationClient.scala | 2 +- .../src/main/scala/example/CliExamples.scala | 3 +- .../src/main/scala/example/ClientServer.scala | 4 +- .../example/ClientWithDecompression.scala | 1 + .../main/scala/example/EndpointExamples.scala | 4 +- .../main/scala/example/GracefulShutdown.scala | 1 + .../src/main/scala/example/HttpsClient.scala | 1 + .../src/main/scala/example/Interrupt.scala | 1 + .../scala/example/MultipartFormData.scala | 3 +- .../src/main/scala/example/SimpleClient.scala | 2 +- .../test/scala/zio/http/TestServerSpec.scala | 5 +- .../src/main/scala/zio/http/ZClient.scala | 77 ++++++++++--------- .../main/scala/zio/http/ZClientAspect.scala | 4 +- .../zio/http/endpoint/EndpointExecutor.scala | 2 +- .../endpoint/internal/EndpointClient.scala | 2 +- .../test/scala/zio/http/ClientHttpsSpec.scala | 3 +- .../test/scala/zio/http/ClientProxySpec.scala | 3 + .../scala/zio/http/ClientStreamingSpec.scala | 3 +- .../test/scala/zio/http/DynamicAppTest.scala | 3 +- .../zio/http/NettyMaxHeaderLengthSpec.scala | 1 + .../zio/http/ResponseCompressionSpec.scala | 3 +- .../src/test/scala/zio/http/SSLSpec.scala | 7 +- .../scala/zio/http/ZClientAspectSpec.scala | 1 + .../ServerClientIntegrationSpec.scala | 19 ++--- .../zio/http/internal/HttpRunnableSpec.scala | 6 +- .../zio/http/netty/NettyStreamBodySpec.scala | 1 + 31 files changed, 98 insertions(+), 73 deletions(-) diff --git a/docs/dsl/body.md b/docs/dsl/body.md index dedd45e103..c9e439e257 100644 --- a/docs/dsl/body.md +++ b/docs/dsl/body.md @@ -30,7 +30,7 @@ On the client-side, `ZIO-HTTP` models content in `ClientRequest` as `Body` with To add content while making a request using ZIO HTTP you can use the `Client.request` method: ```scala mdoc:silent - val actual: ZIO[Client, Throwable, Response] = + val actual: ZIO[Client with Scope, Throwable, Response] = Client.request("https://localhost:8073/success", content = Body.fromString("Some string")) ``` diff --git a/docs/dsl/headers.md b/docs/dsl/headers.md index caa8d51bfb..e30ab133de 100644 --- a/docs/dsl/headers.md +++ b/docs/dsl/headers.md @@ -175,7 +175,7 @@ object SimpleClientJson extends ZIOAppDefault { } yield () override def run = - program.provide(Client.default) + program.provide(Client.default, Scope.default) } ``` diff --git a/docs/examples/basic/http-client.md b/docs/examples/basic/http-client.md index 0e6d99acef..fdcddb97a4 100644 --- a/docs/examples/basic/http-client.md +++ b/docs/examples/basic/http-client.md @@ -18,7 +18,7 @@ object SimpleClient extends ZIOAppDefault { _ <- Console.printLine(data) } yield () - override val run = program.provide(Client.default) + override val run = program.provide(Client.default, Scope.default) } diff --git a/docs/examples/basic/https-client.md b/docs/examples/basic/https-client.md index 4367b53c2a..2b227ffc97 100644 --- a/docs/examples/basic/https-client.md +++ b/docs/examples/basic/https-client.md @@ -35,6 +35,7 @@ object HttpsClient extends ZIOAppDefault { NettyClientDriver.live, DnsResolver.default, ZLayer.succeed(NettyConfig.default), + Scope.default, ) } diff --git a/zio-http-cli/src/main/scala/zio/http/endpoint/cli/HttpCliApp.scala b/zio-http-cli/src/main/scala/zio/http/endpoint/cli/HttpCliApp.scala index 1a5b637d97..37d4654727 100644 --- a/zio-http-cli/src/main/scala/zio/http/endpoint/cli/HttpCliApp.scala +++ b/zio-http-cli/src/main/scala/zio/http/endpoint/cli/HttpCliApp.scala @@ -98,7 +98,7 @@ object HttpCliApp { ) .setHeaders(headers), ) - .provide(Client.default) + .provide(Client.default, Scope.default) _ <- Console.printLine(s"Got response") _ <- Console.printLine(s"Status: ${response.status}") body <- response.body.asString diff --git a/zio-http-example/src/main/scala/example/AuthenticationClient.scala b/zio-http-example/src/main/scala/example/AuthenticationClient.scala index 99a7533caa..5e98f01159 100644 --- a/zio-http-example/src/main/scala/example/AuthenticationClient.scala +++ b/zio-http-example/src/main/scala/example/AuthenticationClient.scala @@ -22,6 +22,6 @@ object AuthenticationClient extends ZIOAppDefault { _ <- Console.printLine(body) } yield () - override val run = program.provide(Client.default) + override val run = program.provide(Client.default, Scope.default) } diff --git a/zio-http-example/src/main/scala/example/CliExamples.scala b/zio-http-example/src/main/scala/example/CliExamples.scala index f426257504..737a18ce4f 100644 --- a/zio-http-example/src/main/scala/example/CliExamples.scala +++ b/zio-http-example/src/main/scala/example/CliExamples.scala @@ -101,9 +101,10 @@ object TestCliClient extends zio.ZIOAppDefault with TestCliEndpoints { .provide( EndpointExecutor.make(serviceName = "test"), Client.default, + Scope.default, ) - lazy val clientExample: URIO[EndpointExecutor[Unit], Unit] = + lazy val clientExample: URIO[EndpointExecutor[Unit] & Scope, Unit] = for { executor <- ZIO.service[EndpointExecutor[Unit]] _ <- executor(getUser(42, Location.parse("some-location").toOption.get)).debug("result1") diff --git a/zio-http-example/src/main/scala/example/ClientServer.scala b/zio-http-example/src/main/scala/example/ClientServer.scala index 9be2634c4c..f1e537adef 100644 --- a/zio-http-example/src/main/scala/example/ClientServer.scala +++ b/zio-http-example/src/main/scala/example/ClientServer.scala @@ -1,6 +1,6 @@ package example -import zio.{ZIO, ZIOAppDefault} +import zio.{Scope, ZIO, ZIOAppDefault} import zio.http._ @@ -16,6 +16,6 @@ object ClientServer extends ZIOAppDefault { } val run = { - Server.serve(app.withDefaultErrorResponse).provide(Server.default, Client.default).exitCode + Server.serve(app.withDefaultErrorResponse).provide(Server.default, Client.default, Scope.default).exitCode } } diff --git a/zio-http-example/src/main/scala/example/ClientWithDecompression.scala b/zio-http-example/src/main/scala/example/ClientWithDecompression.scala index f11a930b40..151cc054e1 100644 --- a/zio-http-example/src/main/scala/example/ClientWithDecompression.scala +++ b/zio-http-example/src/main/scala/example/ClientWithDecompression.scala @@ -22,6 +22,7 @@ object ClientWithDecompression extends ZIOAppDefault { Client.live, ZLayer.succeed(NettyConfig.default), DnsResolver.default, + Scope.default, ) } diff --git a/zio-http-example/src/main/scala/example/EndpointExamples.scala b/zio-http-example/src/main/scala/example/EndpointExamples.scala index 44ea41b1f9..e7d2d21acd 100644 --- a/zio-http-example/src/main/scala/example/EndpointExamples.scala +++ b/zio-http-example/src/main/scala/example/EndpointExamples.scala @@ -51,8 +51,8 @@ object EndpointExamples extends ZIOAppDefault { val x1 = getUser(42) val x2 = getUserPosts(42, 200, "adam") - val result1: UIO[Int] = executor(x1) - val result2: UIO[List[String]] = executor(x2) + val result1: ZIO[Scope, Nothing, Int] = executor(x1) + val result2: ZIO[Scope, Nothing, List[String]] = executor(x2) result1.zip(result2).debug } diff --git a/zio-http-example/src/main/scala/example/GracefulShutdown.scala b/zio-http-example/src/main/scala/example/GracefulShutdown.scala index 0501268fbc..672a8752a7 100644 --- a/zio-http-example/src/main/scala/example/GracefulShutdown.scala +++ b/zio-http-example/src/main/scala/example/GracefulShutdown.scala @@ -52,5 +52,6 @@ object GracefulShutdown extends ZIOAppDefault { _ <- Console.printLine(body) } yield ()).provide( Client.default, + Scope.default, ) } diff --git a/zio-http-example/src/main/scala/example/HttpsClient.scala b/zio-http-example/src/main/scala/example/HttpsClient.scala index eea08c2dde..a91952b7cb 100644 --- a/zio-http-example/src/main/scala/example/HttpsClient.scala +++ b/zio-http-example/src/main/scala/example/HttpsClient.scala @@ -30,6 +30,7 @@ object HttpsClient extends ZIOAppDefault { NettyClientDriver.live, DnsResolver.default, ZLayer.succeed(NettyConfig.default), + Scope.default, ) } diff --git a/zio-http-example/src/main/scala/example/Interrupt.scala b/zio-http-example/src/main/scala/example/Interrupt.scala index b13a97cc13..746897f8fe 100644 --- a/zio-http-example/src/main/scala/example/Interrupt.scala +++ b/zio-http-example/src/main/scala/example/Interrupt.scala @@ -45,6 +45,7 @@ object MyClient extends ZIOAppDefault { ZLayer.succeed(ZClient.Config.default.withFixedConnectionPool(2)), ZLayer.succeed(NettyConfig.default), DnsResolver.default, + Scope.default, ) // .provide(Client.live, NettyClientDriver.fromConfig, ClientConfig.live(ClientConfig().withFixedConnectionPool(2))) .debug("EXIT") diff --git a/zio-http-example/src/main/scala/example/MultipartFormData.scala b/zio-http-example/src/main/scala/example/MultipartFormData.scala index d64f4b00c6..c118f7afea 100644 --- a/zio-http-example/src/main/scala/example/MultipartFormData.scala +++ b/zio-http-example/src/main/scala/example/MultipartFormData.scala @@ -38,7 +38,7 @@ object MultipartFormData extends ZIOAppDefault { } yield response } - private def program: ZIO[Client with Server, Throwable, Unit] = + private def program: ZIO[Client with Server with Scope, Throwable, Unit] = for { port <- Server.install(app) _ <- ZIO.logInfo(s"Server started on port $port") @@ -70,5 +70,6 @@ object MultipartFormData extends ZIOAppDefault { .provide( Server.default, Client.default, + Scope.default, ) } diff --git a/zio-http-example/src/main/scala/example/SimpleClient.scala b/zio-http-example/src/main/scala/example/SimpleClient.scala index b3ad169a4b..15a730186d 100644 --- a/zio-http-example/src/main/scala/example/SimpleClient.scala +++ b/zio-http-example/src/main/scala/example/SimpleClient.scala @@ -13,6 +13,6 @@ object SimpleClient extends ZIOAppDefault { _ <- Console.printLine(data) } yield () - override val run = program.provide(Client.default) + override val run = program.provide(Client.default, Scope.default) } diff --git a/zio-http-testkit/src/test/scala/zio/http/TestServerSpec.scala b/zio-http-testkit/src/test/scala/zio/http/TestServerSpec.scala index 0839971293..86affb2261 100644 --- a/zio-http-testkit/src/test/scala/zio/http/TestServerSpec.scala +++ b/zio-http-testkit/src/test/scala/zio/http/TestServerSpec.scala @@ -32,7 +32,7 @@ object TestServerSpec extends ZIOSpecDefault { ) } yield assertTrue(response1.status == Status.Ok) && assertTrue(response2.status == Status.InternalServerError) - }.provideSome[Client with Driver]( + }.provideSome[Client with Driver with Scope]( TestServer.layer, ), suite("Exact Request=>Response version")( @@ -79,13 +79,14 @@ object TestServerSpec extends ZIOSpecDefault { } yield assertTrue(finalResponse.status == Status.NotFound) }, ) - .provideSome[Client with Driver]( + .provideSome[Client with Driver with Scope]( TestServer.layer, ), ).provide( ZLayer.succeed(Server.Config.default.onAnyOpenPort), Client.default, NettyDriver.live, + Scope.default, ) private def requestToCorrectPort = diff --git a/zio-http/src/main/scala/zio/http/ZClient.scala b/zio-http/src/main/scala/zio/http/ZClient.scala index fa949e5a1e..5aed0e5c99 100644 --- a/zio-http/src/main/scala/zio/http/ZClient.scala +++ b/zio-http/src/main/scala/zio/http/ZClient.scala @@ -54,7 +54,7 @@ trait ZClient[-Env, -In, +Err, +Out] extends HeaderOps[ZClient[Env, In, Err, Out headers: Headers, body: In, sslConfig: Option[ClientSSLConfig], - )(implicit trace: Trace): ZIO[Env, Err, Out] = + )(implicit trace: Trace): ZIO[Env & Scope, Err, Out] = self.request( version, method, @@ -113,7 +113,7 @@ trait ZClient[-Env, -In, +Err, +Out] extends HeaderOps[ZClient[Env, In, Err, Out headers: Headers, body: In2, sslConfig: Option[ClientSSLConfig], - )(implicit trace: Trace): ZIO[Env1, Err1, Out] = + )(implicit trace: Trace): ZIO[Env1 & Scope, Err1, Out] = f(body).flatMap { body => self.request( version, @@ -134,13 +134,13 @@ trait ZClient[-Env, -In, +Err, +Out] extends HeaderOps[ZClient[Env, In, Err, Out self.socket(version, url, headers, app) } - final def delete(pathSuffix: String, body: In)(implicit trace: Trace): ZIO[Env, Err, Out] = + final def delete(pathSuffix: String, body: In)(implicit trace: Trace): ZIO[Env & Scope, Err, Out] = request(Method.DELETE, pathSuffix, body) - final def delete(pathSuffix: String)(implicit trace: Trace, ev: Body <:< In): ZIO[Env, Err, Out] = + final def delete(pathSuffix: String)(implicit trace: Trace, ev: Body <:< In): ZIO[Env & Scope, Err, Out] = delete(pathSuffix, ev(Body.empty)) - final def delete(implicit trace: Trace, ev: Body <:< In): ZIO[Env, Err, Out] = + final def delete(implicit trace: Trace, ev: Body <:< In): ZIO[Env & Scope, Err, Out] = delete("") final def dieOn( @@ -148,22 +148,22 @@ trait ZClient[-Env, -In, +Err, +Out] extends HeaderOps[ZClient[Env, In, Err, Out )(implicit ev1: Err IsSubtypeOfError Throwable, ev2: CanFail[Err], trace: Trace): ZClient[Env, In, Err, Out] = refineOrDie { case e if !f(e) => e } - final def get(pathSuffix: String, body: In)(implicit trace: Trace): ZIO[Env, Err, Out] = + final def get(pathSuffix: String, body: In)(implicit trace: Trace): ZIO[Env & Scope, Err, Out] = request(Method.GET, pathSuffix, body) - final def get(pathSuffix: String)(implicit trace: Trace, ev: Body <:< In): ZIO[Env, Err, Out] = + final def get(pathSuffix: String)(implicit trace: Trace, ev: Body <:< In): ZIO[Env & Scope, Err, Out] = get(pathSuffix, ev(Body.empty)) - final def get(implicit trace: Trace, ev: Body <:< In): ZIO[Env, Err, Out] = + final def get(implicit trace: Trace, ev: Body <:< In): ZIO[Env & Scope, Err, Out] = get("") - final def head(pathSuffix: String, body: In)(implicit trace: Trace): ZIO[Env, Err, Out] = + final def head(pathSuffix: String, body: In)(implicit trace: Trace): ZIO[Env & Scope, Err, Out] = request(Method.HEAD, pathSuffix, body) - final def head(pathSuffix: String)(implicit trace: Trace, ev: Body <:< In): ZIO[Env, Err, Out] = + final def head(pathSuffix: String)(implicit trace: Trace, ev: Body <:< In): ZIO[Env & Scope, Err, Out] = head(pathSuffix, Body.empty) - final def head(implicit trace: Trace, ev: Body <:< In): ZIO[Env, Err, Out] = + final def head(implicit trace: Trace, ev: Body <:< In): ZIO[Env & Scope, Err, Out] = head("") final def host(host: String): ZClient[Env, In, Err, Out] = @@ -186,7 +186,7 @@ trait ZClient[-Env, -In, +Err, +Out] extends HeaderOps[ZClient[Env, In, Err, Out headers: Headers, body: In, sslConfig: Option[ClientSSLConfig], - )(implicit trace: Trace): ZIO[Env, Err2, Out] = + )(implicit trace: Trace): ZIO[Env & Scope, Err2, Out] = self.request(version, method, url, headers, body, sslConfig).mapError(f) def socket[Env1 <: Env]( @@ -217,7 +217,7 @@ trait ZClient[-Env, -In, +Err, +Out] extends HeaderOps[ZClient[Env, In, Err, Out headers: Headers, body: In, sslConfig: Option[ClientSSLConfig], - )(implicit trace: Trace): ZIO[Env1, Err1, Out2] = + )(implicit trace: Trace): ZIO[Env1 & Scope, Err1, Out2] = self .request( version, @@ -244,13 +244,13 @@ trait ZClient[-Env, -In, +Err, +Out] extends HeaderOps[ZClient[Env, In, Err, Out final def port(port: Int): ZClient[Env, In, Err, Out] = copy(url = url.withPort(port)) - final def patch(pathSuffix: String, body: In)(implicit trace: Trace): ZIO[Env, Err, Out] = + final def patch(pathSuffix: String, body: In)(implicit trace: Trace): ZIO[Env & Scope, Err, Out] = request(Method.PATCH, pathSuffix, body) - final def post(pathSuffix: String, body: In)(implicit trace: Trace): ZIO[Env, Err, Out] = + final def post(pathSuffix: String, body: In)(implicit trace: Trace): ZIO[Env & Scope, Err, Out] = request(Method.POST, pathSuffix, body) - final def put(pathSuffix: String, body: In)(implicit trace: Trace): ZIO[Env, Err, Out] = + final def put(pathSuffix: String, body: In)(implicit trace: Trace): ZIO[Env & Scope, Err, Out] = request(Method.PUT, pathSuffix, body) def query(key: String, value: String): ZClient[Env, In, Err, Out] = @@ -277,7 +277,7 @@ trait ZClient[-Env, -In, +Err, +Out] extends HeaderOps[ZClient[Env, In, Err, Out headers: Headers, body: In, sslConfig: Option[ClientSSLConfig], - )(implicit trace: Trace): ZIO[Env, Err2, Out] = + )(implicit trace: Trace): ZIO[Env & Scope, Err2, Out] = self .request( version, @@ -298,7 +298,7 @@ trait ZClient[-Env, -In, +Err, +Out] extends HeaderOps[ZClient[Env, In, Err, Out self.socket(version, url, headers, app).refineOrDie(pf) } - final def request(method: Method, pathSuffix: String, body: In)(implicit trace: Trace): ZIO[Env, Err, Out] = + final def request(method: Method, pathSuffix: String, body: In)(implicit trace: Trace): ZIO[Env & Scope, Err, Out] = request( version, method, @@ -308,7 +308,7 @@ trait ZClient[-Env, -In, +Err, +Out] extends HeaderOps[ZClient[Env, In, Err, Out sslConfig, ) - final def request(request: Request)(implicit ev: Body <:< In, trace: Trace): ZIO[Env, Err, Out] = { + final def request(request: Request)(implicit ev: Body <:< In, trace: Trace): ZIO[Env & Scope, Err, Out] = { self.request( request.version, request.method, @@ -338,7 +338,7 @@ trait ZClient[-Env, -In, +Err, +Out] extends HeaderOps[ZClient[Env, In, Err, Out headers: Headers, body: In, sslConfig: Option[ClientSSLConfig], - )(implicit trace: Trace): ZIO[Env1, Err, Out] = + )(implicit trace: Trace): ZIO[Env1 & Scope, Err, Out] = self .request( version, @@ -388,7 +388,7 @@ trait ZClient[-Env, -In, +Err, +Out] extends HeaderOps[ZClient[Env, In, Err, Out headers: Headers, body: In, sslConfig: Option[ClientSSLConfig], - )(implicit trace: Trace): ZIO[Env, Err, Out] + )(implicit trace: Trace): ZIO[Env & Scope, Err, Out] def socket[Env1 <: Env]( version: Version = Version.Http_1_1, @@ -539,7 +539,7 @@ object ZClient { headers: Headers, body: In, sslConfig: Option[ClientSSLConfig], - )(implicit trace: Trace): ZIO[Env, Err, Out] = + )(implicit trace: Trace): ZIO[Env & Scope, Err, Out] = client.request( version, method, @@ -578,7 +578,7 @@ object ZClient { headers: Headers, body: Body, sslConfig: Option[ClientSSLConfig], - )(implicit trace: Trace): ZIO[Any, Throwable, Response] = { + )(implicit trace: Trace): ZIO[Scope, Throwable, Response] = { val request = Request(body, headers, method, url, version, None) val cfg = sslConfig.fold(config)(config.ssl) @@ -626,7 +626,7 @@ object ZClient { outerScope: Option[Scope], )(implicit trace: Trace, - ): ZIO[Any, Throwable, Response] = + ): ZIO[Scope, Throwable, Response] = request.url.kind match { case location: Location.Absolute => ZIO.uninterruptibleMask { restore => @@ -688,6 +688,7 @@ object ZClient { } } yield () }.forkDaemon // Needs to live as long as the channel is alive, as the response body may be streaming + _ <- ZIO.addFinalizer(onComplete.interrupt) response <- restore(onResponse.await.onInterrupt { onComplete.interrupt *> channelFiber.join.orDie }) @@ -703,7 +704,7 @@ object ZClient { method: Method = Method.GET, headers: Headers = Headers.empty, content: Body = Body.empty, - )(implicit trace: Trace): ZIO[Client, Throwable, Response] = { + )(implicit trace: Trace): ZIO[Client & Scope, Throwable, Response] = { for { uri <- ZIO.fromEither(URL.decode(url)) response <- ZIO.serviceWithZIO[Client]( @@ -715,45 +716,45 @@ object ZClient { } - def delete(pathSuffix: String, body: Body)(implicit trace: Trace): ZIO[Client, Throwable, Response] = + def delete(pathSuffix: String, body: Body)(implicit trace: Trace): ZIO[Client & Scope, Throwable, Response] = ZIO.serviceWithZIO[Client](_.delete(pathSuffix, body)) - def delete(pathSuffix: String)(implicit trace: Trace): ZIO[Client, Throwable, Response] = + def delete(pathSuffix: String)(implicit trace: Trace): ZIO[Client & Scope, Throwable, Response] = ZIO.serviceWithZIO[Client](_.delete(pathSuffix)) - def delete(implicit trace: Trace): ZIO[Client, Throwable, Response] = + def delete(implicit trace: Trace): ZIO[Client & Scope, Throwable, Response] = ZIO.serviceWithZIO[Client](_.delete) - def get(pathSuffix: String, body: Body)(implicit trace: Trace): ZIO[Client, Throwable, Response] = + def get(pathSuffix: String, body: Body)(implicit trace: Trace): ZIO[Client & Scope, Throwable, Response] = ZIO.serviceWithZIO[Client](_.get(pathSuffix, body)) - def get(pathSuffix: String)(implicit trace: Trace): ZIO[Client, Throwable, Response] = + def get(pathSuffix: String)(implicit trace: Trace): ZIO[Client & Scope, Throwable, Response] = ZIO.serviceWithZIO[Client](_.get(pathSuffix)) - def get(implicit trace: Trace): ZIO[Client, Throwable, Response] = + def get(implicit trace: Trace): ZIO[Client & Scope, Throwable, Response] = ZIO.serviceWithZIO[Client](_.get) - def head(pathSuffix: String, body: Body)(implicit trace: Trace): ZIO[Client, Throwable, Response] = + def head(pathSuffix: String, body: Body)(implicit trace: Trace): ZIO[Client & Scope, Throwable, Response] = ZIO.serviceWithZIO[Client](_.head(pathSuffix, body)) - def head(pathSuffix: String)(implicit trace: Trace): ZIO[Client, Throwable, Response] = + def head(pathSuffix: String)(implicit trace: Trace): ZIO[Client & Scope, Throwable, Response] = ZIO.serviceWithZIO[Client](_.head(pathSuffix)) - def head(implicit trace: Trace): ZIO[Client, Throwable, Response] = + def head(implicit trace: Trace): ZIO[Client & Scope, Throwable, Response] = ZIO.serviceWithZIO[Client](_.head) - def patch(pathSuffix: String, body: Body)(implicit trace: Trace): ZIO[Client, Throwable, Response] = + def patch(pathSuffix: String, body: Body)(implicit trace: Trace): ZIO[Client & Scope, Throwable, Response] = ZIO.serviceWithZIO[Client](_.patch(pathSuffix, body)) - def post(pathSuffix: String, body: Body)(implicit trace: Trace): ZIO[Client, Throwable, Response] = + def post(pathSuffix: String, body: Body)(implicit trace: Trace): ZIO[Client & Scope, Throwable, Response] = ZIO.serviceWithZIO[Client](_.post(pathSuffix, body)) - def put(pathSuffix: String, body: Body)(implicit trace: Trace): ZIO[Client, Throwable, Response] = + def put(pathSuffix: String, body: Body)(implicit trace: Trace): ZIO[Client & Scope, Throwable, Response] = ZIO.serviceWithZIO[Client](_.put(pathSuffix, body)) def request( request: Request, - )(implicit trace: Trace): ZIO[Client, Throwable, Response] = ZIO.serviceWithZIO[Client](_.request(request)) + )(implicit trace: Trace): ZIO[Client & Scope, Throwable, Response] = ZIO.serviceWithZIO[Client](_.request(request)) def socket[R]( version: Version = Version.Http_1_1, diff --git a/zio-http/src/main/scala/zio/http/ZClientAspect.scala b/zio-http/src/main/scala/zio/http/ZClientAspect.scala index 4977411ca6..3641590cf7 100644 --- a/zio-http/src/main/scala/zio/http/ZClientAspect.scala +++ b/zio-http/src/main/scala/zio/http/ZClientAspect.scala @@ -140,7 +140,7 @@ object ZClientAspect { headers: Headers, body: In, sslConfig: Option[ClientSSLConfig], - )(implicit trace: Trace): ZIO[Env, Err, Out] = + )(implicit trace: Trace): ZIO[Env & Scope, Err, Out] = client .request(version, method, url, headers, body, sslConfig) .sandbox @@ -216,7 +216,7 @@ object ZClientAspect { headers: Headers, body: In, sslConfig: Option[ClientSSLConfig], - )(implicit trace: Trace): ZIO[Env, Err, Out] = + )(implicit trace: Trace): ZIO[Env & Scope, Err, Out] = client .request(version, method, url, headers, body, sslConfig) .sandbox diff --git a/zio-http/src/main/scala/zio/http/endpoint/EndpointExecutor.scala b/zio-http/src/main/scala/zio/http/endpoint/EndpointExecutor.scala index 5ff947bfd2..77fdd0df39 100644 --- a/zio-http/src/main/scala/zio/http/endpoint/EndpointExecutor.scala +++ b/zio-http/src/main/scala/zio/http/endpoint/EndpointExecutor.scala @@ -57,7 +57,7 @@ final case class EndpointExecutor[+MI]( alt: Alternator[E, invocation.middleware.Err], ev: MI <:< invocation.middleware.In, trace: Trace, - ): ZIO[Any, alt.Out, B] = { + ): ZIO[Scope, alt.Out, B] = { middlewareInput.flatMap { mi => getClient(invocation.endpoint).orDie.flatMap { endpointClient => endpointClient.execute(client, invocation)(ev(mi)) diff --git a/zio-http/src/main/scala/zio/http/endpoint/internal/EndpointClient.scala b/zio-http/src/main/scala/zio/http/endpoint/internal/EndpointClient.scala index f19ec3f4db..91087d7dfc 100644 --- a/zio-http/src/main/scala/zio/http/endpoint/internal/EndpointClient.scala +++ b/zio-http/src/main/scala/zio/http/endpoint/internal/EndpointClient.scala @@ -28,7 +28,7 @@ private[endpoint] final case class EndpointClient[I, E, O, M <: EndpointMiddlewa ) { def execute(client: Client, invocation: Invocation[I, E, O, M])( mi: invocation.middleware.In, - )(implicit alt: Alternator[E, invocation.middleware.Err], trace: Trace): ZIO[Any, alt.Out, O] = { + )(implicit alt: Alternator[E, invocation.middleware.Err], trace: Trace): ZIO[Scope, alt.Out, O] = { val request0 = endpoint.input.encodeRequest(invocation.input) val request = request0.copy(url = endpointRoot ++ request0.url) diff --git a/zio-http/src/test/scala/zio/http/ClientHttpsSpec.scala b/zio-http/src/test/scala/zio/http/ClientHttpsSpec.scala index 85e8391531..d0b3818b7e 100644 --- a/zio-http/src/test/scala/zio/http/ClientHttpsSpec.scala +++ b/zio-http/src/test/scala/zio/http/ClientHttpsSpec.scala @@ -19,7 +19,7 @@ package zio.http import zio.test.Assertion.{anything, equalTo, fails, isSubtype} import zio.test.TestAspect.{ignore, timeout} import zio.test.{ZIOSpecDefault, assertZIO} -import zio.{ZLayer, durationInt} +import zio.{Scope, ZLayer, durationInt} import zio.http.Status import zio.http.netty.NettyConfig @@ -65,6 +65,7 @@ object ClientHttpsSpec extends ZIOSpecDefault { NettyClientDriver.live, DnsResolver.default, ZLayer.succeed(NettyConfig.default), + Scope.default, ) @@ timeout( 30 seconds, ) @@ ignore diff --git a/zio-http/src/test/scala/zio/http/ClientProxySpec.scala b/zio-http/src/test/scala/zio/http/ClientProxySpec.scala index d30032f8dd..48be4c0a92 100644 --- a/zio-http/src/test/scala/zio/http/ClientProxySpec.scala +++ b/zio-http/src/test/scala/zio/http/ClientProxySpec.scala @@ -47,6 +47,7 @@ object ClientProxySpec extends HttpRunnableSpec { NettyClientDriver.live, DnsResolver.default, ZLayer.succeed(NettyConfig.default), + Scope.default, ) } yield out assertZIO(res.either)(isLeft(isSubtype[ConnectException](anything))) @@ -68,6 +69,7 @@ object ClientProxySpec extends HttpRunnableSpec { NettyClientDriver.live, DnsResolver.default, ZLayer.succeed(NettyConfig.default), + Scope.default, ) } yield out assertZIO(res.either)(isRight) @@ -101,6 +103,7 @@ object ClientProxySpec extends HttpRunnableSpec { NettyClientDriver.live, DnsResolver.default, ZLayer.succeed(NettyConfig.default), + Scope.default, ) } yield out assertZIO(res.either)(isRight) diff --git a/zio-http/src/test/scala/zio/http/ClientStreamingSpec.scala b/zio-http/src/test/scala/zio/http/ClientStreamingSpec.scala index e407fce215..1a52aef220 100644 --- a/zio-http/src/test/scala/zio/http/ClientStreamingSpec.scala +++ b/zio-http/src/test/scala/zio/http/ClientStreamingSpec.scala @@ -60,7 +60,7 @@ object ClientStreamingSpec extends HttpRunnableSpec { // TODO: test failure cases - private def tests(streamingServer: Boolean): Seq[Spec[Client, Throwable]] = + private def tests(streamingServer: Boolean): Seq[Spec[Client with Scope, Throwable]] = Seq( test("simple get") { for { @@ -317,6 +317,7 @@ object ClientStreamingSpec extends HttpRunnableSpec { ZLayer.succeed(NettyConfig.default), ZLayer.succeed(Client.Config.default.connectionTimeout(100.seconds).idleTimeout(100.seconds)), Client.live, + Scope.default, ) @@ withLiveClock @@ sequential private def server(streaming: Boolean): ZIO[Any, Throwable, Int] = diff --git a/zio-http/src/test/scala/zio/http/DynamicAppTest.scala b/zio-http/src/test/scala/zio/http/DynamicAppTest.scala index da96576b9f..802e215716 100644 --- a/zio-http/src/test/scala/zio/http/DynamicAppTest.scala +++ b/zio-http/src/test/scala/zio/http/DynamicAppTest.scala @@ -38,7 +38,7 @@ object DynamicAppTest extends ZIOSpecDefault { .withDefaultErrorResponse val layer = - ZLayer.make[Client & Server]( + ZLayer.make[Client & Server & Scope]( ZLayer.succeed(ZClient.Config.default), NettyClientDriver.live, Client.customized, @@ -46,6 +46,7 @@ object DynamicAppTest extends ZIOSpecDefault { Server.live, DnsResolver.default, ZLayer.succeed(NettyConfig.default), + Scope.default, ) def spec = suite("Server")( diff --git a/zio-http/src/test/scala/zio/http/NettyMaxHeaderLengthSpec.scala b/zio-http/src/test/scala/zio/http/NettyMaxHeaderLengthSpec.scala index 514c9e442b..0f438ebe2b 100644 --- a/zio-http/src/test/scala/zio/http/NettyMaxHeaderLengthSpec.scala +++ b/zio-http/src/test/scala/zio/http/NettyMaxHeaderLengthSpec.scala @@ -49,5 +49,6 @@ object NettyMaxHeaderLengthSpec extends ZIOSpecDefault { Client.default, Server.live, ZLayer.succeed(serverConfig), + Scope.default, ) @@ withLiveClock } diff --git a/zio-http/src/test/scala/zio/http/ResponseCompressionSpec.scala b/zio-http/src/test/scala/zio/http/ResponseCompressionSpec.scala index 86f1e9066d..eac110ea58 100644 --- a/zio-http/src/test/scala/zio/http/ResponseCompressionSpec.scala +++ b/zio-http/src/test/scala/zio/http/ResponseCompressionSpec.scala @@ -21,7 +21,7 @@ import java.nio.charset.StandardCharsets import zio.test.TestAspect.withLiveClock import zio.test.{ZIOSpecDefault, assertTrue} -import zio.{Chunk, ZIO, ZInputStream, ZLayer} +import zio.{Chunk, Scope, ZIO, ZInputStream, ZLayer} import zio.stream.ZStream @@ -94,6 +94,7 @@ object ResponseCompressionSpec extends ZIOSpecDefault { ZLayer.succeed(serverConfig), Server.live, Client.default, + Scope.default, ) @@ withLiveClock private def decompressed(bytes: Chunk[Byte]): ZIO[Any, Throwable, String] = diff --git a/zio-http/src/test/scala/zio/http/SSLSpec.scala b/zio-http/src/test/scala/zio/http/SSLSpec.scala index 257df35950..2db65a40c4 100644 --- a/zio-http/src/test/scala/zio/http/SSLSpec.scala +++ b/zio-http/src/test/scala/zio/http/SSLSpec.scala @@ -19,7 +19,7 @@ package zio.http import zio.test.Assertion.equalTo import zio.test.TestAspect.{ignore, timeout} import zio.test.{Gen, ZIOSpecDefault, assertZIO, check} -import zio.{ZIO, ZLayer, durationInt} +import zio.{Scope, ZIO, ZLayer, durationInt} import zio.http.netty.NettyConfig import zio.http.netty.client.NettyClientDriver @@ -61,6 +61,7 @@ object SSLSpec extends ZIOSpecDefault { NettyClientDriver.live, DnsResolver.default, ZLayer.succeed(NettyConfig.default), + Scope.default, ), test("fail with DecoderException when client doesn't have the server certificate") { val actual = Client @@ -75,6 +76,7 @@ object SSLSpec extends ZIOSpecDefault { NettyClientDriver.live, DnsResolver.default, ZLayer.succeed(NettyConfig.default), + Scope.default, ), test("succeed when client has default SSL") { val actual = Client @@ -87,6 +89,7 @@ object SSLSpec extends ZIOSpecDefault { NettyClientDriver.live, DnsResolver.default, ZLayer.succeed(NettyConfig.default), + Scope.default, ), test("Https Redirect when client makes http request") { val actual = Client @@ -99,6 +102,7 @@ object SSLSpec extends ZIOSpecDefault { NettyClientDriver.live, DnsResolver.default, ZLayer.succeed(NettyConfig.default), + Scope.default, ), test("Https request with a large payload should respond with 413") { check(payload) { payload => @@ -117,6 +121,7 @@ object SSLSpec extends ZIOSpecDefault { NettyClientDriver.live, DnsResolver.default, ZLayer.succeed(NettyConfig.default), + Scope.default, ), ), ), diff --git a/zio-http/src/test/scala/zio/http/ZClientAspectSpec.scala b/zio-http/src/test/scala/zio/http/ZClientAspectSpec.scala index 8ef581569c..d600f8042a 100644 --- a/zio-http/src/test/scala/zio/http/ZClientAspectSpec.scala +++ b/zio-http/src/test/scala/zio/http/ZClientAspectSpec.scala @@ -81,5 +81,6 @@ object ZClientAspectSpec extends ZIOSpecDefault { ZLayer.succeed(Server.Config.default.onAnyOpenPort), Server.live, Client.default, + Scope.default, ) @@ withLiveClock } diff --git a/zio-http/src/test/scala/zio/http/endpoint/ServerClientIntegrationSpec.scala b/zio-http/src/test/scala/zio/http/endpoint/ServerClientIntegrationSpec.scala index 4e6cd36aec..577bbfe423 100644 --- a/zio-http/src/test/scala/zio/http/endpoint/ServerClientIntegrationSpec.scala +++ b/zio-http/src/test/scala/zio/http/endpoint/ServerClientIntegrationSpec.scala @@ -63,7 +63,7 @@ object ServerClientIntegrationSpec extends ZIOSpecDefault { route: Routes[R, Err, EndpointMiddleware.None.type], in: In, out: Out, - ): ZIO[Client with R with Server, Err, TestResult] = + ): ZIO[Client with R with Server with Scope, Err, TestResult] = testEndpointZIO(endpoint, route, in, outF = { (value: Out) => assertTrue(out == value) }) def testEndpointZIO[R, In, Err, Out]( @@ -71,7 +71,7 @@ object ServerClientIntegrationSpec extends ZIOSpecDefault { route: Routes[R, Err, EndpointMiddleware.None.type], in: In, outF: Out => ZIO[Any, Nothing, TestResult], - ): ZIO[Client with R with Server, Err, TestResult] = + ): ZIO[Client with R with Server with Scope, Err, TestResult] = for { port <- Server.install(route.toApp @@ RequestHandlerMiddlewares.requestLogging()) executorLayer = ZLayer(ZIO.service[Client].map(makeExecutor(_, port))) @@ -80,7 +80,7 @@ object ServerClientIntegrationSpec extends ZIOSpecDefault { .flatMap { executor => executor.apply(endpoint.apply(in)) } - .provideSome[Client](executorLayer) + .provideSome[Client & Scope](executorLayer) result <- outF(out) } yield result @@ -89,7 +89,7 @@ object ServerClientIntegrationSpec extends ZIOSpecDefault { route: Routes[R, Err, EndpointMiddleware.None.type], in: In, err: Err, - ): ZIO[Client with R with Server, Out, TestResult] = + ): ZIO[Client with R with Server with Scope, Out, TestResult] = testEndpointErrorZIO(endpoint, route, in, errorF = { (value: Err) => assertTrue(err == value) }) def testEndpointErrorZIO[R, In, Err, Out]( @@ -97,7 +97,7 @@ object ServerClientIntegrationSpec extends ZIOSpecDefault { route: Routes[R, Err, EndpointMiddleware.None.type], in: In, errorF: Err => ZIO[Any, Nothing, TestResult], - ): ZIO[Client with R with Server, Out, TestResult] = + ): ZIO[Client with R with Server with Scope, Out, TestResult] = for { port <- Server.install(route.toApp) executorLayer = ZLayer(ZIO.service[Client].map(makeExecutor(_, port))) @@ -106,7 +106,7 @@ object ServerClientIntegrationSpec extends ZIOSpecDefault { .flatMap { executor => executor.apply(endpoint.apply(in)) } - .provideSome[Client](executorLayer) + .provideSome[Client with Scope](executorLayer) .flip result <- errorF(out) } yield result @@ -318,7 +318,7 @@ object ServerClientIntegrationSpec extends ZIOSpecDefault { .serviceWithZIO[EndpointExecutor[alwaysFailingMiddleware.In]] { executor => executor.apply(endpoint.apply(42)) } - .provideSome[Client](executorLayer) + .provideSome[Client & Scope](executorLayer) .flip } yield assertTrue(out == "FAIL") }, @@ -358,7 +358,7 @@ object ServerClientIntegrationSpec extends ZIOSpecDefault { .serviceWithZIO[EndpointExecutor[alwaysFailingMiddleware.In]] { executor => executor.apply(endpointWithAnotherSignature.apply(42)) } - .provideSome[Client](executorLayer) + .provideSome[Client with Scope](executorLayer) .cause } yield assertTrue( cause.prettyPrint.contains( @@ -396,7 +396,7 @@ object ServerClientIntegrationSpec extends ZIOSpecDefault { .serviceWithZIO[EndpointExecutor[Unit]] { executor => executor.apply(endpointWithAnotherSignature.apply(42)) } - .provideSome[Client](executorLayer) + .provideSome[Client with Scope](executorLayer) .cause } yield assertTrue( cause.prettyPrint.contains( @@ -441,5 +441,6 @@ object ServerClientIntegrationSpec extends ZIOSpecDefault { NettyDriver.live, ZLayer.succeed(ZClient.Config.default), DnsResolver.default, + Scope.default, ) @@ withLiveClock @@ sequential @@ timeout(300.seconds) } diff --git a/zio-http/src/test/scala/zio/http/internal/HttpRunnableSpec.scala b/zio-http/src/test/scala/zio/http/internal/HttpRunnableSpec.scala index ec7e0ca01c..4e2266e852 100644 --- a/zio-http/src/test/scala/zio/http/internal/HttpRunnableSpec.scala +++ b/zio-http/src/test/scala/zio/http/internal/HttpRunnableSpec.scala @@ -93,8 +93,8 @@ abstract class HttpRunnableSpec extends ZIOSpecDefault { self => } def deployAndRequest( - call: Client => ZIO[Any, Throwable, Response], - ): Handler[Client with DynamicServer with R, Throwable, Any, Response] = { + call: Client => ZIO[Scope, Throwable, Response], + ): Handler[Client with DynamicServer with R with Scope, Throwable, Any, Response] = { for { port <- Handler.fromZIO(DynamicServer.port) id <- Handler.fromZIO(DynamicServer.deploy[R](app)) @@ -109,7 +109,7 @@ abstract class HttpRunnableSpec extends ZIOSpecDefault { self => } yield response } - def deployChunked: Http[R with Client with DynamicServer, Throwable, Request, Response] = + def deployChunked: Http[R with Client with DynamicServer with Scope, Throwable, Request, Response] = Http.fromHandler { for { port <- Handler.fromZIO(DynamicServer.port) diff --git a/zio-http/src/test/scala/zio/http/netty/NettyStreamBodySpec.scala b/zio-http/src/test/scala/zio/http/netty/NettyStreamBodySpec.scala index f917c31c88..1b03240e65 100644 --- a/zio-http/src/test/scala/zio/http/netty/NettyStreamBodySpec.scala +++ b/zio-http/src/test/scala/zio/http/netty/NettyStreamBodySpec.scala @@ -115,5 +115,6 @@ object NettyStreamBodySpec extends HttpRunnableSpec { }, ).provide( singleConnectionClient, + Scope.default, ) @@ withLiveClock }