s3_website 2.8.3 → 2.8.4
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/changelog.md +8 -0
- data/lib/s3_website/version.rb +1 -1
- data/src/main/scala/s3/website/CloudFront.scala +30 -31
- data/src/main/scala/s3/website/Ruby.scala +1 -1
- data/src/test/scala/s3/website/S3WebsiteSpec.scala +1 -1
- data/src/test/scala/s3/website/UnitTest.scala +11 -0
- metadata +4 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 3eb61e148cba2a736188f4722ffe0f83c880c3e6
|
4
|
+
data.tar.gz: 18d990870b6d1f84c41517ee3fdc84e3cb2d8d8f
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: d9b477c47017a4c3d53c06201f473f595ece6bd1e656405907b3c4cbb1f79475e02c397ffae1d67c92a2b6770d7b68cf8e3eecbc2d7a9726e48ee974f4b8b41d
|
7
|
+
data.tar.gz: e97b944a26585749bef90578ec657d9dff4b40835cdfa1cdb177f937ef5cc0e029a9905ccc965111b78a42a7637e3f1e2e2f4d4f49dc4b4426f1c48cda81b9bf
|
data/changelog.md
CHANGED
@@ -2,6 +2,14 @@
|
|
2
2
|
|
3
3
|
This project uses [Semantic Versioning](http://semver.org).
|
4
4
|
|
5
|
+
## 2.8.4
|
6
|
+
|
7
|
+
* URL encude ' in invalidation path
|
8
|
+
|
9
|
+
See <https://github.com/laurilehmijoki/s3_website/issues/63> for discussion.
|
10
|
+
|
11
|
+
* Accept ' in `exclude_from_upload` and `ignore_on_server`
|
12
|
+
|
5
13
|
## 2.8.3
|
6
14
|
|
7
15
|
* Fix bug where the setting `cloudfront_invalidate_root: true` resulted in a
|
data/lib/s3_website/version.rb
CHANGED
@@ -8,7 +8,7 @@ import scala.collection.JavaConversions._
|
|
8
8
|
import scala.concurrent.duration._
|
9
9
|
import s3.website.S3.{SuccessfulDelete, PushSuccessReport, SuccessfulUpload}
|
10
10
|
import com.amazonaws.auth.BasicAWSCredentials
|
11
|
-
import java.net.URI
|
11
|
+
import java.net.{URLEncoder, URI}
|
12
12
|
import scala.concurrent.{ExecutionContextExecutor, Future}
|
13
13
|
import s3.website.model.Config.awsCredentials
|
14
14
|
|
@@ -68,29 +68,34 @@ object CloudFront {
|
|
68
68
|
def awsCloudFrontClient(config: Config) = new AmazonCloudFrontClient(awsCredentials(config))
|
69
69
|
|
70
70
|
def toInvalidationBatches(pushSuccessReports: Seq[PushSuccessReport])(implicit config: Config): Seq[InvalidationBatch] = {
|
71
|
+
def defaultPath(paths: Seq[String]): Option[String] = {
|
72
|
+
// This is how we support the Default Root Object @ CloudFront (http://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/DefaultRootObject.html)
|
73
|
+
// We could do this more accurately by fetching the distribution config (http://docs.aws.amazon.com/AmazonCloudFront/latest/APIReference/GetConfig.html)
|
74
|
+
// and reading the Default Root Object from there.
|
75
|
+
val containsPotentialDefaultRootObject = paths
|
76
|
+
.exists(
|
77
|
+
_
|
78
|
+
.replaceFirst("^/", "") // S3 keys do not begin with a slash
|
79
|
+
.contains("/") == false // See if the S3 key is a top-level key (i.e., it is not within a directory)
|
80
|
+
)
|
81
|
+
if (containsPotentialDefaultRootObject) Some("/") else None
|
82
|
+
}
|
83
|
+
val indexPath = config.cloudfront_invalidate_root collect {
|
84
|
+
case true if pushSuccessReports.nonEmpty => "/index.html"
|
85
|
+
}
|
86
|
+
|
71
87
|
val invalidationPaths: Seq[String] = {
|
72
|
-
def withDefaultPathIfNeeded(paths: Seq[String]) = {
|
73
|
-
// This is how we support the Default Root Object @ CloudFront (http://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/DefaultRootObject.html)
|
74
|
-
// We do this more accurately by fetching the distribution config (http://docs.aws.amazon.com/AmazonCloudFront/latest/APIReference/GetConfig.html)
|
75
|
-
// and reading the Default Root Object from there.
|
76
|
-
val containsPotentialDefaultRootObject = paths
|
77
|
-
.exists(
|
78
|
-
_
|
79
|
-
.replaceFirst("^/", "") // S3 keys do not begin with a slash
|
80
|
-
.contains("/") == false // See if the S3 key is a top-level key (i.e., it is not within a directory)
|
81
|
-
)
|
82
|
-
if (containsPotentialDefaultRootObject) paths :+ "/" else paths
|
83
|
-
}
|
84
|
-
def withIndexPathIfNeeded(paths: Seq[String]) =
|
85
|
-
if (config.cloudfront_invalidate_root.contains(true) && pushSuccessReports.nonEmpty)
|
86
|
-
paths :+ "/index.html"
|
87
|
-
else
|
88
|
-
paths
|
89
88
|
val paths = pushSuccessReports
|
90
|
-
.filter(needsInvalidation)
|
89
|
+
.filter(needsInvalidation)
|
91
90
|
.map(toInvalidationPath)
|
91
|
+
.map(encodeUnsafeChars)
|
92
92
|
.map(applyInvalidateRootSetting)
|
93
|
-
|
93
|
+
|
94
|
+
val extraPathItems = defaultPath(paths) :: indexPath :: Nil collect {
|
95
|
+
case Some(path) => path
|
96
|
+
}
|
97
|
+
|
98
|
+
paths ++ extraPathItems
|
94
99
|
}
|
95
100
|
|
96
101
|
invalidationPaths
|
@@ -109,17 +114,11 @@ object CloudFront {
|
|
109
114
|
else
|
110
115
|
path
|
111
116
|
|
112
|
-
def toInvalidationPath(report: PushSuccessReport) =
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
"/" + report.s3Key, // CloudFront keys have the slash in front
|
118
|
-
path
|
119
|
-
).toURL.getPath // The URL class encodes the unsafe characters
|
120
|
-
val invalidationPath = "/" + report.s3Key // CloudFront keys have the slash in front
|
121
|
-
encodeUnsafeChars(invalidationPath)
|
122
|
-
}
|
117
|
+
def toInvalidationPath(report: PushSuccessReport) = "/" + report.s3Key
|
118
|
+
|
119
|
+
def encodeUnsafeChars(invalidationPath: String) =
|
120
|
+
new URI("http", "cloudfront", invalidationPath, "").toURL.getPath
|
121
|
+
.replaceAll("'", URLEncoder.encode("'", "UTF-8")) // CloudFront does not accept ' in invalidation path
|
123
122
|
|
124
123
|
|
125
124
|
def needsInvalidation: PartialFunction[PushSuccessReport, Boolean] = {
|
@@ -6,7 +6,7 @@ object Ruby {
|
|
6
6
|
def rubyRegexMatches(text: String, regex: String) = {
|
7
7
|
val z = rubyRuntime.evalScriptlet(
|
8
8
|
s"""# encoding: utf-8
|
9
|
-
!!Regexp.new(
|
9
|
+
!!Regexp.new("$regex").match("$text")"""
|
10
10
|
)
|
11
11
|
z.toJava(classOf[Boolean]).asInstanceOf[Boolean]
|
12
12
|
}
|
@@ -204,7 +204,7 @@ class S3WebsiteSpec extends Specification {
|
|
204
204
|
setLocalFile("articles/arnold's file.html")
|
205
205
|
setOutdatedS3Keys("articles/arnold's file.html")
|
206
206
|
push()
|
207
|
-
sentInvalidationRequest.getInvalidationBatch.getPaths.getItems.toSeq.sorted must equalTo(("/articles/arnold
|
207
|
+
sentInvalidationRequest.getInvalidationBatch.getPaths.getItems.toSeq.sorted must equalTo(("/articles/arnold%27s%20file.html" :: Nil).sorted)
|
208
208
|
}
|
209
209
|
|
210
210
|
"invalidate the root object '/' if a top-level object is updated or deleted" in new BasicSetup {
|
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.8.
|
4
|
+
version: 2.8.4
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Lauri Lehmijoki
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2015-
|
11
|
+
date: 2015-03-01 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: thor
|
@@ -142,6 +142,7 @@ files:
|
|
142
142
|
- src/main/scala/s3/website/package.scala
|
143
143
|
- src/test/scala/s3/website/AwsSdkSpec.scala
|
144
144
|
- src/test/scala/s3/website/S3WebsiteSpec.scala
|
145
|
+
- src/test/scala/s3/website/UnitTest.scala
|
145
146
|
- vagrant/Vagrantfile
|
146
147
|
homepage: https://github.com/laurilehmijoki/s3_website
|
147
148
|
licenses:
|
@@ -170,3 +171,4 @@ summary: Manage your S3 website
|
|
170
171
|
test_files:
|
171
172
|
- src/test/scala/s3/website/AwsSdkSpec.scala
|
172
173
|
- src/test/scala/s3/website/S3WebsiteSpec.scala
|
174
|
+
- src/test/scala/s3/website/UnitTest.scala
|