-
-
Notifications
You must be signed in to change notification settings - Fork 475
Open
Labels
bugSomething isn't workingSomething isn't working
Description
Describe the bug
Using endpoint defined with NoContent status fails with Malformed request body failed to decode: Non-empty body cannot be decoded as Unit
To Reproduce
val unitEndpoint = Endpoint((Method.GET / "")).out[Unit](Status.NoContent)
val unitRoute = unitEndpoint.implement(_ => ZIO.unit)
ZIO
.scoped(
for {
_ <- Server.serve(unitRoute).forkScoped
exec <- ZIO.serviceWith[Client] { client =>
EndpointExecutor(client, EndpointLocator.fromURL(URL.decode("http://localhost:8080").toOption.get))
}
result <- exec(unitEndpoint(()))
} yield {
result
}
)
.provide(Server.live, ZLayer.succeed(Server.Config.default), Client.default)
// res0: Exit[Throwable, Unit] = Failure(Die(zio.http.codec.HttpCodecError$MalformedBody: Malformed request body failed to decode: Non-empty body cannot be decoded as Unit,Stack trace for thread "zio-fiber-":
// ))Expected behaviour
Client request should succeed with unit value.
Desktop (please complete the following information):
- OS: Linux
Additional context
Using Ok instead of NoContent status succeeds:
val unitEndpoint = Endpoint((Method.GET / "")).out[Unit](Status.Ok)
val unitRoute = unitEndpoint.implement(_ => ZIO.unit)
ZIO
.scoped(
for {
_ <- Server.serve(unitRoute).forkScoped
exec <- ZIO.serviceWith[Client] { client =>
EndpointExecutor(client, EndpointLocator.fromURL(URL.decode("http://localhost:8080").toOption.get))
}
result <- exec(unitEndpoint(()))
} yield {
result
}
)
.provide(Server.live, ZLayer.succeed(Server.Config.default), Client.default)
// res0: Exit[Throwable, Unit] = Success(())From what I found, the codec on client side depends on the existence of content-length header to exist to be able to decode Unit, while otoh server (rightfully, according to HTTP spec) leaves this header out in the NoContent case.
Relevant code:
val headers = Conversions.headersFromNetty(jRes.headers()) val knownContentLength = headers.get(Header.ContentLength).map(_.length) if (knownContentLength.contains(0L)) { onComplete.unsafe.done(Exit.succeed(ChannelState.forStatus(status))) Response(status, headers, Body.empty) zio-http/zio-http/shared/src/main/scala/zio/http/codec/internal/BodyCodec.scala
Lines 134 to 136 in 6c99669
case Right((_, BinaryCodecWithSchema(_, schema))) if schema == Schema[Unit] => if (body.isEmpty) Exit.unit.asInstanceOf[IO[Throwable, A]] else ZIO.fail(HttpCodecError.CustomError("InvalidBody", "Non-empty body cannot be decoded as Unit"))
Metadata
Metadata
Assignees
Labels
bugSomething isn't workingSomething isn't working