Skip to content

Commit

Permalink
Set the max buffersize for jsoniter (#2459)
Browse files Browse the repository at this point in the history
* Set the max buffersize for jsoniter

* Add test case for tapir jsonitor max char size
  • Loading branch information
kaaveland authored Nov 19, 2024
1 parent d132ff0 commit fafe332
Show file tree
Hide file tree
Showing 8 changed files with 37 additions and 10 deletions.
2 changes: 2 additions & 0 deletions adapters/play/src/test/resources/application.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
http.server.max-content-length = infinite
play.http.parser.maxMemoryBuffer = 100M
14 changes: 10 additions & 4 deletions adapters/quick/src/main/scala/caliban/QuickRequestHandler.scala
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,8 @@ final private class QuickRequestHandler[R](

def decodeQueryParams(queryParams: QueryParams): Either[Response, GraphQLRequest] = {
def extractField(key: String) =
try Right(queryParams.getAll(key).headOption.map(readFromString[InputValue.ObjectValue](_).fields))
try
Right(queryParams.getAll(key).headOption.map(readFromString[InputValue.ObjectValue](_, readerConfig).fields))
catch { case NonFatal(_) => Left(badRequest(s"Invalid $key query param")) }

for {
Expand All @@ -101,7 +102,7 @@ final private class QuickRequestHandler[R](
body.asArray.foldZIO(
_ => Exit.fail(BodyDecodeErrorResponse),
arr =>
try checkNonEmptyRequest(readFromArray[GraphQLRequest](arr))
try checkNonEmptyRequest(readFromArray[GraphQLRequest](arr, readerConfig))
catch { case NonFatal(_) => Exit.fail(BodyDecodeErrorResponse) }
)

Expand Down Expand Up @@ -136,7 +137,7 @@ final private class QuickRequestHandler[R](
Exit
.fromOption(partsMap.get(key))
.flatMap(_.asChunk)
.flatMap(v => Exit.fromTry(Try(readFromArray[A](v.toArray))))
.flatMap(v => Exit.fromTry(Try(readFromArray[A](v.toArray, readerConfig))))
.orElseFail(Response.badRequest)

def parsePath(path: String): List[PathValue] = path.split('.').toList.map(PathValue.parse)
Expand Down Expand Up @@ -265,7 +266,7 @@ final private class QuickRequestHandler[R](
case ChannelEvent.UserEventTriggered(HandshakeComplete) =>
out.runForeach(frame => ch.send(ChannelEvent.Read(frame))).forkScoped
case ChannelEvent.Read(WebSocketFrame.Text(text)) =>
ZIO.suspend(queue.offer(readFromString[GraphQLWSInput](text)))
ZIO.suspend(queue.offer(readFromString[GraphQLWSInput](text, readerConfig)))
case _ =>
ZIO.unit
})
Expand Down Expand Up @@ -309,4 +310,9 @@ object QuickRequestHandler {
}

private implicit val responseCodec: JsonValueCodec[ResponseValue] = ValueJsoniter.responseValueCodec

private val readerConfig: ReaderConfig = ReaderConfig
.withAppendHexDumpToParseException(false)
.withMaxBufSize(Int.MaxValue - 2)
.withMaxCharBufSize(Int.MaxValue - 2)
}
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ object QuickAdapterSpec extends ZIOSpecDefault {
suite.provideShared(
apiLayer,
Scope.default,
Server.defaultWith(_.port(8090).responseCompression())
Server.defaultWith(_.port(8090).enableRequestStreaming.responseCompression())
)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ package caliban.interop.tapir

import caliban.{ GraphQLRequest, ResponseValue }
import sttp.tapir.Codec.JsonCodec
import sttp.tapir.json.jsoniter._
import MaxCharBufSizeJsonJsoniter._

private object JsonCodecs {
import caliban.interop.jsoniter.ValueJsoniter.stringListCodec
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package caliban.interop.tapir

import com.github.plokhotnyuk.jsoniter_scala.core.ReaderConfig
import sttp.tapir.json.jsoniter.TapirJsonJsoniter

object MaxCharBufSizeJsonJsoniter extends TapirJsonJsoniter {
override lazy val readerConfig: ReaderConfig =
ReaderConfig
.withAppendHexDumpToParseException(false)
.withMaxCharBufSize(Int.MaxValue - 2)
.withMaxBufSize(Int.MaxValue - 2)
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import sttp.model.sse.ServerSentEvent
import sttp.model.{ headers => _, _ }
import sttp.monad.MonadError
import sttp.shared.Identity
import sttp.tapir.json.jsoniter._
import MaxCharBufSizeJsonJsoniter._
import sttp.tapir.model.ServerRequest
import sttp.tapir.server.ServerEndpoint
import sttp.tapir.ztapir.ZioServerSentEvents
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import caliban.interop.tapir.TapirAdapter._
import caliban.ws.Protocol
import sttp.capabilities.zio.ZioStreams
import sttp.model.{ headers => _ }
import sttp.tapir.json.jsoniter._
import MaxCharBufSizeJsonJsoniter._
import sttp.tapir._
import sttp.tapir.model.{ ServerRequest, UnsupportedWebSocketFrameException }
import sttp.tapir.server.ServerEndpoint
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ package caliban.interop.tapir
import caliban.InputValue.ObjectValue
import caliban.Value.StringValue
import caliban._
import com.github.plokhotnyuk.jsoniter_scala.core.{ readFromString, writeToString, JsonValueCodec }
import com.github.plokhotnyuk.jsoniter_scala.core.{ readFromString, writeToString, JsonValueCodec, ReaderConfig }
import com.github.plokhotnyuk.jsoniter_scala.macros.JsonCodecMaker
import sttp.capabilities.zio.ZioStreams
import sttp.capabilities.{ Effect, WebSockets }
Expand All @@ -14,7 +14,7 @@ import sttp.model._
import sttp.model.sse.ServerSentEvent
import sttp.tapir.client.sttp.SttpClientInterpreter
import sttp.tapir.client.sttp.ws.zio._
import sttp.tapir.json.jsoniter._
import MaxCharBufSizeJsonJsoniter._
import sttp.tapir.model.{ ConnectionInfo, ServerRequest }
import sttp.tapir.{ AttributeKey, DecodeResult }
import zio.stream.{ ZPipeline, ZSink, ZStream }
Expand Down Expand Up @@ -272,6 +272,13 @@ object TapirAdapterSpec {
method = Method.GET.method,
query = """mutation{ deleteCharacter(name: "Amos Burton") }"""
).map(r => assertTrue(r.code.code == 400))
},
test("very long field values in mutations") {
val name = "A".repeat(ReaderConfig.maxCharBufSize + 1)
runHttpRequest(
method = Method.POST.method,
query = s"""mutation { deleteCharacter(name: \"$name\") }"""
).map(r => assertTrue(r.code.code == 200))
}
)
),
Expand Down

0 comments on commit fafe332

Please sign in to comment.