Aucun en-tête de contrôle de cache pour les fichiers d'AWS CloudFront avec S3 Origin

27

Nous venons de migrer vers Amazon AWS. Nous avons actuellement une instance EC2 qui fonctionne bien. Il exécute Nginx à l'avant et Apache à l'arrière. Ça marche bien aussi. Tous les sites sont lancés correctement et incluent l'en-tête Cache-Control pour les fichiers qui sont servis à partir de l'EC2.

Le problème est avec TOUS les fichiers statiques que nous avons placés dans Amazon S3 auxquels on accède via CloudFront CDN . Nous pouvons accéder aux fichiers correctement (et aucun problème avec CORS), mais apparemment CloudFront ne sert pas les fichiers avec l'en-tête Cache-Control. Nous voulons tirer parti de la mise en cache du navigateur.

De mon point de vue, l'instance EC2 ne joue aucun rôle ici car les fichiers statiques sont servis directement par S3 + CloudFront, la demande ne va pas au serveur Web dans EC2.

Je suis complètement perdu.

Question: 1) Comment définir le Cache-Control dans ce cas? 2) Est-il possible de définir le Cache-Control? Depuis S3 ou CloudFront?

Remarque: J'ai visité quelques pages dans Google où vous pouvez définir l'en-tête dans S3 pour des objets individuels. Ce n'est vraiment pas une façon productive de le faire spécialement car dans mon cas, nous parlons de plusieurs objets.

Merci!

jarvis
la source
Veuillez publier une URL pour un objet dans S3 et l'URL CloudFront applicable. J'aimerais voir le comportement que vous me décrivez. Poster alternativement des CURL pour les deux, montrant les en-têtes.
Tim
J'ai pu ajouter un en-tête personnalisé "Expire: dim, 15 oct 2027 13:46:07 GMT" en modifiant l'origine dans console.aws.amazon.com/cloudfront/home . Mais cela ne semble pas fonctionner. Comment as-tu finalement fait?
Manolo

Réponses:

31

J'ai visité quelques pages dans Google où vous pouvez définir l'en-tête dans S3 pour des objets individuels. Ce n'est vraiment pas une façon productive de le faire spécialement car dans mon cas, nous parlons de plusieurs objets.

Eh bien, "productif" ou non, c'est ainsi qu'il est conçu pour fonctionner.

CloudFront ne pas ajouter Cache-Control: les en- têtes.

CloudFront transmet (et respecte également, sauf configuration contraire) les en- Cache-Control:têtes fournis par le serveur d'origine, qui dans ce cas est S3.

Pour obtenir les en- Cache-Control:têtes fournis par S3 lorsqu'un objet est récupéré, ils doivent être fournis lorsque l'objet est téléchargé dans S3, ou ajoutés aux métadonnées de l'objet par une opération put + copy ultérieure, qui peut être utilisée pour copier en interne un objet en lui-même dans S3, modifiant les métadonnées dans le processus. C'est ce que fait la console, en arrière-plan, si vous modifiez des métadonnées d'objet.

Il n'y a également (au cas où vous vous poseriez la question) aucun paramètre global dans S3 pour forcer tous les objets d'un compartiment à renvoyer ces en-têtes - c'est un attribut par objet.


Mise à jour: Lambda @ Edge est une nouvelle fonctionnalité de CloudFront qui vous permet de déclencher des déclencheurs contre des demandes et / ou des réponses, entre le visualiseur et le cache et / ou le cache et l'origine, en exécutant du code écrit dans Node.js contre une structure d'objet de demande / réponse simple exposé par CloudFront.

L'une des principales applications de cette fonctionnalité est la manipulation des en-têtes ... donc, bien que ce qui précède soit toujours précis - CloudFront lui-même n'ajoute pas Cache-Control- il est désormais possible pour une fonction Lambda de les ajouter à la réponse renvoyée par CloudFront.

Cet exemple Cache-Control: public, max-age=86400n'est ajouté que si aucun en- Cache-Controltête n'est déjà présent sur la réponse.

L'utilisation de ce code dans un déclencheur de réponse d'origine entraînerait son déclenchement à chaque fois que CloudFront récupère un objet à partir de l'origine et modifiait la réponse avant que CloudFront ne le mette en cache.

'use strict';

exports.handler = (event, context, callback) => {
    const response = event.Records[0].cf.response;

    if(!response.headers['cache-control'])
    {
        response.headers['cache-control'] = [{ 
            key:   'Cache-Control', 
            value: 'public, max-age=86400' 
        }];
    }

    callback(null, response);
};

Mise à jour (2018-06-20): Récemment, j'ai soumis une demande de fonctionnalité à l'équipe CloudFront pour permettre la configuration des en- têtes de réponse d' origine statiques en tant qu'attributs d'origine, similaire à la façon dont les en- têtes de demande statiques peuvent être ajoutés, maintenant ... mais avec un twist, permettant à chaque en-tête d'être configuré pour être ajouté de manière conditionnelle (uniquement si l'origine n'a pas fourni cet en-tête dans la réponse) ou inconditionnellement (en ajoutant l'en-tête et en écrasant l'en-tête à partir de l'origine, le cas échéant).

Avec les demandes de fonctionnalités, vous ne recevez généralement aucune confirmation si elles envisagent réellement d'implémenter la nouvelle fonctionnalité ... ou même si elles ont peut-être déjà travaillé dessus ... c'est juste annoncé lorsqu'elles sont terminées. Donc, je n'ai aucune idée si ceux-ci seront mis en œuvre. Il y a un argument à faire valoir que puisque cette capacité est déjà disponible via Lambda @ Edge, elle n'est pas nécessaire dans la fonctionnalité de base ... mais mon contre-argument est que la base n'est fonctionnellement pas complète sans la possibilité de faire une manipulation d'en-tête de réponse simple et statique, et que si c'est la seule raison pour laquelle un déclencheur est nécessaire, alors exiger des déclencheurs Lambda est un coût inutile, financièrement et avec une latence supplémentaire (même si aucun n'est nécessairement un coût bizarre).

Michael - sqlbot
la source
C'est quand même ennuyeux.
Erica Kane
1
Tada, en effet, @Kunal. C'est un exemple de ce que j'ai appelé dans la réponse "ajouté aux métadonnées de l'objet par une opération put + copy". Utilisez-le avec prudence et testez, car il y a des mises en garde. Il réinitialisera tous vos horodatages et peut avoir des implications pour le chiffrement. Il peut également faire passer les étiquettes d'objets de plusieurs parties à un format de pièce unique, qui est un algorithme différent, et confondra tout système qui a stocké les étiquettes ailleurs pour de futures vérifications d'intégrité. Si le contrôle de version est activé sur le compartiment, votre coût de stockage double, sauf si vous nettoyez les anciennes versions.
Michael - sqlbot
1
Le nouveau service Lambda @ Edge fournit désormais également un mécanisme qui permet d'ajouter des en-têtes de réponse Cache-Control (entre autres) à la volée. J'ai mis à jour la réponse avec un exemple pratique de la façon dont cela peut être fait.
Michael - sqlbot
1
@Broshi, la "politique de confiance" du rôle doit répertorier les services lambda et edgelambda. Jetez un œil à docs.aws.amazon.com/lambda/latest/dg/… .
Michael - sqlbot