Compression de réponse dans ASP.NET Core

La bande passante réseau est une ressource limitée. La réduction de la taille de la réponse augmente généralement la réactivité d’une application, souvent de façon spectaculaire. L’un des moyens de réduire les tailles de charge utile consiste à compresser les réponses d’une application.

Compression avec HTTPS

Les réponses compressées sur des connexions sécurisées peuvent être contrôlées avec l’option EnableForHttps, qui est désactivée par défaut en raison du risque de sécurité. L’utilisation de la compression avec des pages générées dynamiquement peut exposer l’application aux attaques CRIME et BREACH. Les attaques CRIMEet BREACH peuvent être atténuées dans ASP.NET Core avec des jetons anti-contrefaçon. Pour plus d’informations, consultez Prévenir les attaques par falsification de requête intersites (XSRF/CSRF) dans ASP.NET Core. Pour plus d’informations sur l’atténuation des attaques BREACH, consultez Atténuations à l’adresse http://www.breachattack.com/

Même quand EnableForHttps est désactivé dans l’application, IIS, IIS Express et Azure App Service peuvent appliquer gzip sur le serveur web IIS. Lorsque vous examinez les en-têtes de réponse, notez la valeur Serveur. Une valeur d’en-tête de réponse inattendue content-encoding peut être en résultat du serveur web et non de la configuration de l’application ASP.NET Core.

Quand utiliser un intergiciel de compression de réponse

Utilisez les technologies de compression de réponse basées sur serveur dans IIS, Apache ou Nginx. Les performances de l’intergiciel de compression de réponse ne correspondront probablement pas à celles des modules serveur. Le serveur HTTP.sys et le serveur Kestrel n’offrent actuellement pas la prise en charge intégrée de la compression.

Utilisez l’intergiciel de compression de réponse lorsque l’application :

Compression des réponses

En règle générale, toute réponse non compressée en mode natif peut tirer parti de la compression de réponse. Les réponses non compressées en mode natif incluent généralement CSS, JavaScript, HTML, XML et JSON. Ne compressez pas les ressources compressées en mode natif, comme les fichiers PNG. Lorsque vous tentez de compresser davantage une réponse compressée en mode natif, toute petite réduction supplémentaire de la taille et du temps de transmission sera probablement éclipsée par le temps passé à traiter la compression. Ne compressez pas les fichiers à des tailles inférieures à environ 150 à 1000 octets, en fonction du contenu du fichier et de l’efficacité de la compression. La surcharge liée à la compression de petits fichiers peut produire un fichier compressé plus volumineux que le fichier non compressé.

Lorsqu’un client peut traiter du contenu compressé, il doit informer le serveur de ses capacités en envoyant l’en-tête Accept-Encoding avec la requête. Lorsqu’un serveur envoie du contenu compressé, il doit inclure des informations dans l’en-tête Content-Encoding sur la façon dont la réponse compressée est encodée. Les désignations d’encodage de contenu prises en charge par l’intergiciel de compression de réponse sont indiquées dans le tableau suivant.

Valeurs d’en-tête Accept-Encoding Intergiciel pris en charge Description
br Oui (valeur par défaut) Format de données compressées Brotli
deflate Non Format de données compressées DEFLATE
exi Non Échange XML efficace W3C
gzip Oui Format de fichier Gzip
identity Oui Identificateur « Aucun encodage » : la réponse ne doit pas être encodée.
pack200-gzip Non Format de transfert réseau pour les archives Java
* Oui Tout encodage de contenu disponible non explicitement demandé

Pour plus d’informations, consultez la liste de codage de contenu officielle de l’IANA.

L’intergiciel de compression de réponse permet d’ajouter des fournisseurs de compression supplémentaires pour les valeurs d’en-tête Accept-Encoding personnalisées. Pour plus d’informations, consultez Fournisseurs personnalisés dans cet article.

L’intergiciel de compression de réponse est capable de réagir à la pondération de la valeur de qualité (qvalue, q) lors de l’envoi par le client pour hiérarchiser les schémas de compression. Pour plus d’informations, consultez RFC 9110 : Accept-Encoding.

Les algorithmes de compression doivent trouver un équilibre entre la vitesse de la compression et l’efficacité de la compression. L’efficacité dans ce contexte fait référence à la taille de la sortie après compression. La plus petite taille est obtenue par la compression optimale.

