src/main/scala/s3/website/model/push.scala in s3_website-2.14.1 vs src/main/scala/s3/website/model/push.scala in s3_website-2.14.2

- old
+ new

@@ -7,16 +7,16 @@ import java.util.zip.{GZIPInputStream, GZIPOutputStream} import org.apache.tika.Tika import s3.website.Ruby._ import s3.website._ -import s3.website.model.Upload.tika -import s3.website.model.Encoding.encodingOnS3 +import s3.website.model.Upload.{amountOfMagicGzipBytes, tika} +import s3.website.model.Encoding.{Gzip, Zopfli, encodingOnS3} import java.io.File.createTempFile -import org.apache.commons.io.FileUtils -import org.apache.commons.io.IOUtils.copy +import org.apache.commons.io.{FileUtils, IOUtils} +import org.apache.commons.io.IOUtils._ import scala.concurrent.{ExecutionContextExecutor, Future} import scala.util.Try object Encoding { @@ -58,20 +58,25 @@ case class Upload(originalFile: File, uploadType: UploadType)(implicit site: Site, logger: Logger) { lazy val s3Key = site.resolveS3Key(originalFile) lazy val encodingOnS3 = Encoding.encodingOnS3(s3Key) + lazy val gzipEnabledByConfig: Boolean = encodingOnS3.fold(false)((algorithm: Either[Gzip, Zopfli]) => true) - /** - * This is the file we should upload, because it contains the potentially gzipped contents of the original file. - * - * May throw an exception, so remember to call this in a Try or Future monad - */ - lazy val uploadFile: Try[File] = Upload uploadFile originalFile - lazy val contentType: Try[String] = tika map { tika => - val mimeType = tika.detect(originalFile) + val file = // This file contains the data that the user should see after decoding the the transport protocol (HTTP) encoding (practically: after ungzipping) + if (fileIsGzippedByExternalBuildTool) { + val unzippedFile = createTempFile(originalFile.getName, "unzipped") + unzippedFile.deleteOnExit() + using(new GZIPInputStream(fis(originalFile))) { stream => + IOUtils.copy(stream, new FileOutputStream(unzippedFile)) + } + unzippedFile + } else { + originalFile + } + val mimeType = tika.detect(file) if (mimeType.startsWith("text/") || mimeType == "application/json") mimeType + "; charset=utf-8" else mimeType } @@ -93,51 +98,53 @@ ) /** * May throw an exception, so remember to call this in a Try or Future monad */ - lazy val md5 = Upload md5 originalFile -} + lazy val md5 = uploadFile map { file => + using(fis { file }) { DigestUtils.md5Hex } + } -object Upload { - lazy val tika = Try(new Tika()) - - def md5(originalFile: File)(implicit site: Site, logger: Logger): Try[MD5] = - uploadFile(originalFile) map { file => - using(fis { file }) { DigestUtils.md5Hex } - } - - def uploadFile(originalFile: File)(implicit site: Site, logger: Logger): Try[File] = - encodingOnS3(site resolveS3Key originalFile) - .fold(Try(originalFile))(algorithm => - Try { - val isAlreadyGzipped = - if (originalFile.length() < 2) { - false - } else { - val fis = new FileInputStream(originalFile) - val amountOfMagicGzipBytes = 2 - val firstTwoBytes = Array.fill[Byte](amountOfMagicGzipBytes)(0) - fis.read(firstTwoBytes, 0, amountOfMagicGzipBytes) - val head = firstTwoBytes(0) & 0xff | (firstTwoBytes(1) << 8) & 0xff00 - head == GZIPInputStream.GZIP_MAGIC - } - if (isAlreadyGzipped) { - logger.debug(s"File ${originalFile.getAbsolutePath} is already gzipped. Skipping gzip.") - originalFile - } else { - val tempFile = createTempFile(originalFile.getName, "gzip") - tempFile.deleteOnExit() - using(new GZIPOutputStream(new FileOutputStream(tempFile))) { stream => - copy(fis(originalFile), stream) - } - tempFile + // This is the file we should try to upload + lazy val uploadFile: Try[File] = + if (gzipEnabledByConfig) + Try { + if (fileIsGzippedByExternalBuildTool) { + logger.debug(s"File ${originalFile.getAbsolutePath} is already gzipped. Skipping gzip.") + originalFile + } else { + logger.debug(s"Gzipping file ${originalFile.getName}") + val tempFile = createTempFile(originalFile.getName, "gzip") + tempFile.deleteOnExit() + using(new GZIPOutputStream(new FileOutputStream(tempFile))) { stream => + IOUtils.copy(fis(originalFile), stream) } + tempFile } - ) + } + else + Try(originalFile) + private lazy val fileIsGzippedByExternalBuildTool = gzipEnabledByConfig && originalFileIsGzipped + + private lazy val originalFileIsGzipped = + if (originalFile.length() < amountOfMagicGzipBytes) { + false + } else { + val fis = new FileInputStream(originalFile) + val firstTwoBytes = Array.fill[Byte](amountOfMagicGzipBytes)(0) + fis.read(firstTwoBytes, 0, amountOfMagicGzipBytes) + val head = firstTwoBytes(0) & 0xff | (firstTwoBytes(1) << 8) & 0xff00 + head == GZIPInputStream.GZIP_MAGIC + } + private[this] def fis(file: File): InputStream = new FileInputStream(file) private[this] def using[T <: Closeable, R](cl: T)(f: (T) => R): R = try f(cl) finally cl.close() +} + +object Upload { + lazy val tika = Try(new Tika()) + private val amountOfMagicGzipBytes = 2 } object Files { def recursiveListFiles(f: File): Seq[File] = { val these = f.listFiles