1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
# 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 if @compress_output==false
    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