From 50ea685cab7d7083d29137d75a99857e4f493839 Mon Sep 17 00:00:00 2001 From: Brian Foshee Date: Wed, 19 Oct 2016 13:56:28 -0400 Subject: [PATCH 1/2] Add support for CacheControl header --- DOCS.md | 13 ++++++++----- aws.go | 32 +++++++++++++++++++++++++++++++- main.go | 7 +++++++ plugin.go | 1 + 4 files changed, 47 insertions(+), 6 deletions(-) diff --git a/DOCS.md b/DOCS.md index ea5899f..a9b6944 100644 --- a/DOCS.md +++ b/DOCS.md @@ -10,6 +10,7 @@ Use the S3 sync plugin to synchronize files and folders with an Amazon 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 +* `cache_control` - override default cache control 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 @@ -30,7 +31,7 @@ publish: cloudfront_distribution_id: "9c5785d3ece6a9cdefa4" ``` -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. +The `acl`, `content_type`, `cache_control`, 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: @@ -45,6 +46,7 @@ publish: content_encoding: ".js": gzip ".css": gzip + cache_control: "public, max-age: 31536000" region: "us-east-1" bucket: "my-bucket.s3-website-us-east-1.amazonaws.com" access_key: "970d28f4dd477bc184fbd10b376de753" @@ -61,6 +63,9 @@ The `content_type` field the key is an extension including the leading dot `.`. 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. +In the `cache_control` field the key is an extension including the leading dot `.`. If you want to set cahce control for files with no extension, set the key +to th empty string `""`. If there are no matches for the `cache_control` of a file, no cache-control header will be added. + The `metadata` field can be set as either an object where the keys are the metadata headers: ```yaml @@ -75,7 +80,7 @@ publish: target: /target/location delete: true metadata: - Cache-Control: "max-age: 10000" + custom-meta: "abc123" ``` Or you can specify metadata for file patterns by using a glob: @@ -93,9 +98,7 @@ publish: delete: true metadata: "*.png": - Cache-Control: "max-age: 10000000" - "*.html": - Cache-Control: "max-age: 1000" + CustomMeta: "abc123" ``` Additionally, you can specify redirect targets for files that don't exist by using the `redirects` key: diff --git a/aws.go b/aws.go index 495e2df..1778849 100644 --- a/aws.go +++ b/aws.go @@ -52,7 +52,7 @@ func (a *AWS) Upload(local, remote string) error { defer file.Close() - access := "" + var access string for pattern := range p.Access { if match := glob.Glob(pattern, local); match == true { access = p.Access[pattern] @@ -86,6 +86,14 @@ func (a *AWS) Upload(local, remote string) error { } } + var cacheControl string + for pattern := range p.CacheControl { + if match := glob.Glob(pattern, local); match == true { + cacheControl = p.CacheControl[pattern] + break + } + } + metadata := map[string]*string{} for pattern := range p.Metadata { if match := glob.Glob(pattern, local); match == true { @@ -115,6 +123,10 @@ func (a *AWS) Upload(local, remote string) error { Metadata: metadata, } + if len(cacheControl) > 0 { + putObject.CacheControl = aws.String(cacheControl) + } + if len(contentEncoding) > 0 { putObject.ContentEncoding = aws.String(contentEncoding) } @@ -150,6 +162,16 @@ func (a *AWS) Upload(local, remote string) error { shouldCopy = true } + if !shouldCopy && head.CacheControl == nil && cacheControl != "" { + debug("Cache-Control has changed from unset to %s", cacheControl) + shouldCopy = true + } + + if !shouldCopy && head.CacheControl != nil && cacheControl != *head.CacheControl { + debug("Cache-Control has changed from %s to %s", *head.CacheControl, cacheControl) + shouldCopy = true + } + if !shouldCopy && len(head.Metadata) != len(metadata) { debug("Count of metadata values has changed for %s", local) shouldCopy = true @@ -216,6 +238,10 @@ func (a *AWS) Upload(local, remote string) error { MetadataDirective: aws.String("REPLACE"), } + if len(cacheControl) > 0 { + copyObject.CacheControl = aws.String(cacheControl) + } + if len(contentEncoding) > 0 { copyObject.ContentEncoding = aws.String(contentEncoding) } @@ -238,6 +264,10 @@ func (a *AWS) Upload(local, remote string) error { Metadata: metadata, } + if len(cacheControl) > 0 { + putObject.CacheControl = aws.String(cacheControl) + } + if len(contentEncoding) > 0 { putObject.ContentEncoding = aws.String(contentEncoding) } diff --git a/main.go b/main.go index 27a6bc9..4317007 100644 --- a/main.go +++ b/main.go @@ -74,6 +74,12 @@ func main() { EnvVar: "PLUGIN_CONTENT_ENCODING", Value: &StringMapFlag{}, }, + cli.GenericFlag{ + Name: "cache-control", + Usage: "cache-control settings for uploads", + EnvVar: "PLUGIN_CACHE_CONTROL", + Value: &StringMapFlag{}, + }, cli.GenericFlag{ Name: "metadata", Usage: "additional metadata for uploads", @@ -116,6 +122,7 @@ func run(c *cli.Context) error { Target: c.String("target"), Delete: c.Bool("delete"), Access: c.Generic("access").(*StringMapFlag).Get(), + CacheControl: c.Generic("cache-control").(*StringMapFlag).Get(), ContentType: c.Generic("content-type").(*StringMapFlag).Get(), ContentEncoding: c.Generic("content-encoding").(*StringMapFlag).Get(), Metadata: c.Generic("metadata").(*DeepStringMapFlag).Get(), diff --git a/plugin.go b/plugin.go index f2023f4..f66204a 100644 --- a/plugin.go +++ b/plugin.go @@ -17,6 +17,7 @@ type Plugin struct { Target string Delete bool Access map[string]string + CacheControl map[string]string ContentType map[string]string ContentEncoding map[string]string Metadata map[string]map[string]string From e07c6190e46fd9093deba811cd0a7af2207998c2 Mon Sep 17 00:00:00 2001 From: Brian Foshee Date: Wed, 19 Oct 2016 14:59:17 -0400 Subject: [PATCH 2/2] fix cache control docs typos --- DOCS.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/DOCS.md b/DOCS.md index a9b6944..03adacf 100644 --- a/DOCS.md +++ b/DOCS.md @@ -63,8 +63,8 @@ The `content_type` field the key is an extension including the leading dot `.`. 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. -In the `cache_control` field the key is an extension including the leading dot `.`. If you want to set cahce control for files with no extension, set the key -to th empty string `""`. If there are no matches for the `cache_control` of a file, no cache-control header will be added. +In the `cache_control` field the key is an extension including the leading dot `.`. If you want to set cache control for files with no extension, set the key +to the empty string `""`. If there are no matches for the `cache_control` of a file, no cache-control header will be added. The `metadata` field can be set as either an object where the keys are the metadata headers: