Skip to content

Commit

Permalink
Change FileRange underlying field type to tapir.sttp.File
Browse files Browse the repository at this point in the history
  • Loading branch information
bartekzylinski committed Oct 4, 2021
1 parent c97e320 commit 7ed2f90
Show file tree
Hide file tree
Showing 24 changed files with 43 additions and 70 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,7 @@ private[http4s] class EndpointToHttp4sClient(clientOptions: Http4sClientOptions)
req.withEntity(Applicative[F].pure(encoded.asInstanceOf[InputStream]))(entityEncoder)
case RawBodyType.FileBody =>
val entityEncoder = EntityEncoder.fileEncoder[F]
req.withEntity(encoded.asInstanceOf[FileRange].toFile)(entityEncoder)
req.withEntity(encoded.asInstanceOf[FileRange].file)(entityEncoder)
case _: RawBodyType.MultipartBody =>
throw new IllegalArgumentException("Multipart body isn't supported yet")
}
Expand Down Expand Up @@ -205,7 +205,7 @@ private[http4s] class EndpointToHttp4sClient(clientOptions: Http4sClientOptions)
response.body.compile.toVector.map(_.toArray).map(new ByteArrayInputStream(_)).map(_.asInstanceOf[Any])
case RawBodyType.FileBody =>
val file = clientOptions.createFile()
response.body.through(Files[F].writeAll(file.toPath)).compile.drain.map(_ => FileRange.from(file))
response.body.through(Files[F].writeAll(file.toPath)).compile.drain.map(_ => FileRange(file))
case RawBodyType.MultipartBody(_, _) => throw new IllegalArgumentException("Multipart bodies aren't supported in responses")
}
.getOrElse[F[Any]](((): Any).pure[F])
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -164,7 +164,7 @@ private[play] class EndpointToPlayClient(clientOptions: PlayClientOptions, ws: S
// For some reason, Play comes with a Writeable for Supplier[InputStream] but not InputStream directly
val inputStreamSupplier: Supplier[InputStream] = () => encoded.asInstanceOf[InputStream]
req.withBody(inputStreamSupplier)
case RawBodyType.FileBody => req.withBody(encoded.asInstanceOf[FileRange].toFile)
case RawBodyType.FileBody => req.withBody(encoded.asInstanceOf[FileRange].file)
case _: RawBodyType.MultipartBody => throw new IllegalArgumentException("Multipart body aren't supported")
}

