Refactor FilteredCompressHandler to inherit from stdlib

This changes its behavior to align with the stdlib variant in that
compression is now delayed till the moment that the server begins to
send a response.

This allows the handler to avoid compressing empty responses,and
safeguards against any double compression of content that may occur
if another handler decides to compressi ts response.

This does however come at the drawback(?) of it now removing
`content-length` headers on requests if it exists; since compression
makes the value inaccurate anyway.

See: https://github.com/crystal-lang/crystal/pull/9625
This commit is contained in:
syeopite 2025-05-28 15:38:49 -07:00
parent df8839d1f0
commit f61bfb9948
No known key found for this signature in database
GPG Key ID: A73C186DA3955A1A

View File

@ -61,28 +61,13 @@ class Kemal::ExceptionHandler
end end
end end
class FilteredCompressHandler < Kemal::Handler class FilteredCompressHandler < HTTP::CompressHandler
exclude ["/videoplayback", "/videoplayback/*", "/vi/*", "/sb/*", "/ggpht/*", "/api/v1/auth/notifications"] exclude ["/videoplayback", "/videoplayback/*", "/vi/*", "/sb/*", "/ggpht/*", "/api/v1/auth/notifications"]
exclude ["/api/v1/auth/notifications", "/data_control"], "POST" exclude ["/api/v1/auth/notifications", "/data_control"], "POST"
def call(env) def call(context)
return call_next env if exclude_match? env return call_next context if exclude_match? context
super
{% if flag?(:without_zlib) %}
call_next env
{% else %}
request_headers = env.request.headers
if request_headers.includes_word?("Accept-Encoding", "gzip")
env.response.headers["Content-Encoding"] = "gzip"
env.response.output = Compress::Gzip::Writer.new(env.response.output, sync_close: true)
elsif request_headers.includes_word?("Accept-Encoding", "deflate")
env.response.headers["Content-Encoding"] = "deflate"
env.response.output = Compress::Deflate::Writer.new(env.response.output, sync_close: true)
end
call_next env
{% end %}
end end
end end