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 :
- Ne pouvez pas utiliser les technologies de compression basées sur serveur suivantes :
- Êtes hébergé directement sur :
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 :
- Paramétrer
EnableForHttps
surtrue
pose un problème de sécurité. Pour plus d’informations , consultez Compression avec HTTPS dans cet article. 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 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. 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çantgzip, deflate, br
parnone
. - 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-Encoding
en-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 valeurbr
,gzip
,*
ou l’encodage personnalisé qui correspond à un fournisseur de compression personnalisé. La valeur ne doit pas êtreidentity
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).
- Affichez ou téléchargez l’exemple de code (procédure de téléchargement)
- Source intergiciel de compression de réponse
- Intergiciel (middleware) ASP.NET Core
- Réseau des développeurs Mozilla : Accept-Encoding
- RFC 9110 Section 8.4.1 : Codages de contenu
- RFC 9110 Section 8.4.1.3 : Codage Gzip
- Spécification du format de fichier GZIP version 4.3
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 :
- Ne pouvez pas utiliser les technologies de compression basées sur serveur suivantes :
- Êtes hébergé directement sur :
- Serveur HTTP.sys (anciennement WebListener)
- Kestrel serveur
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.
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.
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.
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 debr
,gzip
,*
ou l’encodage personnalisé qui correspond au fournisseur de compression personnalisé que vous avez établi. La valeur ne doit pas êtreidentity
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.