Skip to content

Commit

Permalink
Return actual content type of pre-gzipped file (#2939)
Browse files Browse the repository at this point in the history
  • Loading branch information
kciesielski committed Jun 6, 2023
1 parent 5504445 commit 9456ff5
Show file tree
Hide file tree
Showing 3 changed files with 40 additions and 6 deletions.
2 changes: 1 addition & 1 deletion files/src/main/scalajvm/sttp/tapir/files/Files.scala
Expand Up @@ -86,7 +86,7 @@ object Files {
if (!realRequestedPath.startsWith(resolvedGzipped))
LeftUrlNotFound
else
Right(ResolvedUrl(realRequestedPath.toUri.toURL, MediaType.ApplicationGzip, Some("gzip")))
Right(ResolvedUrl(realRequestedPath.toUri.toURL, contentTypeFromName(resolved.getFileName.toString), Some("gzip")))
} else {
if (!JFiles.exists(resolved, LinkOption.NOFOLLOW_LINKS)) {
default match {
Expand Down
2 changes: 1 addition & 1 deletion files/src/main/scalajvm/sttp/tapir/files/Resources.scala
Expand Up @@ -72,7 +72,7 @@ object Resources {
def resolveRec(path: List[String], default: Option[List[String]]): Option[ResolvedUrl] = {
val name = (resourcePrefix ++ path).mkString("/")
val resultOpt = (if (useGzippedIfAvailable(input, options))
Option(classLoader.getResource(name + ".gz")).map(ResolvedUrl(_, MediaType.ApplicationGzip, Some("gzip")))
Option(classLoader.getResource(name + ".gz")).map(ResolvedUrl(_, contentTypeFromName(name), Some("gzip")))
else None)
.orElse(Option(classLoader.getResource(name)).map(ResolvedUrl(_, contentTypeFromName(name), None)))
.orElse(default match {
Expand Down
Expand Up @@ -23,6 +23,8 @@ import java.util.Comparator
import scala.concurrent.Future
import java.io.ByteArrayOutputStream
import java.util.zip.GZIPOutputStream
import java.util.zip.GZIPInputStream
import java.io.ByteArrayInputStream

class ServerFilesTests[F[_], OPTIONS, ROUTE](
serverInterpreter: TestServerInterpreter[F, Any, OPTIONS, ROUTE],
Expand Down Expand Up @@ -159,6 +161,7 @@ class ServerFilesTests[F[_], OPTIONS, ROUTE](
},
Test("should return pre-gzipped files") {
// https://github.com/softwaremill/tapir/issues/2869
// https://github.com/softwaremill/tapir/issues/2929
withTestFilesDirectory { testDir =>
serveRoute(
staticFilesGetServerEndpoint[F]("test")(testDir.getAbsolutePath, FilesOptions.default.withUseGzippedIfAvailable)
Expand All @@ -174,8 +177,32 @@ class ServerFilesTests[F[_], OPTIONS, ROUTE](
.map(r => {
r.code shouldBe StatusCode.Ok
r.body shouldBe "img gzipped content"
r.headers contains Header(HeaderNames.ContentEncoding, "gzip") shouldBe true
r.headers contains Header(HeaderNames.ContentType, MediaType.ApplicationGzip.toString()) shouldBe true
r.headers should contain(Header(HeaderNames.ContentEncoding, "gzip"))
r.headers should contain(Header(HeaderNames.ContentType, MediaType.ImageGif.toString()))
})
testCases.sequence.map(_.last)
}
.unsafeToFuture()
}
},
Test("should return compressed file directly") {
// https://github.com/softwaremill/tapir/issues/2929
withTestFilesDirectory { testDir =>
serveRoute(
staticFilesGetServerEndpoint[F]("test")(testDir.getAbsolutePath, FilesOptions.default.withUseGzippedIfAvailable)
)
.use { port =>
val testCases =
for (acceptEncodingValue <- List("gzip, deflate", "gzip", "deflate, gzip;q=1.0, *;q=0.5"))
yield emptyRequest
.acceptEncoding(acceptEncodingValue)
.get(uri"http://localhost:$port/test/img.gif.gz")
.response(asByteArrayAlways)
.send(backend)
.map(r => {
r.code shouldBe StatusCode.Ok
decompress(r.body) shouldBe "img gzipped content"
r.headers should contain(Header(HeaderNames.ContentType, MediaType.ApplicationGzip.toString()))
})
testCases.sequence.map(_.last)
}
Expand Down Expand Up @@ -378,8 +405,8 @@ class ServerFilesTests[F[_], OPTIONS, ROUTE](
.map(r => {
r.code shouldBe StatusCode.Ok
r.body shouldBe "Gzipped resource"
r.headers contains Header(HeaderNames.ContentEncoding, "gzip") shouldBe true
r.headers contains Header(HeaderNames.ContentType, MediaType.ApplicationGzip.toString()) shouldBe true
r.headers should contain(Header(HeaderNames.ContentEncoding, "gzip"))
r.headers should contain (Header(HeaderNames.ContentType, MediaType.TextPlain.toString()))
})
}
.unsafeToFuture()
Expand Down Expand Up @@ -654,6 +681,13 @@ class ServerFilesTests[F[_], OPTIONS, ROUTE](
outputStream.toByteArray
}

def decompress(bytes: Array[Byte]): String = {
val inputStream = new GZIPInputStream(new ByteArrayInputStream(bytes))
val outputStream = new ByteArrayOutputStream()
inputStream.transferTo(outputStream)
outputStream.toString("UTF-8")
}

def withTestFilesDirectory[T](t: File => Future[T]): Future[T] = {
val parent = Files.createTempDirectory("tapir-tests")

Expand Down

0 comments on commit 9456ff5

Please sign in to comment.