%

Nginx + Brotli / OpenBSD

Article publié, le et modifié le
5 minutes de lecture

Cet article contient 858 mots.
Source brute de l'article :
Commit version : 0c0ab51

Description

Sous OpenBSD, il n’y a pas encore de port du module nginx-brotli, donc la gestion de la compression au format Brotli semble compromise. Et, bien : non !

Version :

  • OpenBSD : 6.7, 6.8
  • nginx : 1.16.1, 1.18.0
  • brotli : 1.0.7

nginx et brotli ne sont pas dans le système de base, mais dans les ports. À installer avec la commande pkg_add


Étant donné qu’il n’est pas recommandé d’activer la compression à la volée - sauf au doux sacrifice d’usage de techniques CSP et de contrôle absolu sur l’émetteur du contenu compressé à la volée -, dans ce mémo, nous nous concentrerons sur la délivrance de contenu compressé de fichiers statiques.

Il y a une manière assez simple de mettre en place :

  1. Compresser les fichiers statiques au format brotli avant l’envoi sur l’espace web
  2. Au sein de nginx :
    • Vérifier le support du format par le client web
    • Vérifier que le fichier statique compressé existe localement
    • Envoi du fichier statique compressé.

Compression brotli local

La compression de fichiers se fait simplement : $ brotli -Z fichier qui produira un fichier supplémentaire portant l’extension br. L’option -Z offre le meilleur taux de compression, par défaut.

Lire le manpage installé, pour plus d’informations, si besoin… $ man brotli


Voici la fonction que j’utilise dans le cadre de mon fichier deploy pour mes fichiers créés avec Hugo :

Fichier : deploy

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
_gz() {
    cd "${dir_local}" || exit 1
    
    find . -type f -size +1024c -a \( \
        -name "*.css" -o -name "*.eot" -o -name "*.html" -o -name "*.js" \
        -o -name "*.otf" -o -name "*.svg" -o -name "*.ttf" -o -name "*.txt" \
        -o -name "*.xml" \
        \) | while read -r line; do echo "Compress ${line}"; brotli -Z "${line}"; gzip -9 -f < "${line}" > "${line}.gz"; done
        
    cd "$ROOT" || exit 1
}

Ainsi, si le fichier statique fait plus de 1024 octets - choix totalement arbitraire - et que son extension est de type CSS, JS, JSON, HTML, SVG, TXT, ou XML, ou des fichiers de fonts de type eot, otf, ou ttf, alors la fonction compresse, dans un premier temps, au format brotli, suivi d’une compression au format gzip.

Info

Configuration nginx

Passons maintenant au paramètrage du serveur web nginx. Dans le contexte server :

  1. Dans un premier temps, nous déclarons une variable nommée $extension : set $extension "";
  2. puis, nous vérifions le support de brotli par le client web, pour affecter la variable $extension qui nous servira ensuite : if ($http_accept_encoding ~ br) { set $extension .br; }
  3. dans un second temps, nous demandons à nginx de vérifier l’existence du fichier statique au format compressé : if (-f $request_filename$extension) { rewrite (.*) $1$extension break; }
  4. ensuite, nous utilisons les déclarations de contexte location pour délivrer le fichier statique demandé dans sa forme compressée. Par exemple, pour un fichier CSS : location ~ /*.css.br$ { add_header Content-Encoding br; add_header Vary "Accept-Encoding"; gzip off; types {} default_type text/css; } Faire de même pour les autres formats de fichiers compressables, tels que ceux cités ci-dessus. Remarquons :
    • l’usage de la déclaration gzip off; puisque nous n’avons pas besoin à ce moment de ladite compression.
    • l’ajout des entêtes HTTP nécessaires
    • et la déclaration du type de contenu lié au format de fichier délivré.

Voilà.


Pour finir, je vous offre les deux fichiers de déclaration que j’utilise pour mon serveur nginx sous OpenBSD :

Fichier : /etc/nginx/conf.d/brotli.conf

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
set $extension "";

if ($http_accept_encoding ~ br) {
    set $extension .br;
}

if (-f $request_filename$extension) {
    rewrite (.*) $1$extension break;
}

location ~ /*.css.br$ {
    include /etc/nginx/conf.d/brotli-infos.conf;
    default_type text/css;
}

# font file eot
location ~ /*.eot.br$ {
    include /etc/nginx/conf.d/server/brotli-infos.conf;
    default_type application/vnd.ms-fontobject;
}
         
location ~ /*.html.br {
    include /etc/nginx/conf.d/brotli-infos.conf;
    default_type text/html;
}

location ~ /*.js.br$ {
    include /etc/nginx/conf.d/brotli-infos.conf;
    default_type application/javascript;
}

location ~ /*.json.br$ {
    include /etc/nginx/conf.d/brotli-infos.conf;
    default_type application/json;
}       

# opentype font file
location ~ /*.otf.br$ {
    include /etc/nginx/conf.d/server/brotli-infos.conf;
    default_type font/opentype;
}
                         
location ~ /*.svg.br$ {
    include /etc/nginx/conf.d/brotli-infos.conf;
    default_type image/svg+xml;
}

# font file ttf
location ~ /*.ttf.br$ {
    include /etc/nginx/conf.d/server/brotli-infos.conf;
    default_type font/ttf;
}

location ~ /*.txt.br$ {
    include /etc/nginx/conf.d/brotli-infos.conf;
    default_type text/plain;
}

location ~ /*.xml.br$ {
    include /etc/nginx/conf.d/brotli-infos.conf;
    default_type text/xml;
}

Fichier : /etc/nginx/conf.d/brotli-infos.conf

1
2
3
add_header Content-Encoding br;
add_header Vary "Accept-Encoding";
gzip off;

Documentations