68 lines
1.7 KiB
Ruby
68 lines
1.7 KiB
Ruby
# OutputCompression
|
|
# Rails output compression filters
|
|
#
|
|
# Adds two classmethods to ActionController that can be used as after-filters:
|
|
# strip_whitespace and compress_output.
|
|
# If you use page-caching, you MUST specify the compress_output filter AFTER
|
|
# caches_page, otherwise the compressed data will be cached instead of the HTML
|
|
#
|
|
# class MyController < ApplicationController
|
|
# after_filter :strip_whitespace
|
|
# caches_page :index
|
|
# after_filter :compress_output
|
|
# end
|
|
|
|
begin
|
|
require "zlib"
|
|
require "stringio"
|
|
GZIP_SUPPORTED = true
|
|
rescue
|
|
GZIP_SUPPORTED = false
|
|
end
|
|
|
|
module CompressionSystem
|
|
def compress_output
|
|
return unless accepts_gzip?
|
|
output = StringIO.new
|
|
def output.close
|
|
# Zlib does a close. Bad Zlib...
|
|
rewind
|
|
end
|
|
gz = Zlib::GzipWriter.new(output)
|
|
gz.write(response.body)
|
|
gz.close
|
|
if output.length < response.body.length
|
|
@old_response_body = response.body
|
|
response.body = output.string
|
|
response.headers["Content-encoding"] = @compression_encoding
|
|
end
|
|
end
|
|
|
|
def accepts_gzip?
|
|
return false unless GZIP_SUPPORTED
|
|
accepts = request.env["HTTP_ACCEPT_ENCODING"]
|
|
return false unless accepts && accepts =~ /(x-gzip|gzip)/
|
|
@compression_encoding = $1
|
|
true
|
|
end
|
|
|
|
def strip_whitespace
|
|
response.body.gsub!(/()|(.*?<\/script>)|()|()|\s+/m) do |m|
|
|
if m =~ /^()(.*?)<\/script>$/m
|
|
$1 + $2.strip.gsub(/\s+/, " ").gsub("", "\n-->") + ""
|
|
elsif m =~ /^$/m
|
|
""
|
|
elsif m =~ /^<(textarea|pre)/
|
|
m
|
|
else " "
|
|
end
|
|
end
|
|
response.body.gsub! /\s+\s+/, ">"
|
|
end
|
|
end
|
|
|
|
module ActionController
|
|
class Base
|
|
include CompressionSystem
|
|
end
|
|
end
|