s3_website 2.14.1 → 2.14.2

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 3bbec93340ef359945d7d3cfbe80883d68375991
4
- data.tar.gz: 5bdcd5868373b3864e4dd5e5632cf3776a4c2486
3
+ metadata.gz: 0ec6e16da212e3d7ca9874580d8dd9be94860ad9
4
+ data.tar.gz: 52622ca62f5343414315af55e456dbb4b03a2230
5
5
  SHA512:
6
- metadata.gz: 8c1ce8a06185665f9c5069ef5a116c596928bed0b0045e8ab8fb4ca0a2e83c40897229b8581705f15907840cca5d2bbffc97d6d9735d1f1444645fcbd7b44cf9
7
- data.tar.gz: 626d786f95ed0678bc13fddc544c37a8775f7e3856d7dbb9e158da8ac06fee042288323f4b5296e24ee517ea04ca8f93f98486abd698fef407902762df74c674
6
+ metadata.gz: 4aaf8cf3d256762c897c777f175c6f5e549ece335a0ed45005980c1676d6876a85f91d6dbf1d6b9e038bbd28e3bb846d8bb6e8d31afebcced7320805176df2d0
7
+ data.tar.gz: 510fe2386587a3b07e08e9fb017c47a9a7abb01ddb2eccc51f0ba9c099b875ac451cc5e03291247e72d12998a35e85ebfcdba8acae67a2335f3991f1ee36522a
data/changelog.md CHANGED
@@ -2,6 +2,12 @@
2
2
 
