diff --git a/DOCS.md b/DOCS.md index 24d87c1..ea5899f 100644 --- a/DOCS.md +++ b/DOCS.md @@ -9,6 +9,7 @@ Use the S3 sync plugin to synchronize files and folders with an Amazon S3 bucket * `target` - target folder in your S3 bucket * `delete` - deletes files in the target not found in the source * `content_type` - override default mime-types to use this value +* `content_encoding` - override default content encoding header for files * `metadata` - set custom metadata * `redirects` - targets that should redirect elsewhere * `cloudfront_distribution_id` - (optional) the cloudfront distribution id to invalidate after syncing @@ -29,7 +30,7 @@ publish: cloudfront_distribution_id: "9c5785d3ece6a9cdefa4" ``` -Both `acl` and `content_type` can be passed as a string value to apply to all files, or as a map to apply to a subset of files. +The `acl`, `content_type`, and `content_encoding` parameters can be passed as a string value to apply to all files, or as a map to apply to a subset of files. For example: @@ -41,6 +42,9 @@ publish: "private/*": private content_type: ".svg": image/svg+xml + content_encoding: + ".js": gzip + ".css": gzip region: "us-east-1" bucket: "my-bucket.s3-website-us-east-1.amazonaws.com" access_key: "970d28f4dd477bc184fbd10b376de753" @@ -54,6 +58,9 @@ In the case of `acl` the key of the map is a glob. If there are no matches in yo The `content_type` field the key is an extension including the leading dot `.`. If you want to set a content type for files with no extension, set the key to the empty string `""`. If there are no matches for the `content_type` of any file, one will automatically be determined for you. +In the `content_encoding` field the key is an extension including the leading dot `.`. If you want to set a encoding type for files with no extension, set the key +to th empty string `""`. If there are no matches for the `content_encoding` of a file, no content-encoding header will be added. + The `metadata` field can be set as either an object where the keys are the metadata headers: ```yaml diff --git a/aws.go b/aws.go index 56ddd41..7d114f3 100644 --- a/aws.go +++ b/aws.go @@ -82,6 +82,19 @@ func (a *AWS) Upload(local, remote string) error { } } + var contentEncoding string + if a.vargs.ContentEncoding.IsString() { + contentEncoding = a.vargs.ContentEncoding.String() + } else if !a.vargs.ContentEncoding.IsEmpty() { + encodingMap := a.vargs.ContentEncoding.Map() + for patternExt := range encodingMap { + if patternExt == fileExt { + contentEncoding = encodingMap[patternExt] + break + } + } + } + metadata := map[string]*string{} vmap := a.vargs.Metadata.Map() if len(vmap) > 0 { @@ -108,15 +121,21 @@ func (a *AWS) Upload(local, remote string) error { return err } - debug("Uploading \"%s\" with Content-Type \"%s\" and permissions \"%s\"", local, contentType, access) - _, err = a.client.PutObject(&s3.PutObjectInput{ + debug("\"%s\" not found in bucket, uploading with Content-Type \"%s\" and permissions \"%s\"", local, contentType, access) + var putObject = &s3.PutObjectInput{ Bucket: aws.String(a.vargs.Bucket), Key: aws.String(remote), Body: file, ContentType: aws.String(contentType), ACL: aws.String(access), Metadata: metadata, - }) + } + + if(len(contentEncoding) > 0) { + putObject.ContentEncoding = aws.String(contentEncoding) + } + + _, err = a.client.PutObject(putObject) return err } @@ -137,6 +156,16 @@ func (a *AWS) Upload(local, remote string) error { shouldCopy = true } + if !shouldCopy && head.ContentEncoding == nil && contentEncoding != "" { + debug("Content-Encoding has changed from unset to %s", contentEncoding) + shouldCopy = true + } + + if !shouldCopy && head.ContentEncoding != nil && contentEncoding != *head.ContentEncoding { + debug("Content-Encoding has changed from %s to %s", *head.ContentEncoding, contentEncoding) + shouldCopy = true + } + if !shouldCopy && len(head.Metadata) != len(metadata) { debug("Count of metadata values has changed for %s", local) shouldCopy = true @@ -193,7 +222,7 @@ func (a *AWS) Upload(local, remote string) error { } debug("Updating metadata for \"%s\" Content-Type: \"%s\", ACL: \"%s\"", local, contentType, access) - _, err = a.client.CopyObject(&s3.CopyObjectInput{ + var copyObject = &s3.CopyObjectInput{ Bucket: aws.String(a.vargs.Bucket), Key: aws.String(remote), CopySource: aws.String(fmt.Sprintf("%s/%s", a.vargs.Bucket, remote)), @@ -201,7 +230,13 @@ func (a *AWS) Upload(local, remote string) error { ContentType: aws.String(contentType), Metadata: metadata, MetadataDirective: aws.String("REPLACE"), - }) + } + + if(len(contentEncoding) > 0) { + copyObject.ContentEncoding = aws.String(contentEncoding) + } + + _, err = a.client.CopyObject(copyObject) return err } else { _, err = file.Seek(0, 0) @@ -210,14 +245,20 @@ func (a *AWS) Upload(local, remote string) error { } debug("Uploading \"%s\" with Content-Type \"%s\" and permissions \"%s\"", local, contentType, access) - _, err = a.client.PutObject(&s3.PutObjectInput{ + var putObject = &s3.PutObjectInput{ Bucket: aws.String(a.vargs.Bucket), Key: aws.String(remote), Body: file, ContentType: aws.String(contentType), ACL: aws.String(access), Metadata: metadata, - }) + } + + if(len(contentEncoding) > 0){ + putObject.ContentEncoding = aws.String(contentEncoding) + } + + _, err = a.client.PutObject(putObject) return err } } diff --git a/types.go b/types.go index dde55dc..7f35f34 100644 --- a/types.go +++ b/types.go @@ -12,6 +12,7 @@ type PluginArgs struct { Delete bool `json:"delete"` Access StringMap `json:"acl"` ContentType StringMap `json:"content_type"` + ContentEncoding StringMap `json:"content_encoding"` Metadata DeepStringMap `json:"metadata"` Redirects map[string]string `json:"redirects"` CloudFrontDistribution string `json:"cloudfront_distribution_id"`