Les en-têtes impliqués dans la requête, l’envoi, la mise en cache et la réception de contenu compressé sont décrits dans le tableau suivant.

En-tête Role
Accept-Encoding Envoyé du client au serveur pour indiquer les schémas d’encodage de contenu acceptables pour le client.
Content-Encoding Envoyé du serveur au client pour indiquer l’encodage du contenu dans la charge utile.
Content-Length Lorsque la compression se produit, l’en-tête Content-Length est supprimé, car le contenu du corps change lorsque la réponse est compressée.
Content-MD5 Lorsque la compression se produit, l’en-tête Content-MD5 est supprimé, car le contenu du corps a changé et le hachage n’est plus valide.
Content-Type Spécifie le type MIME du contenu. Chaque réponse doit spécifier son Content-Type. L’intergiciel de compression de réponse vérifie cette valeur pour déterminer si la réponse doit être compressée. L’intergiciel de compression de réponse spécifie un ensemble de types MIME par défaut qu’il peut encoder, et ils peuvent être remplacés ou complétés.
Vary Lorsqu’il est envoyé par le serveur avec une valeur de Accept-Encoding aux clients et aux proxys, l’en-tête Vary indique au client ou au proxy qu’il doit mettre en cache (varier) les réponses en fonction de la valeur de l’en-tête Accept-Encoding de la requête. Le résultat du retour du contenu avec l’en-tête Vary: Accept-Encoding est que les réponses compressées et non compressées sont mises en cache séparément.

Explorez les fonctionnalités de l’intergiciel de compression de réponse avec cet exemple d’application. L’exemple illustre :

  • La compression des réponses d’application à l’aide de Gzip et de fournisseurs de compression personnalisés.
  • Comment ajouter un type MIME à la liste par défaut des types MIME pour la compression.
  • Comment ajouter un fournisseur de compression de réponse personnalisé.

Configuration

Le code suivant montre comment activer l’intergiciel de compression de réponse pour les types MIME et les fournisseurs de compression par défaut (Brotli et Gzip) :

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddResponseCompression(options =>
{
    options.EnableForHttps = true;
});

var app = builder.Build();

app.UseResponseCompression();

app.MapGet("/", () => "Hello World!");

app.Run();

Remarques :

Envoyez une requête à l’exemple d’application sans l’en-tête Accept-Encoding et observez que la réponse n’est pas compressée. L’en-tête Content-Encoding ne figure pas dans la collection En-têtes de réponse.

Par exemple, dans Firefox Developer :

  • Sélectionnez l’onglet Réseau.
  • Cliquez avec le bouton droit sur la requête dans la liste Requête réseau , puis sélectionnez Modifier et renvoyer
  • Changez la valeur Accept-Encoding: en remplaçant gzip, deflate, br par none.
  • Sélectionnez Envoyer.

Envoyez une requête à l’exemple d’application avec un navigateur à l’aide des outils de développement et observez que la réponse est compressée. Les en-têtes Content-Encoding et Vary sont présents dans la réponse.

Fournisseurs

Fournisseurs de compression Brotli et Gzip

Utilisez le BrotliCompressionProvider pour compresser les réponses avec le format de données compressées Brotli.

Si aucun fournisseur de compression n’est explicitement ajouté au CompressionProviderCollection :

  • Le fournisseur de compression Brotli et le fournisseur de compression Gzip sont ajoutés par défaut au groupe des fournisseurs de compression.
  • La compression par défaut est la compression Brotli lorsque le format de données compressée Brotli est pris en charge par le client. Si Brotli n’est pas pris en charge par le client, la compression par défaut devient Gzip lorsque le client prend en charge la compression Gzip.

Notes

