97

I have moved 20000 files to AWS S3 by s3cmd command. Now i want to add cache-control for all images (.jpg)

These files are located in ( s3://bucket-name/images/ ). How can i add cache-control for all images by s3cmd or is there any other way to add header ?

Thanks

Rajaraman
  • 1,637
  • 5
  • 19
  • 24

10 Answers10

94

Please try the current upstream master branch (https://github.com/s3tools/s3cmd), as it now has a modify command, used as follows:

./s3cmd --recursive modify --add-header="Cache-Control:max-age=86400" s3://yourbucket/
juanreyesv
  • 853
  • 9
  • 22
user3440362
  • 980
  • 6
  • 2
  • 5
    Hi, thanks for the reply , i tried this and i am getting error like ERROR: Invalid command: u'modify' – Rajaraman Mar 20 '14 at 05:53
  • @Rajaraman u know anything about it?? after this step its showing access denied – shajin Sep 18 '14 at 18:34
  • 2
    This works.. tested with s3cmd version 1.5.0-rc1 BUT!: this changes the object's Content-type header to "binary/octet-stream"! Tested with one PNG -file. – Hardy Oct 16 '14 at 13:27
  • 1
    I experienced the same problem as @Hardy. It also removed public readability from all my files. Watch out. – Andrew B. Nov 30 '14 at 20:10
  • @shajin, I had a similar error when using sync, and it worked after I cd into the source directory and use ./ rather than specifying the directory path. – Rene Wooller Dec 15 '15 at 05:02
  • Any news on this? @AndrewBadr – anothercoder Jan 26 '16 at 18:47
  • 1
    It appears the `Content-Type` bug was fixed with [#406](https://github.com/s3tools/s3cmd/pull/406). – josh3736 Mar 09 '16 at 20:04
  • Works well, just make sure you actually clone from github, in my case `apt-get` didn't work – Beowulfenator Aug 02 '16 at 19:01
  • Worked well with '*.jpeg' objects. Interestingly did not apply header to css,js,or svgs. s3cmd version 2.0.1 – bbeecher May 15 '19 at 18:41
  • Do these changes apply also for future uploads? for example, when you upload a file through the s3 API or just manually in the web console, to keep the Cache-Control set on the folder/bucket – Andrei F Oct 07 '20 at 10:16
77

Also with the AWS's own client:

aws s3 sync /path s3://yourbucket/ --cache-control max-age=604800
stan
  • 809
  • 9
  • 18
user31208
  • 1,448
  • 1
  • 18
  • 22
  • 2
    This works if you are uploading to AWS from a local path on your computer and want everything to keep proper cache-control – youanden Sep 23 '14 at 06:30
  • 25
    That works to set cache headers at time of initial sync but does not update existing files. You can force an update like so `find . -type f -exec touch '{}' \;; aws s3 sync /path s3://yourbucket/ --recursive --cache-control max-age=604800` – Matt Byrne Sep 24 '14 at 04:59
  • 3
    The OP is asking to update existing files in S3, not upload new files – Beowulfenator Aug 02 '16 at 18:55
  • 3
    Is the `--recursive` still necessary? The CLI documentation doesn't seem to list it as an argument. http://docs.aws.amazon.com/cli/latest/reference/s3/sync.html – Corey McMahon May 05 '17 at 15:04
  • 2
    @MattByrne The --recursive must be omitted since 1.7.12 https://github.com/aws/aws-cli/blob/develop/CHANGELOG.rst#1712 – Bernhardt Scherer Aug 22 '17 at 09:59
  • @boernard - noted and thanks for pointing this out to keep answer current for others looking at this. My answer was current when I made it in 2014, and that version was Feb 2015 ;-) – Matt Byrne Aug 22 '17 at 10:11
  • 1
    Using `touch '{}'` as mentioned above will change the file's modification date, which might be undesired. To set `cache-control` on existing files, see @rodrigo-silveira's answer below. – Fabien Snauwaert Aug 30 '17 at 18:52
  • The problem with this though is you may not want to set cache-control on *all* files in a sync (ex: if copying a static website to S3, you probably want a long cache control on imgs & CSS files, but not html or other content that may change frequently). – Adam Parkin Apr 22 '18 at 00:16
  • @AdamParkin Whilst that's true, it's beyond the scope of this question – Luke Nov 06 '22 at 19:30
42

My bucket has mp4, jpg, and other files. The files I wanted to update are stored in a "sub-bucket" (ex: https://s3.amazonaws.com/my.bucket/sub-directory/my-video.mp4). In my case I only wanted to update the cache control on mp4 files:

aws s3 cp \
   s3://my.bucket/sub-directory/ s3://my.bucket/sub-directory/ \
   --exclude '*.jpg' --exclude '*.png' \
   --cache-control 'max-age=31104000' \
   --recursive

To test out what this will do, you can use the --dryrun flag:

aws s3 cp --dryrun \
   s3://my.bucket/sub-directory/ s3://my.bucket/sub-directory/ \
   --exclude '*.jpg' --exclude '*.png' \
   --cache-control 'max-age=31104000' \
   --recursive
rodrigo-silveira
  • 12,607
  • 11
  • 69
  • 123
  • I get this error: "when calling the CopyObject operation: This copy request is illegal because it is trying to copy an object to itself without changing the object's metadata, storage class, website redirect location or encryption attributes." – Flimm Nov 24 '16 at 10:17
  • 9
    To fix it, I had to add `--metadata-directive REPLACE --acl public-read`. – Flimm Nov 24 '16 at 10:23
  • I originally used the metadata-directive to make this work but that ended up changing the content-type of the objects vs just adding `--acl public-read` – Matt Gaunt Jul 29 '20 at 04:06
27

To adjust metadata such as cache-control on an object in S3 without having to re-upload it and without having to use any third party tools, you can do the following with the AWS CLI. It copies the object to itself while overriding the metadata with your chosen settings:

aws s3api copy-object --copy-source <bucket-name>/<file> --bucket <bucket-name> --key <file> --metadata-directive REPLACE --cache-control "max-age=3600"

Process this command in a find to do it on an existing set of files that already exists in the bucket as you mention:

find . -type f -exec aws s3api copy-object --copy-source <bucket-name>/{} --bucket <bucket-name> --key {} --metadata-directive REPLACE --cache-control "max-age=3600"

replace <bucket-name> with the name of your bucket

WARNING: this will overwrite all your existing metadata on the files such as acl, just add additional flags to the command to set what you need, e.g., --acl public-read to give full public access. (thanks @jackson)

ErikE
  • 48,881
  • 23
  • 151
  • 196
Joel Duckworth
  • 5,455
  • 3
  • 20
  • 21
  • 7
    This did set my cache headers, although it removed the "public" permissions I had set on the files (rendering them unviewable on my s3-hosted site). To keep the files public, I had to run the command with `--acl public-read`. – Jackson Oct 19 '16 at 22:37
  • It also changed my content-type to binary/octet -- no bueno – Joe Love Feb 08 '23 at 22:21
19

If you want to avoid third party tools, and this is a one-time task, you can use the AWS console.

  1. Browse to your s3 bucket
  2. Select all of the objects you want to change
  3. Click Actions -> Change metadata
  4. Select Cache-Control for the key, input whatever control you want as the value
  5. Save
mattdedek
  • 2,525
  • 2
  • 17
  • 19
  • 3
    How can you make these changes for future uploads? for example, when you upload a file through the s3 API or just manually in the web console, to keep the Cache-Control set on the folder/bucket – Andrei F Oct 07 '20 at 10:15
5
PUT / ObjectName HTTP/1.1 
Host: BucketName .s3.amazonaws.com 
Date: date 
x-amz-meta-Cache-Control : max-age= <value in seconds> 
Authorization: signatureValue 

Every Metadata setting contains a Key-Value pair. Cache control metadata key is “Cache-Control” and Value is “max-age=<time for which you want your object to be accessed from cache in seconds>”

You can set Cache Control Custom Header for Amazon S3 Objects by sending HTTP PUT Request to Amazon S3 Server with appropriate headers in two ways:

Set Cache Control Metadata using Amazon S3 REST API PUT Object Request - If you are a programmer, you can write your own software program to use Amazon S3 REST or SOAP APIs to set Custom Headers with PUT Object Request. This website only refers to Amazon S3 REST APIs, please refer to AWS documentation website for details on how to use SOAP APIs. Set Cache Control Metadata using Bucket Explorer User Interface - If you like to set custom HTTP Headers like Cache Control using mouse clicks instead of writing a software program, you can use Bucket Explorer's user interface for that. With this Custom HTTP Header, you can specify the caching behavior that must be followed with the request/response chain and to prevent caches from interfering with the request or response.

for more information please check How to Set Cache Control Header for Amazon S3 Object?`

Laxmikant Ratnaparkhi
  • 4,745
  • 5
  • 33
  • 49
1

(Since the OP asked for any other way)

You can also do it via aws-cli, e.g. (v: aws-cli/1.8.8 Python/2.7.2 Darwin/12.5.0):

aws s3api put-object \
--bucket mybucket \
--key my/key \
--cache-control max-age=1 \
--body myfile.txt

Although please note that you will rewrite any existing object.

Jose Alban
  • 7,286
  • 2
  • 34
  • 19
1

This is honestly the best way atm without running into errors mentioned in the other answers:

aws s3 cp s3://my-bucket/ s3://my-bucket/ --recursive --metadata-directive REPLACE \
--expires 2034-01-01T00:00:00Z --acl public-read --cache-control max-age=2592000,public
Yoda
  • 79
  • 6
0

Just upgrade the s3cmd to version 1.5.1 and the issue will resolve.

0

Another really simple way to do this is to use S3 Browser: http://s3browser.com/ You can simply just shift click or ctrl+a to select all the images you want; then just go to the 'Http Headers' tab and click - 'Add new header' & then 'Apply changes'. It automatically kept all my other permissions and headers.

If you use S3 alot; its a sweet app anyways esp if you have enormous uploads (there's nothing better in the world of ftp, dropbox or otherwise!)

Reece
  • 641
  • 7
  • 18
  • 1
    why the downvotes? the OP said 's3cmd or is there any other way to add header' s3browser is great at bulk header editing; way better than AWS console web interface. – Reece Mar 22 '19 at 22:06
  • 1
    I didn't downvote you, but this is a bad idea because it's unmaintainable. You have to manually go do this every time somebody adds a new file (or try to train them to do it). A better solution would be "run this script to upload your files" and it always works correctly. No need for manual interventions and following steps. – Ryan Shillington May 15 '19 at 20:58
  • 2
    why do people bother to use gui (s)ftp clients like filezilla or cyberduck when there's the linux sftp command? Similarly bad idea? Theoretically you could script almost any software solution that theres an existing GUI solution. I'd like to think the what qualifies it as a good or bad idea is the context of use. I find s3 browser to be a useful tool, don't think it hurts to present it as an option. – Reece May 16 '19 at 00:00