Skip to content

Commit ee426c1

Browse files
authored
Merge branch 'series/1.x' into merge/0.1-1.x
2 parents caa5a7c + 1d87385 commit ee426c1

3 files changed

Lines changed: 38 additions & 26 deletions

File tree

build.sbt

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616

1717
name := "feral"
1818

19-
ThisBuild / tlBaseVersion := "0.1"
19+
ThisBuild / tlBaseVersion := "1.0"
2020
ThisBuild / startYear := Some(2021)
2121

2222
ThisBuild / developers := List(
@@ -59,7 +59,7 @@ ThisBuild / crossScalaVersions := Seq(Scala212, Scala3, Scala213)
5959
val catsEffectVersion = "3.3.13"
6060
val circeVersion = "0.14.2"
6161
val fs2Version = "3.2.9"
62-
val http4sVersion = "0.23.13"
62+
val http4sVersion = "1.0.0-M34"
6363
val natchezVersion = "0.1.6"
6464
val munitVersion = "0.7.29"
6565
val munitCEVersion = "1.0.7"
@@ -181,7 +181,6 @@ lazy val examples = crossProject(JSPlatform, JVMPlatform)
181181
"org.http4s" %%% "http4s-dsl" % http4sVersion,
182182
"org.http4s" %%% "http4s-ember-client" % http4sVersion,
183183
"org.tpolecat" %%% "natchez-xray" % natchezVersion,
184-
"org.tpolecat" %%% "natchez-http4s" % "0.3.2",
185184
"org.tpolecat" %%% "skunk-core" % "0.3.1"
186185
)
187186
)

examples/src/main/scala/feral/examples/Http4sLambda.scala

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,6 @@ import cats.effect.std.Random
2121
import feral.lambda._
2222
import feral.lambda.events._
2323
import feral.lambda.http4s._
24-
import natchez.Trace
25-
import natchez.http4s.NatchezMiddleware
2624
import natchez.xray.XRay
2725
import org.http4s.HttpRoutes
2826
import org.http4s.client.Client
@@ -60,18 +58,16 @@ object http4sHandler
6058

6159
// a middleware to add tracing to any handler
6260
// it extracts the kernel from the event and adds tags derived from the context
63-
TracedHandler(entrypoint) { implicit trace =>
64-
val tracedClient = NatchezMiddleware.client(client)
65-
61+
TracedHandler(entrypoint) { _ =>
6662
// a "middleware" that converts an HttpRoutes into a ApiGatewayProxyHandler
67-
ApiGatewayProxyHandler(myRoutes[IO](tracedClient))
63+
ApiGatewayProxyHandler(myRoutes[IO](client))
6864
}
6965
}
7066

7167
/**
7268
* Nothing special about this method, including its existence, just an example :)
7369
*/
74-
def myRoutes[F[_]: Concurrent: Trace](client: Client[F]): HttpRoutes[F] = {
70+
def myRoutes[F[_]: Concurrent](client: Client[F]): HttpRoutes[F] = {
7571
implicit val dsl = Http4sDsl[F]
7672
import dsl._
7773

@@ -80,7 +76,7 @@ object http4sHandler
8076
case GET -> Root / "joke" => Ok(client.expect[String](uri"icanhazdadjoke.com"))
8177
}
8278

83-
NatchezMiddleware.server(routes)
79+
routes
8480
}
8581

8682
}

lambda-http4s/src/main/scala/feral/lambda/http4s/ApiGatewayProxyHandler.scala

Lines changed: 32 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -17,20 +17,24 @@
1717
package feral.lambda
1818
package http4s
1919

20+
import cats.data.OptionT
2021
import cats.effect.kernel.Concurrent
2122
import cats.syntax.all._
2223
import feral.lambda.events.ApiGatewayProxyEventV2
2324
import feral.lambda.events.ApiGatewayProxyStructuredResultV2
24-
import fs2.Stream
25+
import fs2.Chunk
2526
import org.http4s.Charset
27+
import org.http4s.Entity
2628
import org.http4s.Headers
2729
import org.http4s.HttpRoutes
30+
import org.http4s.MalformedMessageBodyFailure
2831
import org.http4s.Method
2932
import org.http4s.Request
3033
import org.http4s.Response
3134
import org.http4s.Uri
3235
import org.http4s.headers.Cookie
3336
import org.http4s.headers.`Set-Cookie`
37+
import scodec.bits.ByteVector
3438

3539
object ApiGatewayProxyHandler {
3640

@@ -39,15 +43,21 @@ object ApiGatewayProxyHandler {
3943
for {
4044
event <- LambdaEnv.event
4145
request <- decodeEvent(event)
42-
response <- routes(request).getOrElse(Response.notFound[F])
46+
response <- routes(request).getOrElse(Response.notFound)
4347
isBase64Encoded = !response.charset.contains(Charset.`UTF-8`)
44-
responseBody <- response
45-
.body
46-
.through(
47-
if (isBase64Encoded) fs2.text.base64.encode else fs2.text.utf8.decode
48-
)
49-
.compile
50-
.string
48+
responseBody <- response.entity match {
49+
case Entity.Empty => "".pure
50+
case Entity.Strict(chunk) => // TODO
51+
if (isBase64Encoded) chunk.toByteVector.toBase64.pure
52+
else chunk.toByteVector.decodeUtf8.liftTo
53+
case Entity.Default(body, _) =>
54+
body
55+
.through(
56+
if (isBase64Encoded) fs2.text.base64.encode else fs2.text.utf8.decode
57+
)
58+
.compile
59+
.string
60+
}
5161
} yield {
5262
val headers = response.headers.headers.groupMap(_.name)(_.value)
5363
Some(
@@ -70,15 +80,22 @@ object ApiGatewayProxyHandler {
7080
uri <- Uri.fromString(event.rawPath + "?" + event.rawQueryString).liftTo[F]
7181
cookies = event.cookies.filter(_.nonEmpty).map(Cookie.name.toString -> _.mkString("; "))
7282
headers = Headers(cookies.toList ::: event.headers.toList)
73-
readBody =
74-
if (event.isBase64Encoded)
75-
fs2.text.base64.decode[F]
76-
else
77-
fs2.text.utf8.encode[F]
83+
body <- OptionT
84+
.fromOption(event.body)
85+
.semiflatMap { eventBody =>
86+
if (event.isBase64Encoded)
87+
ByteVector
88+
.fromBase64Descriptive(eventBody)
89+
.leftMap(MalformedMessageBodyFailure(_))
90+
.liftTo
91+
else
92+
ByteVector.encodeUtf8(eventBody).liftTo
93+
}
94+
.value
7895
} yield Request(
7996
method,
8097
uri,
8198
headers = headers,
82-
body = Stream.fromOption[F](event.body).through(readBody)
99+
entity = body.foldMap(b => Entity.strict(Chunk.byteVector(b)))
83100
)
84101
}

0 commit comments

Comments
 (0)