Les liens de documentation vers la source de référence .NET chargent généralement la branche par défaut du référentiel, qui représente le développement actuel pour la prochaine version de .NET. Pour sélectionner une balise pour une version spécifique, utilisez la liste déroulante Échanger les branches ou les balises. Pour plus d’informations, consultez Comment sélectionner une balise de version du code source ASP.NET Core (dotnet/AspNetCore.Docs #26205).

Lorsqu’un fournisseur de compression est ajouté, les autres fournisseurs ne le sont pas. Par exemple, si le fournisseur de compression Gzip est le seul fournisseur explicitement ajouté, aucun autre fournisseur de compression n’est ajouté.

Le code suivant :

  • Active la compression de réponse pour les requêtes HTTPS.
  • Ajoute les fournisseurs de compression de réponse Brotli et Gzip.
using System.IO.Compression;
using Microsoft.AspNetCore.ResponseCompression;

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddResponseCompression(options =>
{
    options.EnableForHttps = true;
    options.Providers.Add<BrotliCompressionProvider>();
    options.Providers.Add<GzipCompressionProvider>();
});

builder.Services.Configure<BrotliCompressionProviderOptions>(options =>
{
    options.Level = CompressionLevel.Fastest;
});

builder.Services.Configure<GzipCompressionProviderOptions>(options =>
{
    options.Level = CompressionLevel.SmallestSize;
});

var app = builder.Build();

app.UseResponseCompression();

app.MapGet("/", () => "Hello World!");

app.Run();

Définir le niveau de compression avec BrotliCompressionProviderOptions et GzipCompressionProviderOptions. Les fournisseurs de compression Brotli et Gzip ont par défaut le niveau de compression le plus rapide, CompressionLevel.Fastest, ce qui peut ne pas produire la compression la plus efficace. Si vous souhaitez la compression la plus efficace, configurez l’intergiciel de compression de réponse pour une compression optimale.

Consultez CompressionLevel, énumération pour connaître les valeurs qui indiquent si une opération de compression privilégie la vitesse ou la taille de la compression.

using System.IO.Compression;
using Microsoft.AspNetCore.ResponseCompression;

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddResponseCompression(options =>
{
    options.EnableForHttps = true;
    options.Providers.Add<BrotliCompressionProvider>();
    options.Providers.Add<GzipCompressionProvider>();
});

builder.Services.Configure<BrotliCompressionProviderOptions>(options =>
{
    options.Level = CompressionLevel.Fastest;
});

builder.Services.Configure<GzipCompressionProviderOptions>(options =>
{
    options.Level = CompressionLevel.SmallestSize;
});

var app = builder.Build();

app.UseResponseCompression();

app.MapGet("/", () => "Hello World!");

app.Run();

Fournisseurs personnalisés

Créer des implémentations de compression personnalisées avec ICompressionProvider. Le EncodingName représente l’encodage de contenu que ce ICompressionProvider produit. L’intergiciel de compression de réponse utilise ces informations pour choisir le fournisseur en fonction de la liste spécifiée dans l’en-tête Accept-Encoding de la requête.

Les requêtés adressées à l’exemple d’application avec l’en-tête Accept-Encoding: mycustomcompression retournent une réponse avec un en-tête Content-Encoding: mycustomcompression. Le client doit pouvoir décompresser l’encodage personnalisé pour qu’une implémentation de compression personnalisée fonctionne.

using Microsoft.AspNetCore.ResponseCompression;

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddResponseCompression(options =>
{
    options.Providers.Add<BrotliCompressionProvider>();
    options.Providers.Add<GzipCompressionProvider>();
    options.Providers.Add<CustomCompressionProvider>();
});

var app = builder.Build();

app.UseResponseCompression();

app.MapGet("/", () => "Hello World!");

app.Run();
using Microsoft.AspNetCore.ResponseCompression;

public class CustomCompressionProvider : ICompressionProvider
{
    public string EncodingName => "mycustomcompression";
    public bool SupportsFlush => true;

    public Stream CreateStream(Stream outputStream)
    {
        // Replace with a custom compression stream wrapper.
        return outputStream;
    }
}

Avec le code précédent, le corps de la réponse n’est pas compressé par l’exemple. Toutefois, l’exemple montre où implémenter un algorithme de compression personnalisé.

types MIME

L’intergiciel de compression de réponse spécifie un ensemble par défaut de types MIME pour la compression. Consultez le code source pour obtenir la liste complète des types MIME pris en charge.

Notes

Les liens de documentation vers la source de référence .NET chargent généralement la branche par défaut du référentiel, qui représente le développement actuel pour la prochaine version de .NET. Pour sélectionner une balise pour une version spécifique, utilisez la liste déroulante Échanger les branches ou les balises. Pour plus d’informations, consultez Comment sélectionner une balise de version du code source ASP.NET Core (dotnet/AspNetCore.Docs #26205).

Remplacez ou complétez les types MIME avec ResponseCompressionOptions.MimeTypes. Notez que les types MIME génériques, tels que text/* ne sont pas pris en charge. L’exemple d’application ajoute un type MIME pour image/svg+xml et compresse et sert l’image de bannière ASP.NET Core banner.svg.

using Microsoft.AspNetCore.ResponseCompression;
using ResponseCompressionSample;

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddResponseCompression(options =>
{
    options.EnableForHttps = true;
    options.Providers.Add<BrotliCompressionProvider>();
    options.Providers.Add<GzipCompressionProvider>();
    options.Providers.Add<CustomCompressionProvider>();
    options.MimeTypes =
    ResponseCompressionDefaults.MimeTypes.Concat(
        new[] { "image/svg+xml" });
});

var app = builder.Build();

app.UseResponseCompression();

Ajouter l’en-tête Vary

Lors de la compression des réponses en fonction de l’Accept-Encodingen-tête de la requête, il peut exister des versions non compressées et plusieurs versions compressées de la réponse. Pour indiquer aux caches client et proxy que plusieurs versions existent et doivent être stockées, l’en-tête Vary est ajouté avec une valeur Accept-Encoding. L’intergiciel de réponse ajoute automatiquement l’en-tête Vary lorsque la réponse est compressée.

Notes

Les liens de documentation vers la source de référence .NET chargent généralement la branche par défaut du référentiel, qui représente le développement actuel pour la prochaine version de .NET. Pour sélectionner une balise pour une version spécifique, utilisez la liste déroulante Échanger les branches ou les balises. Pour plus d’informations, consultez Comment sélectionner une balise de version du code source ASP.NET Core (dotnet/AspNetCore.Docs #26205).

Problème d’intergiciel derrière un proxy inverse Nginx

Lorsqu’une requête est proxiée par Nginx, l’en-tête Accept-Encoding est supprimé. La suppression de l’en-tête Accept-Encoding empêche l’intergiciel de compression de réponse de compresser la réponse. Pour plus d’informations, consultez NGINX : Compression et décompression. Ce problème est suivi par Comprendre la compression pass-through pour Nginx (dotnet/aspnetcore#5989).

Désactiver la compression dynamique IIS

Pour désactiver le module de compression dynamique IIS configuré au niveau du serveur, consultez Désactiver des modules IIS.

Résoudre les problèmes de compression de réponse

Utilisez un outil comme Firefox Browser Developer, qui permet de définir l’en-tête de requête Accept-Encoding et d’examiner les en-têtes, la taille et le corps de la réponse. Par défaut, l’intergiciel de compression de réponse compresse les réponses qui répondent aux conditions suivantes :

  • L’en-tête Accept-Encoding est présent avec la valeur br, gzip, *ou l’encodage personnalisé qui correspond à un fournisseur de compression personnalisé. La valeur ne doit pas être identity ou avoir un paramètre de valeur de qualité (qvalue, q) de 0 (zéro).
  • Le type MIME (Content-Type) doit être défini et doit correspondre à un type MIME configuré sur le ResponseCompressionOptions.
  • La requête ne doit pas inclure l’en-tête Content-Range.
  • La requête doit utiliser un protocole non sécurisé (http), sauf si le protocole sécurisé (https) est configuré dans les options d’intergiciel de compression de réponse. Notez le danger décrit ci-dessus lors de l’activation de la compression de contenu sécurisée.

Exemple déployé sur Azure

L’exemple d’application déployé sur Azure contient le fichier Program.cs suivant :

using Microsoft.AspNetCore.ResponseCompression;
using ResponseCompressionSample;

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddResponseCompression(options =>
{
    options.EnableForHttps = true;
    options.Providers.Add<BrotliCompressionProvider>();
    options.Providers.Add<GzipCompressionProvider>();
    options.Providers.Add<CustomCompressionProvider>();
    options.MimeTypes =
    ResponseCompressionDefaults.MimeTypes.Concat(
        new[] { "image/svg+xml" });
});

var app = builder.Build();

app.UseResponseCompression();

app.Map("/trickle", async (HttpResponse httpResponse) =>
{
    httpResponse.ContentType = "text/plain;charset=utf-8";

    for (int i = 0; i < 20; i++)
    {
        await httpResponse.WriteAsync("a");
        await httpResponse.Body.FlushAsync();
        await Task.Delay(TimeSpan.FromMilliseconds(50));
    }
});

app.Map("/testfile1kb.txt", () => Results.File(
    app.Environment.ContentRootFileProvider.GetFileInfo("testfile1kb.txt").PhysicalPath,
    "text/plain;charset=utf-8"));

app.Map("/banner.svg", () => Results.File(
    app.Environment.ContentRootFileProvider.GetFileInfo("banner.svg").PhysicalPath,
    "image/svg+xml;charset=utf-8"));

app.MapFallback(() => LoremIpsum.Text);

app.Run();

Ressources supplémentaires

Notes

Les liens de documentation vers la source de référence .NET chargent généralement la branche par défaut du référentiel, qui représente le développement actuel pour la prochaine version de .NET. Pour sélectionner une balise pour une version spécifique, utilisez la liste déroulante Échanger les branches ou les balises. Pour plus d’informations, consultez Comment sélectionner une balise de version du code source ASP.NET Core (dotnet/AspNetCore.Docs #26205).

La bande passante réseau est une ressource limitée. La réduction de la taille de la réponse augmente généralement la réactivité d’une application, souvent de façon spectaculaire. L’un des moyens de réduire les tailles de charge utile consiste à compresser les réponses d’une application.

Affichez ou téléchargez l’exemple de code (procédure de téléchargement)

Quand utiliser un intergiciel de compression de réponse

Utiliser les technologies de compression de réponse basées sur serveur dans IIS, Apache ou Nginx. Les performances de l’intergiciel ne correspondront probablement pas à celles des modules serveur. Le serveur HTTP.sys et le serveur Kestrel n’offrent actuellement pas la prise en charge intégrée de la compression.

Utilisez l’intergiciel de compression de réponse lorsque vous :

Compression des réponses

En règle générale, toute réponse non compressée en mode natif peut tirer parti de la compression de réponse. Les réponses non compressées en mode natif incluent généralement : CSS, JavaScript, HTML, XML et JSON. Vous ne devez pas compresser pas les ressources compressées en mode natif, comme les fichiers PNG. Si vous essayez de compresser davantage une réponse compressée en mode natif, toute petite réduction supplémentaire de la taille et du temps de transmission sera probablement éclipsée par le temps pris pour traiter la compression. Ne compressez pas les fichiers à des tailles inférieures à environ 150 à 1000 octets (en fonction du contenu du fichier et de l’efficacité de la compression). La surcharge liée à la compression de petits fichiers peut produire un fichier compressé plus volumineux que le fichier non compressé.

Lorsqu’un client peut traiter du contenu compressé, il doit informer le serveur de ses capacités en envoyant l’en-tête Accept-Encoding avec la requête. Lorsqu’un serveur envoie du contenu compressé, il doit inclure des informations dans l’en-tête Content-Encoding sur la façon dont la réponse compressée est encodée. Les désignations d’encodage de contenu prises en charge par l’intergiciel sont indiquées dans le tableau suivant.

Valeurs d’en-tête Accept-Encoding Intergiciel pris en charge Description
br Oui (valeur par défaut) Format de données compressées Brotli
deflate Non Format de données compressées DEFLATE
exi Non Échange XML efficace W3C
gzip Oui Format de fichier Gzip
identity Oui Identificateur « Aucun encodage » : la réponse ne doit pas être encodée.
pack200-gzip Non Format de transfert réseau pour les archives Java
* Oui Tout encodage de contenu disponible non explicitement demandé

Pour plus d’informations, consultez la liste de codage de contenu officielle de l’IANA.

L’intergiciel vous permet d’ajouter des fournisseurs de compression supplémentaires pour les valeurs d’en-tête Accept-Encoding personnalisées. Pour plus d’informations, consultez Fournisseurs personnalisés ci-dessous.

L’intergiciel est capable de réagir à la pondération de la valeur de qualité (qvalue, q) lors de l’envoi par le client pour hiérarchiser les schémas de compression. Pour plus d’informations, consultez RFC 9110 : Accept-Encoding.

Les algorithmes de compression doivent trouver un équilibre entre la vitesse de la compression et l’efficacité de la compression. L’efficacité dans ce contexte fait référence à la taille de la sortie après compression. La plus petite taille est obtenue par la compression optimale.

Les en-têtes impliqués dans la requête, l’envoi, la mise en cache et la réception de contenu compressé sont décrits dans le tableau ci-dessous.

En-tête Role
Accept-Encoding Envoyé du client au serveur pour indiquer les schémas d’encodage de contenu acceptables pour le client.
Content-Encoding Envoyé du serveur au client pour indiquer l’encodage du contenu dans la charge utile.
Content-Length Lorsque la compression se produit, l’en-tête Content-Length est supprimé, car le contenu du corps change lorsque la réponse est compressée.
Content-MD5 Lorsque la compression se produit, l’en-tête Content-MD5 est supprimé, car le contenu du corps a changé et le hachage n’est plus valide.
Content-Type Spécifie le type MIME du contenu. Chaque réponse doit spécifier son Content-Type. L’intergiciel vérifie cette valeur pour déterminer si la réponse doit être compressée. L’intergiciel spécifie un ensemble de types MIME par défaut qu’il peut encoder, mais vous pouvez remplacer ou ajouter des types MIME.
Vary Lorsqu’il est envoyé par le serveur avec une valeur de Accept-Encoding aux clients et aux proxys, l’en-tête Vary indique au client ou au proxy qu’il doit mettre en cache (varier) les réponses en fonction de la valeur de l’en-tête Accept-Encoding de la requête. Le résultat du retour du contenu avec l’en-tête Vary: Accept-Encoding est que les réponses compressées et non compressées sont mises en cache séparément.

Explorez les fonctionnalités de l’intergiciel de compression de réponse avec cet exemple d’application. L’exemple illustre :

  • La compression des réponses d’application à l’aide de Gzip et de fournisseurs de compression personnalisés.
  • Comment ajouter un type MIME à la liste par défaut des types MIME pour la compression.

Configuration

Le code suivant montre comment activer l’intergiciel de compression de réponse pour les types MIME et les fournisseurs de compression par défaut (Brotli et Gzip) :

public class Startup
{
    public void ConfigureServices(IServiceCollection services)
    {
        services.AddResponseCompression();
    }

    public void Configure(IApplicationBuilder app, IHostingEnvironment env)
    {
        app.UseResponseCompression();
    }
}

Remarques :

  • app.UseResponseCompression doit être appelé avant tout intergiciel qui compresse les réponses. Pour plus d’informations, consultez Intergiciel (middleware) ASP.NET Core.
  • Utilisez un outil comme Fiddler ou Firefox Browser Developer pour définir l’en-tête de requête Accept-Encoding et examiner les en-têtes, la taille et le corps de la réponse.

Envoyez une requête à l’exemple d’application sans l’en-tête Accept-Encoding et observez que la réponse n’est pas compressée. Les en-têtes Content-Encoding et Vary ne sont pas présents dans la réponse.

Fiddler window showing result of a request without the Accept-Encoding header. The response isn't compressed.

Envoyez une requête à l’exemple d’application avec l’en-tête Accept-Encoding: br (compression Brotli) et observez que la réponse est compressée. Les en-têtes Content-Encoding et Vary sont présents dans la réponse.

Fiddler window showing result of a request with the Accept-Encoding header and a value of br. The Vary and Content-Encoding headers are added to the response. The response is compressed.

Fournisseurs

Fournisseur de compression Brotli

Utilisez le BrotliCompressionProvider pour compresser les réponses avec le format de données compressées Brotli.

Si aucun fournisseur de compression n’est explicitement ajouté au CompressionProviderCollection :

  • Le fournisseur de compression Brotli est ajouté par défaut au groupe des fournisseurs de compression, ainsi que le fournisseur de compression Gzip.
  • La compression par défaut est la compression Brotli lorsque le format de données compressée Brotli est pris en charge par le client. Si Brotli n’est pas pris en charge par le client, la compression par défaut devient Gzip lorsque le client prend en charge la compression Gzip.
public void ConfigureServices(IServiceCollection services)
{
    services.AddResponseCompression();
}

Le fournisseur de compression Brotli doit être ajouté lorsque des fournisseurs de compression sont explicitement ajoutés :

public void ConfigureServices(IServiceCollection services)
{
    services.AddResponseCompression(options =>
    {
        options.Providers.Add<BrotliCompressionProvider>();
        options.Providers.Add<GzipCompressionProvider>();
        options.Providers.Add<CustomCompressionProvider>();
        options.MimeTypes = 
            ResponseCompressionDefaults.MimeTypes.Concat(
                new[] { "image/svg+xml" });
    });
}

Définir le niveau de compression avec BrotliCompressionProviderOptions. Le fournisseur de compression Brotli a par défaut le niveau de compression le plus rapide, (CompressionLevel.Fastest), ce qui peut ne pas produire la compression la plus efficace. Si vous souhaitez la compression la plus efficace, configurez l’intergiciel pour une compression optimale.

Niveau de compression Description
CompressionLevel.Fastest La compression doit s'exécuter aussi rapidement que possible, même si la sortie résultante n'est pas compressée de manière optimale.
CompressionLevel.NoCompression Aucune compression ne doit être effectuée.
CompressionLevel.Optimal Les réponses doivent être compressées de manière optimale, même si la compression prend plus de temps.
public void ConfigureServices(IServiceCollection services)
{
    services.AddResponseCompression();

    services.Configure<BrotliCompressionProviderOptions>(options => 
    {
        options.Level = CompressionLevel.Fastest;
    });
}

Fournisseur de compression Gzip

Utilisez le GzipCompressionProvider pour compresser les réponses au format de fichier Gzip.

Si aucun fournisseur de compression n’est explicitement ajouté au CompressionProviderCollection :

  • Le fournisseur de compression Gzip est ajouté par défaut au groupe des fournisseurs de compression, ainsi que le fournisseur de compression Brotli.
  • La compression par défaut est la compression Brotli lorsque le format de données compressée Brotli est pris en charge par le client. Si Brotli n’est pas pris en charge par le client, la compression par défaut devient Gzip lorsque le client prend en charge la compression Gzip.
public void ConfigureServices(IServiceCollection services)
{
    services.AddResponseCompression();
}

Le fournisseur de compression Gzip doit être ajouté lorsque des fournisseurs de compression sont explicitement ajoutés :

public void ConfigureServices(IServiceCollection services)
{
    services.AddResponseCompression(options =>
    {
        options.Providers.Add<BrotliCompressionProvider>();
        options.Providers.Add<GzipCompressionProvider>();
        options.Providers.Add<CustomCompressionProvider>();
        options.MimeTypes = 
            ResponseCompressionDefaults.MimeTypes.Concat(
                new[] { "image/svg+xml" });
    });
}

Définir le niveau de compression avec GzipCompressionProviderOptions. Le fournisseur de compression Gzip a par défaut le niveau de compression le plus rapide, (CompressionLevel.Fastest), ce qui peut ne pas produire la compression la plus efficace. Si vous souhaitez la compression la plus efficace, configurez l’intergiciel pour une compression optimale.

Niveau de compression Description
CompressionLevel.Fastest La compression doit s'exécuter aussi rapidement que possible, même si la sortie résultante n'est pas compressée de manière optimale.
CompressionLevel.NoCompression Aucune compression ne doit être effectuée.
CompressionLevel.Optimal Les réponses doivent être compressées de manière optimale, même si la compression prend plus de temps.
public void ConfigureServices(IServiceCollection services)
{
    services.AddResponseCompression();

    services.Configure<GzipCompressionProviderOptions>(options => 
    {
        options.Level = CompressionLevel.Fastest;
    });
}

Fournisseurs personnalisés

Créer des implémentations de compression personnalisées avec ICompressionProvider. Le EncodingName représente l’encodage de contenu que ce ICompressionProvider produit. L’intergiciel utilise ces informations pour choisir le fournisseur en fonction de la liste spécifiée dans l’en-tête Accept-Encoding de la requête.

À l’aide de l’exemple d’application, le client envoie une requête avec l’en-tête Accept-Encoding: mycustomcompression. L’intergiciel utilise l’implémentation de compression personnalisée et retourne la réponse avec un en-tête Content-Encoding: mycustomcompression. Le client doit pouvoir décompresser l’encodage personnalisé pour qu’une implémentation de compression personnalisée fonctionne.

public void ConfigureServices(IServiceCollection services)
{
    services.AddResponseCompression(options =>
    {
        options.Providers.Add<BrotliCompressionProvider>();
        options.Providers.Add<GzipCompressionProvider>();
        options.Providers.Add<CustomCompressionProvider>();
        options.MimeTypes = 
            ResponseCompressionDefaults.MimeTypes.Concat(
                new[] { "image/svg+xml" });
    });
}
public class CustomCompressionProvider : ICompressionProvider
{
    public string EncodingName => "mycustomcompression";
    public bool SupportsFlush => true;

    public Stream CreateStream(Stream outputStream)
    {
        // Create a custom compression stream wrapper here
        return outputStream;
    }
}

Envoyez une requête à l’exemple d’application avec l’en-tête Accept-Encoding: mycustomcompression et observez les en-têtes de réponse. Les en-têtes Vary et Content-Encoding sont présents dans la réponse. Le corps de la réponse (non affiché) n’est pas compressé par l’exemple. Il n’existe pas d’implémentation de compression dans la classe CustomCompressionProvider de l’exemple. Toutefois, l’exemple montre où vous pourriez implémenter un tel algorithme de compression.

Fiddler window showing result of a request with the Accept-Encoding header and a value of mycustomcompression. The Vary and Content-Encoding headers are added to the response.

types MIME

L’intergiciel spécifie un ensemble par défaut de types MIME pour la compression :

  • application/javascript
  • application/json
  • application/xml
  • text/css
  • text/html
  • text/json
  • text/plain
  • text/xml

Remplacez ou complétez les types MIME avec les options d’intergiciel de compression de réponse. Notez que les types MIME génériques, tels que text/* ne sont pas pris en charge. L’exemple d’application ajoute un type MIME pour image/svg+xml et compresse et sert l’image de bannière ASP.NET Core (banner.svg).

public void ConfigureServices(IServiceCollection services)
{
    services.AddResponseCompression(options =>
    {
        options.Providers.Add<BrotliCompressionProvider>();
        options.Providers.Add<GzipCompressionProvider>();
        options.Providers.Add<CustomCompressionProvider>();
        options.MimeTypes = 
            ResponseCompressionDefaults.MimeTypes.Concat(
                new[] { "image/svg+xml" });
    });
}

Compression avec protocole sécurisé

Les réponses compressées sur des connexions sécurisées peuvent être contrôlées avec l’option EnableForHttps, qui est désactivée par défaut. L’utilisation de la compression avec des pages générées dynamiquement peut entraîner des problèmes de sécurité tels que les attaques CRIME et BREACH.

Ajouter l’en-tête Vary

Lors de la compression des réponses en fonction de l’en-tête Accept-Encoding, il existe potentiellement plusieurs versions compressées de la réponse et une version non compressée. Pour indiquer aux caches client et proxy que plusieurs versions existent et doivent être stockées, l’en-tête Vary est ajouté avec une valeur Accept-Encoding. Dans ASP.NET Core 2.0 ou une version ultérieure, l’intergiciel ajoute automatiquement l’en-tête Vary lorsque la réponse est compressée.

Problème d’intergiciel derrière un proxy inverse Nginx

Lorsqu’une requête est proxiée par Nginx, l’en-tête Accept-Encoding est supprimé. La suppression de l’en-tête Accept-Encoding empêche l’intergiciel de compresser la réponse. Pour plus d’informations, consultez NGINX : Compression et décompression. Ce problème est suivi par Comprendre la compression pass-through pour Nginx (dotnet/aspnetcore#5989).

Travailler avec la compression dynamique IIS

Si vous souhaitez désactiver pour une application un module de compression dynamique IIS actif configuré au niveau du serveur , désactivez le module avec un ajout au fichier web.config. Pour plus d’informations, consultez Désactivation de modules IIS.

Dépannage

Utilisez un outil comme Fiddler ou Firefox Browser Developer, qui vous permettent de définir l’en-tête de requête Accept-Encoding et d’examiner les en-têtes, la taille et le corps de la réponse. Par défaut, l’intergiciel de compression de réponse compresse les réponses qui répondent aux conditions suivantes :

  • L’en-tête Accept-Encoding est présent avec une valeur de br, gzip, * ou l’encodage personnalisé qui correspond au fournisseur de compression personnalisé que vous avez établi. La valeur ne doit pas être identity ou avoir un paramètre de valeur de qualité (qvalue, q) de 0 (zéro).
  • Le type MIME (Content-Type) doit être défini et doit correspondre à un type MIME configuré sur le ResponseCompressionOptions.
  • La requête ne doit pas inclure l’en-tête Content-Range.
  • La requête doit utiliser un protocole non sécurisé (http), sauf si le protocole sécurisé (https) est configuré dans les options d’intergiciel de compression de réponse. Notez le danger décrit ci-dessus lors de l’activation de la compression de contenu sécurisée.

Ressources supplémentaires