3
3
  This project uses [Semantic Versioning](http://semver.org).
4
4
 
5
+ ## 2.14.2
6
+
7
+ * Apply correct mime type on already-gzipped files
8
+
9
+ See <https://github.com/laurilehmijoki/s3_website/issues/229#issuecomment-237229421> for discussion
10
+
5
11
  ## 2.14.1
6
12
 
7
13
  * Do not gzip a file that is already gzipped
@@ -1,3 +1,3 @@
1
1
  module S3Website
2
- VERSION = '2.14.1'
2
+ VERSION = '2.14.2'
3
3
  end
@@ -9,12 +9,12 @@ import java.util.zip.{GZIPInputStream, GZIPOutputStream}
9
9
  import org.apache.tika.Tika
10
10
  import s3.website.Ruby._
11
11
  import s3.website._
12
- import s3.website.model.Upload.tika
13
- import s3.website.model.Encoding.encodingOnS3
12
+ import s3.website.model.Upload.{amountOfMagicGzipBytes, tika}
13
+ import s3.website.model.Encoding.{Gzip, Zopfli, encodingOnS3}
14
14
  import java.io.File.createTempFile
15
15
 
16
- import org.apache.commons.io.FileUtils
17
- import org.apache.commons.io.IOUtils.copy
16
+ import org.apache.commons.io.{FileUtils, IOUtils}
17
+ import org.apache.commons.io.IOUtils._
18
18
 
19
19
  import scala.concurrent.{ExecutionContextExecutor, Future}
20
20
  import scala.util.Try
@@ -60,16 +60,21 @@ case class Upload(originalFile: File, uploadType: UploadType)(implicit site: Sit
60
60
  lazy val s3Key = site.resolveS3Key(originalFile)
61
61
 
62
62
  lazy val encodingOnS3 = Encoding.encodingOnS3(s3Key)
63
-
64
- /**
65
- * This is the file we should upload, because it contains the potentially gzipped contents of the original file.
66
- *
67
- * May throw an exception, so remember to call this in a Try or Future monad
68
- */
69
- lazy val uploadFile: Try[File] = Upload uploadFile originalFile
63
+ lazy val gzipEnabledByConfig: Boolean = encodingOnS3.fold(false)((algorithm: Either[Gzip, Zopfli]) => true)
70
64
 
71
65
  lazy val contentType: Try[String] = tika map { tika =>
72
- val mimeType = tika.detect(originalFile)
66
+ val file = // This file contains the data that the user should see after decoding the the transport protocol (HTTP) encoding (practically: after ungzipping)
67
+ if (fileIsGzippedByExternalBuildTool) {
68
+ val unzippedFile = createTempFile(originalFile.getName, "unzipped")
69
+ unzippedFile.deleteOnExit()
70
+ using(new GZIPInputStream(fis(originalFile))) { stream =>
71
+ IOUtils.copy(stream, new FileOutputStream(unzippedFile))
72
+ }
73
+ unzippedFile
74
+ } else {
75
+ originalFile
76
+ }
77
+ val mimeType = tika.detect(file)
73
78
  if (mimeType.startsWith("text/") || mimeType == "application/json")
74
79
  mimeType + "; charset=utf-8"
75
80
  else
@@ -95,50 +100,52 @@ case class Upload(originalFile: File, uploadType: UploadType)(implicit site: Sit
95
100
  /**
96
101
  * May throw an exception, so remember to call this in a Try or Future monad
97
102
  */
98
- lazy val md5 = Upload md5 originalFile
99
- }
100
-
101
- object Upload {
102
- lazy val tika = Try(new Tika())
103
-
104
- def md5(originalFile: File)(implicit site: Site, logger: Logger): Try[MD5] =
105
- uploadFile(originalFile) map { file =>
106
- using(fis { file }) { DigestUtils.md5Hex }
107
- }
103
+ lazy val md5 = uploadFile map { file =>
104
+ using(fis { file }) { DigestUtils.md5Hex }
105
+ }
108
106
 
109
- def uploadFile(originalFile: File)(implicit site: Site, logger: Logger): Try[File] =
110
- encodingOnS3(site resolveS3Key originalFile)
111
- .fold(Try(originalFile))(algorithm =>
112
- Try {
113
- val isAlreadyGzipped =
114
- if (originalFile.length() < 2) {
115
- false
116
- } else {
117
- val fis = new FileInputStream(originalFile)
118
- val amountOfMagicGzipBytes = 2
119
- val firstTwoBytes = Array.fill[Byte](amountOfMagicGzipBytes)(0)
120
- fis.read(firstTwoBytes, 0, amountOfMagicGzipBytes)
121
- val head = firstTwoBytes(0) & 0xff | (firstTwoBytes(1) << 8) & 0xff00
122
- head == GZIPInputStream.GZIP_MAGIC
123
- }
124
- if (isAlreadyGzipped) {
125
- logger.debug(s"File ${originalFile.getAbsolutePath} is already gzipped. Skipping gzip.")
126
- originalFile
127
- } else {
128
- val tempFile = createTempFile(originalFile.getName, "gzip")
129
- tempFile.deleteOnExit()
130
- using(new GZIPOutputStream(new FileOutputStream(tempFile))) { stream =>
131
- copy(fis(originalFile), stream)
132
- }
133
- tempFile
107
+ // This is the file we should try to upload
108
+ lazy val uploadFile: Try[File] =
109
+ if (gzipEnabledByConfig)
110
+ Try {
111
+ if (fileIsGzippedByExternalBuildTool) {
112
+ logger.debug(s"File ${originalFile.getAbsolutePath} is already gzipped. Skipping gzip.")
113
+ originalFile
114
+ } else {
115
+ logger.debug(s"Gzipping file ${originalFile.getName}")
116
+ val tempFile = createTempFile(originalFile.getName, "gzip")
117
+ tempFile.deleteOnExit()
118
+ using(new GZIPOutputStream(new FileOutputStream(tempFile))) { stream =>
119
+ IOUtils.copy(fis(originalFile), stream)
134
120
  }
121
+ tempFile
135
122
  }
136
- )
123
+ }
124
+ else
125
+ Try(originalFile)
126
+
127
+ private lazy val fileIsGzippedByExternalBuildTool = gzipEnabledByConfig && originalFileIsGzipped
128
+
129
+ private lazy val originalFileIsGzipped =
130
+ if (originalFile.length() < amountOfMagicGzipBytes) {
131
+ false
132
+ } else {
133
+ val fis = new FileInputStream(originalFile)
134
+ val firstTwoBytes = Array.fill[Byte](amountOfMagicGzipBytes)(0)
135
+ fis.read(firstTwoBytes, 0, amountOfMagicGzipBytes)
136
+ val head = firstTwoBytes(0) & 0xff | (firstTwoBytes(1) << 8) & 0xff00
137
+ head == GZIPInputStream.GZIP_MAGIC
138
+ }
137
139
 
138
140
  private[this] def fis(file: File): InputStream = new FileInputStream(file)
139
141
  private[this] def using[T <: Closeable, R](cl: T)(f: (T) => R): R = try f(cl) finally cl.close()
140
142
  }
141
143
 
144
+ object Upload {
145
+ lazy val tika = Try(new Tika())
146
+ private val amountOfMagicGzipBytes = 2
147
+ }
148
+
142
149
  object Files {
143
150
  def recursiveListFiles(f: File): Seq[File] = {
144
151
  val these = f.listFiles
@@ -44,11 +44,10 @@ class S3WebsiteSpec extends Specification {
44
44
  sentPutObjectRequest.getKey must equalTo("styles.css")
45
45
  }
46
46
 
47
- "gzips a file" in new BasicSetup {
47
+ "gzip a file" in new BasicSetup {
48
48
  val htmlString = "<h1>hi again</h1>"
49
- val gzippedBytes = gzip(htmlString.getBytes(StandardCharsets.UTF_8))
50
49
  config = "gzip: true"
51
- setLocalFileWithContent("index.html", gzippedBytes)
50
+ setLocalFileWithContent(("index.html", htmlString))
52
51
  setS3File("styles.css", "1c5117e5839ad8fc00ce3c41296255a1" /* md5 of the gzip of the file contents */)
53
52
  val putObjectRequestCaptor = ArgumentCaptor.forClass(classOf[PutObjectRequest])
54
53
  push()
@@ -62,6 +61,15 @@ class S3WebsiteSpec extends Specification {
62
61
  unzippedString must equalTo(htmlString)
63
62
  }
64
63
 
64
+ "apply the correct mime type on an already gzipped file" in new BasicSetup {
65
+ val htmlString = "<html><body><h1>Hello world</h1></body></html>"
66
+ val gzippedHtml = gzip(htmlString.getBytes(StandardCharsets.UTF_8))
67
+ config = "gzip: true"
68
+ setLocalFileWithContent("index.html", gzippedHtml)
69
+ push()
70
+ sentPutObjectRequest.getMetadata.getContentType must equalTo("text/html; charset=utf-8")
71
+ }
72
+
65
73
  "not gzip the file if it's already gzipped" in new BasicSetup {
66
74
  config = "gzip: true"
67
75
 
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: s3_website
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.14.1
4
+ version: 2.14.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Lauri Lehmijoki
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2016-08-02 00:00:00.000000000 Z
11
+ date: 2016-08-04 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: thor