# 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 

class ActionController::Base 
  include CompressionSystem 
end