gzip, наче все ok


Попередні два пости були про gzip, і цей буде про gzip. Я дещо пройшовся по граблях (можна подивитися git log для цього файлу); схоже, тепер в мене все вийшло. Нарешті.

docker run -it --rm ubuntu
apt update
apt install apache2 curl brotli zopfli
service apache2 start

Так. Це буде моє тестове середовище.

curl -s -I http://127.0.0.1 | grep Content-Length
# Пише:
# Content-Length: 10918

curl -s -H "Accept-Encoding: gzip" -I http://127.0.0.1 | grep Content-Length
# Пише:
# Content-Length: 3138

Це стандартна стартова сторінка Апача. Стиснута штатним модулем mod_deflate, вона важить 3138 байт. Запам’ятаю.

Роблю pre-compressed версію цього файлу.

zopfli /var/www/html/index.html
brotli -Z /var/www/html/index.html
ls -l /var/www/html/
# Пише:
# -rw-r--r-- 1 root root 10918 Jan 31 00:31 index.html
# -rw-r--r-- 1 root root  2325 Jan 31 00:31 index.html.br
# -rw-r--r-- 1 root root  3041 Jan 31 00:51 index.html.gz

Запам’ятаю ще одну важливу цифру — 3041 байт.

Так. Тепер я напишу шматок конфігурації, користуючись офіційним прикладом з документації до mod_deflate.

cat - >/etc/apache2/conf-available/precompressed.conf <<'CONFIG'
<Directory /var/www>
  <IfModule mod_headers.c>
    <IfModule mod_rewrite.c>
      RewriteEngine on

      RewriteCond "%{HTTP:Accept-encoding}" "br"
      RewriteCond "%{REQUEST_FILENAME}\.br" -s
      RewriteRule "^(.*)\.(html|css|js)"    "$1\.$2\.br" [QSA]
      RewriteRule "\.html\.br$" "-" [T=text/html,E=no-gzip:1,E=no-brotli:1]
      RewriteRule "\.css\.br$"  "-" [T=text/css,E=no-gzip:1,E=no-brotli:1]
      RewriteRule "\.js\.br$"   "-" [T=text/javascript,E=no-gzip:1,E=no-brotli:1]
      <FilesMatch "\.(html|js|css)\.br$">
        RemoveLanguage .br
        Header set Content-Encoding br
        Header append Vary Accept-Encoding
      </FilesMatch>

      RewriteCond "%{HTTP:Accept-encoding}" "gzip"
      RewriteCond "%{REQUEST_FILENAME}\.gz" -s
      RewriteRule "^(.*)\.(html|css|js)"    "$1\.$2\.gz" [QSA]
      RewriteRule "\.html\.gz$" "-" [T=text/html,E=no-gzip:1,E=no-brotli:1]
      RewriteRule "\.css\.gz$"  "-" [T=text/css,E=no-gzip:1,E=no-brotli:1]
      RewriteRule "\.js\.gz$"   "-" [T=text/javascript,E=no-gzip:1,E=no-brotli:1]
      <FilesMatch "\.(html|js|css)\.gz$">
        Header set Content-Encoding gzip
        Header append Vary Accept-Encoding
      </FilesMatch>
    </IfModule>
  </IfModule>
</Directory>
CONFIG

a2enconf precompressed
a2enmod headers rewrite
service apache2 restart

Все готово.

curl -s -H "Accept-Encoding: gzip" -I http://127.0.0.1
# Пише:
# HTTP/1.1 200 OK
# Date: Sun, 31 Jan 2021 00:31:42 GMT
# Server: Apache/2.4.41 (Ubuntu)
# Vary: Accept-encoding
# Last-Modified: Sat, 30 Jan 2021 22:51:51 GMT
# ETag: "be1-5ba25f776b8ba"
# Accept-Ranges: bytes
# Content-Length: 3041
# Content-Encoding: gzip
# Content-Type: text/html

Довжина 3041 байт, а не 3138. Так. Це воно. Це результат роботи Zopfli.

curl -s -H "Accept-Encoding: gzip, br" -I http://127.0.0.1
# Пише:
# HTTP/1.1 200 OK
# Date: Sun, 31 Jan 2021 00:32:31 GMT
# Server: Apache/2.4.41 (Ubuntu)
# Vary: Accept-encoding
# Last-Modified: Sat, 30 Jan 2021 22:31:57 GMT
# ETag: "915-5ba25b03e9140"
# Accept-Ranges: bytes
# Content-Length: 2325
# Content-Encoding: br
# Content-Type: text/html

Це статичний Brotli. Все працює. Наче все добре.