Expand Down Expand Up @@ -205,7 +205,7 @@ private[play] class EndpointToPlayClient(clientOptions: PlayClientOptions, ws: S
val outputStream = Files.newOutputStream(f.toPath)
outputStream.write(response.body[Array[Byte]])
outputStream.close()
FileRange.from(f)
FileRange(f)
case RawBodyType.MultipartBody(_, _) => throw new IllegalArgumentException("Multipart bodies aren't supported in responses")
}
.getOrElse(()) // Unit
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -143,7 +143,7 @@ private[sttp] class EndpointToSttpClient[R](clientOptions: SttpClientOptions, ws
case RawBodyType.ByteArrayBody => req.body(encoded)
case RawBodyType.ByteBufferBody => req.body(encoded)
case RawBodyType.InputStreamBody => req.body(encoded)
case RawBodyType.FileBody => req.body(encoded.asInstanceOf[FileRange].toFile)
case RawBodyType.FileBody => req.body(encoded.asInstanceOf[FileRange].file)
case m: RawBodyType.MultipartBody =>
val parts: Seq[Part[RequestBody[Any]]] = (encoded: Seq[RawPart]).flatMap { p =>
m.partType(p.name).map { partType =>
Expand All @@ -170,7 +170,7 @@ private[sttp] class EndpointToSttpClient[R](clientOptions: SttpClientOptions, ws
case RawBodyType.ByteArrayBody => multipart(p.name, p.body)
case RawBodyType.ByteBufferBody => multipart(p.name, p.body)
case RawBodyType.InputStreamBody => multipart(p.name, p.body)
case RawBodyType.FileBody => multipartFile(p.name, p.body.asInstanceOf[FileRange].toFile)
case RawBodyType.FileBody => multipartFile(p.name, p.body.asInstanceOf[FileRange].file)
case RawBodyType.MultipartBody(_, _) => throw new IllegalArgumentException("Nested multipart bodies aren't supported")
}

Expand All @@ -185,7 +185,7 @@ private[sttp] class EndpointToSttpClient[R](clientOptions: SttpClientOptions, ws
case RawBodyType.ByteArrayBody => asByteArrayAlways
case RawBodyType.ByteBufferBody => asByteArrayAlways.map(ByteBuffer.wrap)
case RawBodyType.InputStreamBody => asByteArrayAlways.map(new ByteArrayInputStream(_))
case RawBodyType.FileBody => asFileAlways(clientOptions.createFile()).map(FileRange.from)
case RawBodyType.FileBody => asFileAlways(clientOptions.createFile()).map(d => FileRange(d))
case RawBodyType.MultipartBody(_, _) => throw new IllegalArgumentException("Multipart bodies aren't supported in responses")
}
.getOrElse(ignore)
Expand Down
2 changes: 1 addition & 1 deletion core/src/main/scala/sttp/tapir/Codec.scala
Original file line number Diff line number Diff line change
Expand Up @@ -186,7 +186,7 @@ object Codec extends FormCodecMacros with LowPriorityCodec {
id[ByteBuffer, OctetStream](OctetStream(), Schema.schemaForByteBuffer)
implicit val fileRange: Codec[FileRange, FileRange, OctetStream] =
id[FileRange, OctetStream](OctetStream(), Schema.schemaForTapirFile)
implicit val file: Codec[FileRange, File, OctetStream] = fileRange.map(_.toFile)(FileRange.from)
implicit val file: Codec[FileRange, File, OctetStream] = fileRange.map(_.file)(f => FileRange(f))

implicit val formSeqCodecUtf8: Codec[String, Seq[(String, String)], XWwwFormUrlencoded] = formSeqCodec(StandardCharsets.UTF_8)
implicit val formMapCodecUtf8: Codec[String, Map[String, String], XWwwFormUrlencoded] = formMapCodec(StandardCharsets.UTF_8)
Expand Down
4 changes: 1 addition & 3 deletions core/src/main/scala/sttp/tapir/FileRange.scala
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,4 @@ package sttp.tapir

import sttp.model.headers.Range

case class FileRange(underlying: Any, range: Option[Range] = None) extends FileRangeExtension

object FileRange extends FileRangeCompanionExtensions
case class FileRange(file: File, range: Option[Range] = None)
2 changes: 1 addition & 1 deletion core/src/main/scala/sttp/tapir/Tapir.scala
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ trait Tapir extends TapirExtensions with TapirComputedInputs with TapirStaticCon
def byteBufferBody: EndpointIO.Body[ByteBuffer, ByteBuffer] = rawBinaryBody[ByteBuffer]
def inputStreamBody: EndpointIO.Body[InputStream, InputStream] = rawBinaryBody[InputStream]
def fileRangeBody: EndpointIO.Body[FileRange, FileRange] = rawBinaryBody[FileRange]
def fileBody: EndpointIO.Body[FileRange, File] = rawBinaryBody[FileRange].map(_.toFile)(d => FileRange.from(d))
def fileBody: EndpointIO.Body[FileRange, File] = rawBinaryBody[FileRange].map(_.file)(d => FileRange(d))

def formBody[T: Codec[String, *, CodecFormat.XWwwFormUrlencoded]]: EndpointIO.Body[String, T] =
anyFromUtf8StringBody[T, CodecFormat.XWwwFormUrlencoded](implicitly)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,7 @@ class ServerInterpreter[R, F[_], B, S](
case DecodeResult.Value(bodyV) => (values.setBodyInputValue(bodyV): DecodeBasicInputsResult).unit
case failure: DecodeResult.Failure =>
v.createdFiles
.foldLeft(monad.unit(()))((u, f) => u.flatMap(_ => deleteFile(f.toFile)))
.foldLeft(monad.unit(()))((u, f) => u.flatMap(_ => deleteFile(f.file)))
.map(_ => DecodeBasicInputsResult.Failure(bodyInput, failure): DecodeBasicInputsResult)
}
}
Expand Down
11 changes: 0 additions & 11 deletions core/src/main/scalajs/sttp/tapir/TapirFileExtension.scala

This file was deleted.

14 changes: 0 additions & 14 deletions core/src/main/scalajvm/sttp/tapir/FileRangeExtension.scala

This file was deleted.

2 changes: 1 addition & 1 deletion core/src/main/scalajvm/sttp/tapir/internal/FileChunk.scala
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ object FileChunk {
case Some(range) =>
(range.start, range.end) match {
case (Some(start), Some(end)) =>
val stream = RangeInputStream(new FileInputStream(tapirFile.toPath.toFile), start, end)
val stream = RangeInputStream(new FileInputStream(tapirFile.file), start, end)
Some(stream)
case _ => None
}
Expand Down
4 changes: 2 additions & 2 deletions core/src/main/scalajvm/sttp/tapir/static/Files.scala
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ object Files {
result <-
if (isModified(filesInput, etag, lastModified)) {
val contentRange = range.toContentRange(file.length(), range.unit).toString()
m.unit(StaticOutput.FoundPartial(FileRange.from(file, range), Some(Instant.ofEpochMilli(lastModified)), Some(range.contentLength), Some(contentTypeFromName(file.getName)), etag, Some("bytes"), Some(contentRange)))
m.unit(StaticOutput.FoundPartial(FileRange(file, Some(range)), Some(Instant.ofEpochMilli(lastModified)), Some(range.contentLength), Some(contentTypeFromName(file.getName)), etag, Some("bytes"), Some(contentRange)))
}
else StaticOutput.NotModified.unit
} yield result
Expand All @@ -79,7 +79,7 @@ object Files {
result <-
if (isModified(filesInput, etag, lastModified))
m.blocking(file.toFile.length()).map(contentLength =>
StaticOutput.Found(FileRange.from(file.toFile), Some(Instant.ofEpochMilli(lastModified)), Some(contentLength), Some(contentTypeFromName(file.toFile.getName)), etag))
StaticOutput.Found(FileRange(file.toFile), Some(Instant.ofEpochMilli(lastModified)), Some(contentLength), Some(contentTypeFromName(file.toFile.getName)), etag))
else StaticOutput.NotModified.unit
} yield result

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -151,9 +151,9 @@ class MultipartCodecDerivationTest extends AnyFlatSpec with MultipartCodecDeriva
try {
// when
codec.encode(Test1(f)) shouldBe List(
Part("f1", FileRange.from(f), fileName = Some(f.getName), contentType = Some(MediaType.ApplicationOctetStream))
Part("f1", FileRange(f), fileName = Some(f.getName), contentType = Some(MediaType.ApplicationOctetStream))
)
codec.decode(List(Part("f1", FileRange.from(f), fileName = Some(f.getName)))) shouldBe DecodeResult.Value(Test1(f))
codec.decode(List(Part("f1", FileRange(f), fileName = Some(f.getName)))) shouldBe DecodeResult.Value(Test1(f))
} finally {
f.delete()
}
Expand All @@ -169,10 +169,10 @@ class MultipartCodecDerivationTest extends AnyFlatSpec with MultipartCodecDeriva
try {
// when
codec.encode(Test1(Part("?", Some(f), otherDispositionParams = Map("a1" -> "b1")), 12)) shouldBe List(
Part("f1", FileRange.from(f), otherDispositionParams = Map("a1" -> "b1"), contentType = Some(MediaType.ApplicationOctetStream)),
Part("f1", FileRange(f), otherDispositionParams = Map("a1" -> "b1"), contentType = Some(MediaType.ApplicationOctetStream)),
Part("f2", "12", contentType = Some(MediaType.TextPlain.charset(StandardCharsets.UTF_8)))
)
codec.decode(List(Part("f1", FileRange.from(f), fileName = Some(f.getName)), Part("f2", "12"))) shouldBe DecodeResult.Value(
codec.decode(List(Part("f1", FileRange(f), fileName = Some(f.getName)), Part("f2", "12"))) shouldBe DecodeResult.Value(
Test1(Part("f1", Some(f), fileName = Some(f.getName)), 12)
)
} finally {
Expand All @@ -190,7 +190,7 @@ class MultipartCodecDerivationTest extends AnyFlatSpec with MultipartCodecDeriva
val codec = implicitly[MultipartCodec[Test1]].codec

// when
codec.schema.name shouldBe Some(SName("sttp.tapir.generic.MultipartCodecDerivationTestJVM.<local MultipartCodecDerivationTestJVM>.Test1"))
codec.schema.name shouldBe Some(SName("sttp.tapir.generic.MultipartCodecDerivationTest.<local MultipartCodecDerivationTest>.Test1"))
codec.schema.schemaType shouldBe
SProduct[Test1](
List(field(FieldName("f1"), implicitly[Schema[File]]), field(FieldName("f2"), implicitly[Schema[Int]]))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ private[akkahttp] class AkkaRequestBody(ctx: RequestContext, request: ServerRequ
case RawBodyType.FileBody =>
serverOptions
.createFile(request)
.flatMap(file => body.dataBytes.runWith(FileIO.toPath(file.toPath)).map(_ => FileRange.from(file)).map(f => RawValue(f, Seq(f))))
.flatMap(file => body.dataBytes.runWith(FileIO.toPath(file.toPath)).map(_ => FileRange(file)).map(f => RawValue(f, Seq(f))))
case m: RawBodyType.MultipartBody =>
implicitly[FromEntityUnmarshaller[Multipart.FormData]].apply(body).flatMap { fd =>
fd.parts
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -62,12 +62,12 @@ private[akkahttp] class AkkaToResponseBody(implicit ec: ExecutionContext, m: Mat
.flatMap(range =>
(range.start, range.end) match {
case (Some(start), Some(end)) =>
val source = FileIO.fromPath(file.toPath).map(_.slice(start.toInt, end.toInt))
val source = FileIO.fromPath(file.file.toPath).map(_.slice(start.toInt, end.toInt))
Some(HttpEntity(ct, source))
case _ => None
}
)
.getOrElse(HttpEntity.fromPath(ct, file.toFile.toPath))
.getOrElse(HttpEntity.fromPath(ct, file.file.toPath))
case m: RawBodyType.MultipartBody =>
val parts = (r: Seq[RawPart]).flatMap(rawPartToBodyPart(m, _))
val body = Multipart.FormData(parts: _*)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ class FinatraRequestBody(request: Request, serverOptions: FinatraServerOptions)
case RawBodyType.ByteArrayBody => Future.value[R](asByteArray).map(RawValue(_))
case RawBodyType.ByteBufferBody => Future.value[R](asByteBuffer).map(RawValue(_))
case RawBodyType.InputStreamBody => Future.value[R](new ByteArrayInputStream(asByteArray)).map(RawValue(_))
case RawBodyType.FileBody => serverOptions.createFile(asByteArray).map(FileRange.from).map(file => RawValue(file, Seq(file)))
case RawBodyType.FileBody => serverOptions.createFile(asByteArray).map(f => FileRange(f)).map(file => RawValue(file, Seq(file)))
case m: RawBodyType.MultipartBody => multiPartRequestToRawBody(request, m).map(RawValue.fromParts)
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ class FinatraToResponseBody extends ToResponseBody[FinatraContent, NoStreams] {
val tapirFile = v.asInstanceOf[FileRange]
FileChunk.prepare(tapirFile)
.map(s => FinatraContentReader(Reader.fromStream(s)))
.getOrElse(FinatraContentReader(Reader.fromFile(tapirFile.toFile)))
.getOrElse(FinatraContentReader(Reader.fromFile(tapirFile.file)))
case m: RawBodyType.MultipartBody =>
val entity = MultipartEntityBuilder.create()
v.flatMap(rawPartToFormBodyPart(m, _)).foreach { formBodyPart: FormBodyPart => entity.addPart(formBodyPart) }
Expand All @@ -52,8 +52,8 @@ class FinatraToResponseBody extends ToResponseBody[FinatraContent, NoStreams] {
new ByteArrayBody(array, ContentType.create(contentType), part.fileName.get)
case RawBodyType.FileBody =>
part.fileName match {
case Some(filename) => new FileBody(r.asInstanceOf[FileRange].toFile, ContentType.create(contentType), filename)
case None => new FileBody(r.asInstanceOf[FileRange].toFile, ContentType.create(contentType))
case Some(filename) => new FileBody(r.asInstanceOf[FileRange].file, ContentType.create(contentType), filename)
case None => new FileBody(r.asInstanceOf[FileRange].file, ContentType.create(contentType))
}
case RawBodyType.InputStreamBody =>
new InputStreamBody(r, ContentType.create(contentType), part.fileName.get)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ private[http4s] class Http4sRequestBody[F[_]: Async, G[_]: Monad](
case RawBodyType.FileBody =>
serverOptions.createFile(serverRequest).flatMap { file =>
val fileSink = Files[F].writeAll(file.toPath)
t(body.through(fileSink).compile.drain.map(_ => RawValue(FileRange.from(file), Seq(FileRange.from(file)))))
t(body.through(fileSink).compile.drain.map(_ => RawValue(FileRange(file), Seq(FileRange(file)))))
}
case m: RawBodyType.MultipartBody =>
// TODO: use MultipartDecoder.mixedMultipart once available?
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -54,10 +54,10 @@ private[http4s] class Http4sToResponseBody[F[_]: Async, G[_]](
tapirFile.range.flatMap(range => {
(range.start, range.end) match {
case (Some(start), Some(end)) =>
Some(Files[F].readRange(tapirFile.toPath, range.contentLength.toInt, start, end))
Some(Files[F].readRange(tapirFile.file.toPath, range.contentLength.toInt, start, end))
case _ => None
}
}).getOrElse(Files[F].readAll(tapirFile.toFile.toPath, serverOptions.ioChunkSize))
}).getOrElse(Files[F].readAll(tapirFile.file.toPath, serverOptions.ioChunkSize))
case m: RawBodyType.MultipartBody =>
val parts = (r: Seq[RawPart]).flatMap(rawPartToBodyPart(m, _))
val body = implicitly[EntityEncoder[F, multipart.Multipart[F]]].toEntity(multipart.Multipart(parts.toVector)).body
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,11 +44,11 @@ private[play] class PlayRequestBody(request: Request[Source[ByteString, Any]], s
case RawBodyType.FileBody =>
bodyAsFile match {
case Some(file) =>
val tapirFile = FileRange.from(file)
val tapirFile = FileRange(file)
Future.successful(RawValue(tapirFile, Seq(tapirFile)))
case None =>
val file = FileRange.from(serverOptions.temporaryFileCreator.create().toFile)
body().runWith(FileIO.toPath(file.toFile.toPath)).map(_ => RawValue(file, Seq(file)))
val file = FileRange(serverOptions.temporaryFileCreator.create().toFile)
body().runWith(FileIO.toPath(file.file.toPath)).map(_ => RawValue(file, Seq(file)))
}
case m: RawBodyType.MultipartBody => multiPartRequestToRawBody(request, m, body)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,11 +47,11 @@ class PlayToResponseBody extends ToResponseBody[HttpEntity, AkkaStreams] {
val tapirFile = v.asInstanceOf[FileRange]
tapirFile.range.flatMap(range =>
range.start.map(start => {
val file = FileIO.fromPath(tapirFile.toPath, range.contentLength.toInt, start)
val file = FileIO.fromPath(tapirFile.file.toPath, range.contentLength.toInt, start)
HttpEntity.Streamed(file, Option(range.contentLength), contentType)
})
).getOrElse({
val path = tapirFile.toFile.toPath
val path = tapirFile.file.toPath
val fileSize = Some(Files.size(path))
val file = FileIO.fromPath(path)
HttpEntity.Streamed(file, fileSize, contentType)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ class VertxRequestBody[F[_], S <: Streams[S]](
rc.fileUploads().asScala.headOption match {
case Some(upload) =>
Future.succeededFuture {
val file = FileRange.from(new File(upload.uploadedFileName()))
val file = FileRange(new File(upload.uploadedFileName()))
RawValue(file, Seq(file))
}
case None if rc.getBody != null =>
Expand All @@ -53,7 +53,7 @@ class VertxRequestBody[F[_], S <: Streams[S]](
.flatMap(_ => fs.writeFile(filePath, rc.getBody))
.flatMap(_ =>
Future.succeededFuture {
val file = FileRange.from(new File(filePath))
val file = FileRange(new File(filePath))
RawValue(file, Seq(file))
}
)
Expand Down Expand Up @@ -90,7 +90,7 @@ class VertxRequestBody[F[_], S <: Streams[S]](
case RawBodyType.InputStreamBody => throw new IllegalArgumentException("Cannot create a multipart as an InputStream")
case RawBodyType.FileBody =>
val f = rc.fileUploads.asScala.find(_.name == name).get
FileRange.from(new File(f.uploadedFileName()))
FileRange(new File(f.uploadedFileName()))
case RawBodyType.MultipartBody(partTypes, _) =>
partTypes.map { case (partName, rawBodyType) =>
Part(partName, extractPart(partName, rawBodyType))
Expand Down
Loading

0 comments on commit 7ed2f90

Please sign in to comment.