Open counter2015 opened 2 years ago
Hm I think it's not about encoding of the body (the linked sttp issue sets the body encoding, as far as I know), but rather about using filename
/filename*
appropriately as you write.
Which interpreter are you using, http4s? I wonder what changed since 0.17 🤔
yes, http4s. the full depenience can be found here
0.17 version
import sbt._
object Dependencies {
val tapirVersion = "0.17.12"
val tapir = Seq(
"com.softwaremill.sttp.tapir" %% "tapir-zio" % tapirVersion,
"com.softwaremill.sttp.tapir" %% "tapir-zio-http4s-server" % tapirVersion,
"com.softwaremill.sttp.tapir" %% "tapir-json-circe" % tapirVersion,
"com.softwaremill.sttp.tapir" %% "tapir-openapi-docs" % tapirVersion,
"com.softwaremill.sttp.tapir" %% "tapir-openapi-circe-yaml" % tapirVersion,
"com.softwaremill.sttp.tapir" %% "tapir-swagger-ui-http4s" % tapirVersion,
)
val zioLoggingVersion = "0.5.14"
val log = Seq(
"ch.qos.logback" % "logback-classic" % "1.2.10",
"dev.zio" %% "zio-logging" % zioLoggingVersion,
"dev.zio" %% "zio-logging-slf4j" % zioLoggingVersion,
)
val coreDependency = tapir ++ log
}
0.19 version
import sbt._
object Dependencies {
val tapirVersion = "0.19.3"
val tapir = Seq(
"com.softwaremill.sttp.tapir" %% "tapir-zio" % tapirVersion,
"com.softwaremill.sttp.tapir" %% "tapir-zio-http4s-server" % tapirVersion,
"com.softwaremill.sttp.tapir" %% "tapir-json-circe" % tapirVersion,
"com.softwaremill.sttp.tapir" %% "tapir-swagger-ui-bundle" % tapirVersion,
)
val zioLoggingVersion = "0.5.14"
val log = Seq(
"ch.qos.logback" % "logback-classic" % "1.2.10",
"dev.zio" %% "zio-logging" % zioLoggingVersion,
"dev.zio" %% "zio-logging-slf4j" % zioLoggingVersion,
)
val coreDependency = tapir ++ log
}
I think this is a problem with http4s, see: https://github.com/http4s/http4s/issues/5809
For future testing, here's my test code reproducing the problem:
import cats.effect._
import org.http4s.HttpRoutes
import org.http4s.server.Router
import org.http4s.blaze.server.BlazeServerBuilder
import org.http4s.syntax.kleisli._
import sttp.model.Part
import sttp.tapir._
import sttp.tapir.server.http4s.Http4sServerInterpreter
import java.io.File
import scala.concurrent.ExecutionContext
import scala.io.Source
import sttp.tapir.generic.auto._
/*
curl -X 'POST' 'http://localhost:8080/file/1' -H 'accept: text/plain' -H 'Content-Type: multipart/form-data' -F 'uploader=me' -F 'file=@中文文件名.json;type=application/json'
*/
object Test extends IOApp {
case class FileForm(file: Part[File])
val uploadEndpoint =
endpoint.post
.in("file")
.in(path[String]("id"))
.in(multipartBody[FileForm])
.tag("File")
def uploadLogic(id: String, form: FileForm): IO[Unit] = IO {
println(s"\n\n\nGot: $id ${form.file}\n${Source.fromFile(form.file.body).mkString("\n")}")
}
val uploadRoutes: HttpRoutes[IO] =
Http4sServerInterpreter[IO]().toRoutes(uploadEndpoint.serverLogicSuccess { case (id, form) => uploadLogic(id, form) })
implicit val ec: ExecutionContext = scala.concurrent.ExecutionContext.Implicits.global
override def run(args: List[String]): IO[ExitCode] = {
BlazeServerBuilder[IO]
.withExecutionContext(ec)
.bindHttp(8080, "localhost")
.withHttpApp(Router("/" -> uploadRoutes).orNotFound)
.resource
.use { _ => IO.never }
.as(ExitCode.Success)
}
}
Thanks!
so , this question can be solve?
@weili96 well, we don't really have a solution to this problem. So I'd keep this open.
Tapir version: 0.19.3
Scala version: 2.13.7
Describe the Problem
In rfc6266
I wrote an endpoint to hanle file upload , like this
It works well in old version of tapir 0.17.12, but not work in 0.19.3
since https://github.com/softwaremill/sttp/pull/877 add encoding in client side mutipart body, does tapir provide something like this in server side ? So I can use default UTF-8 Codec ?
How to reproduce?
In another window, or in swagger page
response: Bad Request Invalid value for: body
Additional information
0.17.12 version can be found here, it works well https://github.com/counter2015/tapir-zio-http4s.g8/tree/0.17/src/main/g8
Raw log from postman