Skip to content

fix: skip gzip for compressed types, parse Accept-Encoding quality values#6

Draft
troglodyne-bot wants to merge 1 commit into
Troglodyne-Internet-Widgets:masterfrom
troglodyne-bot:koan/fix-compression-logic
Draft

fix: skip gzip for compressed types, parse Accept-Encoding quality values#6
troglodyne-bot wants to merge 1 commit into
Troglodyne-Internet-Widgets:masterfrom
troglodyne-bot:koan/fix-compression-logic

Conversation

@troglodyne-bot

Copy link
Copy Markdown
Contributor

What

Two bugs in HTTP compression handling fixed, with tests.

Why

  1. Accept-Encoding quality values silently disabled gzip: 'gzip;q=0.9' never matched 'gzip' via equality — any client that sends quality parameters (proxies, HTTP/2 negotiators) got uncompressed responses without any error.

  2. Already-compressed MIME types were gzip'd anyway: PNG, JPEG, ZIP, PDF, WebP, and a dozen other pre-compressed formats were run through IO::Compress::Gzip every request. These formats don't compress further — they only get larger and waste CPU. On a media-heavy site this is pure overhead.

Also removes a duplicate use File::Find import (lines 27 and 36 pre-patch).

How

  • Extracted Accept-Encoding parsing into _accepts_gzip($header) — strips quality params (s/;.*//r) before matching, returns explicit 1/0.
  • Added %incompressible_mime — a compile-time hash of MIME types that should never be gzip'd (images, audio, video, archives, PDF, WASM, Office docs).
  • serve() now checks $incompressible_mime{$ft} before compressing; skips to the uncompressed path if matched.

Testing

t/04-compression.t — 14 assertions:

  • 9 for _accepts_gzip: covers plain, quality values, multiple encodings, false cases
  • 5 for serve() compression behavior: text gets encoded, PNG/JPEG/ZIP do not, deflate=0 disables compression

…lues

Two bugs in HTTP compression handling:

1. Accept-Encoding parsing used string equality on the raw token, so
   'gzip;q=0.9' never matched 'gzip'. Strip quality params before
   comparing. Extracted into _accepts_gzip() for testability.

2. serve() gzip'd all files regardless of MIME type — compressing
   already-compressed formats (JPEG, PNG, ZIP, PDF, etc.) wastes CPU
   and produces larger responses. Added %incompressible_mime guard.

Also removes duplicate 'use File::Find' import.

Tests: t/04-compression.t — 14 assertions covering both bugs.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Comment thread lib/TPSGI.pm

my $ct = 'Content-type';

# MIME types that are already compressed — gzip would waste CPU and bloat responses

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is a less than comprehensive list. I'd prefer if it was accurate for at least the list of mime types understood by Plack::MIME, given that's what we're using in practice to figure mimetypes.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants