Lukas
4 Minuten

Was selbstverständlich erscheint und in klassischen AWS S3-Buckets auch wunderbar funktioniert, ist die Sache mit den Pretty URLs, genauer gesagt den Standardstammobjekten.

Diese müssen in AWS CloudFront nämlich explizit gesetzt werden, denn es findet keine automatische Weiterleitung statt. Das klingt komplizierter, als es eigentlich ist.

Weiterleitungsverhalten eines klassischen AWS S3-Buckets

Ein klassischer AWS S3-Bucket leitet Anfragen für ein Unterverzeichnis automatisch an das Standardstammobjekt, das heißt, dass eine Anfrage an http://example.com/subdirectory automatisch die Index-Datei http://example.com/subdirectoy/index.html zurückgibt.

Weiterleitungsverhalten in einer AWS CloudFront-Distribution

In CloudFront findet diese automatische Weiterleitung nicht statt, es lässt sich lediglich ein Standardstammobjekt für das Hauptverzeichnis anlegen. So leitet zwar http://example.com korrekt zu http://example.com/index.html weiter, in Unterverzeichnissen findet diese Weiterleitung aber nicht statt.

Aber ich will Pretty URLs!!!

Damit die Pretty URLs dennoch funktionieren, wird eine Lambda@Edge-Funktion benötigt. Diese Funktion wird als Reaktion auf jede Ursprungsanfrage an CloudFront ausgeführt, bevor CloudFront das Objekt vom AWS S3-Ursprung anfordert und ändert alle Anfragen, die mit einem Trailing-Slash enden in die gewünschten /index.html-Endungen.

Als Erstes wird eine AWS Lambda@Edge-Funktion ohne Vorgabe erstellt. Wichtig ist, dass dieser Funktion eine Rolle zugeordnet wird, die die Richtlinienvorlage "Grundlegende Lambda@Edge-Berechtigungen (für CloudFront-Auslöser)" enthält.

Nachdem die Funktion erstellt wurde, wird als Erstes die Region auf "US East (N. Virginia) umgestellt, denn der benötigte CloudFront-Auslöser ist nur in dieser Region verfügbar.

Als Nächstes wird folgender Code eingefügt:

'use strict';

const pointsToFile = uri => /\/[^/]+\.[^/]+$/.test(uri);

exports.handler = (event, context, callback) => {

    // Extract the request from the CloudFront event that is sent to Lambda@Edge
    var request = event.Records[0].cf.request;

    // Extract the URI from the request
    var oldUri = request.uri;
    var newUri;

    if (!pointsToFile(oldUri) && !oldUri.endsWith('/')) {
      const newUri = request.querystring ? `${oldUri}/?${request.querystring}` : `${oldUri}/`;
      return callback(null, {
        body: '',
        status: '301',
        statusDescription: 'Moved Permanently',
        headers: {
          location: [{
            key: 'Location',
            value: newUri,
          }],
        }
      });
    } else {
      newUri = oldUri;
    }

    // Match any '/' that occurs at the end of a URI. Replace it with a default index
    newUri = newUri.replace(/\/$/, '\/index.html');

    // Log the URI as received by CloudFront and the new URI to be used to fetch from origin
    console.log("Old URI: " + oldUri);
    console.log("New URI: " + newUri);

    // Replace the received URI with the URI that includes the index page
    request.uri = newUri;

    // Return to CloudFront
    return callback(null, request);

};

Jetzt wird der Funktion als letzter Schritt noch der CloudFrontAuslöser hinzugefügt. Hierfür wird die ID der CloudFront-Distribution benötigt, damit die Funktion der CloudFront-Distribution zugeordnet wird. Nach einigen Minuten ist der Veröffentlichungsprozess abgeschlossen und die Pretty URLs funktionieren auch in CloudFront.

Kaffeekasse

Der Artikel hat Dir weitergeholfen?

Der Artikel hat Dir weitergeholfen? Sehr schön, so soll es sein! Wenn Dir unsere Snippets weiterhelfen, supporte uns auf Steady.com.

Supporte uns auf Steady.com