ASP.NET Core : activer la compression des réponses en GZIP / Deflate / Brotli (1/2)
Il peut être utile de supporter la compression les réponses lorsqu’elles sont volumineuse cela peut réduire considérablement le temps de téléchargement de celle ci.
Activer la compression gzip
Pour activer la compression gzip c’est très simple le framework ASP.NET Core fournit des classes toute faite.
Dans le fichier Startup il suffit d’activer la compression des réponses de la manière suivante :
1
2
3
4
5
6
7
8
|
using Microsoft.AspNetCore.ResponseCompression; ... public ConfigureServices(IServiceCollection services) { services.AddResponseCompression(); } |
Il est à noter que vous pouvez aussi configurer le niveau de compression Gzip de la manière suivante :
1
|
services.Configure<GzipCompressionProviderOptions>(o => o.Level = System.IO.Compression.CompressionLevel.Optimal); |
Si votre site est en https vous pouvez activer la compression de la manière suivante :
1
2
3
4
|
services.AddResponseCompression(o => { o.EnableForHttps = true ; }); |
Attention activer la compression avec le protocole HTTPS peut mener à des failles tel que BREACH et CRIME
Puis dans la méthode Configure vous devez appeler la méthode d’extension suivante :
1
|
app.UseResponseCompression(); |
Activer la compression Brotli
ASP.NET Core ne fournit pas de compression provider pour ce format.
Il faut donc l'écrire soit même.
Compression provider Brotli :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
public class BrotliCompressionProvider : ICompressionProvider { private readonly CompressionLevel _compressionLevel; public BrotliCompressionProvider(CompressionLevel compressionLevel = CompressionLevel.Fastest) { _compressionLevel = compressionLevel; } public string EncodingName => "br" ; public bool SupportsFlush => true ; public Stream CreateStream(Stream outputStream) { return new BrotliStream(outputStream, _compressionLevel); } } |
Activer la compression Deflate
Compression provider Defalte :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
public class DeflateCompressionProvider : ICompressionProvider { private readonly CompressionLevel _compressionLevel; public DeflateCompressionProvider(CompressionLevel compressionLevel = CompressionLevel.Fastest) { _compressionLevel = compressionLevel; } public string EncodingName => "deflate" ; public bool SupportsFlush => true ; public Stream CreateStream(Stream outputStream) { return new DeflateStream(outputStream, _compressionLevel); } } |
Attention la classe DeflateStream ne respectent pas bien la norme Deflate donc si vous utiliser un client autre que .Net il ne pourra pas décoder votre archive.
Ajout des ICompressionProvider custom
Puis, il faut modifier la méthode AddResponseCompression de la manière suivante :
1
2
3
4
5
6
|
services.AddResponseCompression(o => { o.Providers.Add( new BrotliCompressionProvider()); o.Providers.Add( new DeflateCompressionProvider()); o.EnableForHttps = true ; }); |
Récupérer une réponse compressée
Maintenant que nous avons une réponse compressée il n’y a qu’a l’utiliser.
Pour avoir un contenu compressé le client devra envoyé le header Accept-Encoding avec comme valeur gzip, ou deflate, ou br.
Il peut aussi envoyé les 3 “gzip,deflate,br” pour dire au serveur qu’il supporte les 3 formats.
Mais les clients de décompresse pas automatiquement les réponses :
– heureusement ma libraire Tiny.RestClient le fait automatiquement sans besoin de configurer quoi que ce soit.
– La classe HttpClient permet de décompresser automatiquement un contenu compressé.
Mais son utilisation n’est pas évidente car il faut lui passer un handler spécifique :
1
2
3
4
5
6
7
8
9
10
11
|
HttpClientHandler handler = new HttpClientHandler() { AutomaticDecompression = DecompressionMethods.GZip | DecompressionMethods.Deflate };
using ( var client = new HttpClient(handler)) { .... } |
Attention pour l'instant la compression brotli n'est pas encore géré par HttpClient.
Quand faut-il activer la compression ?
La documentation précise qu’il ne faut pas compresser des fichiers inférieurs à 1000 octets car cela peut produire un fichier compressé plus volumineux que le fichier non compressé.
Il est aussi à noter que la compression rajoute de la charge de calculs côté serveur.
Dans le prochain article, nous verrons comment supporter un appel d'une requête avec un contenu déjà compressé.
Happy coding.
Commentaires