]> git.openstreetmap.org Git - rails.git/blob - lib/output_compression/output_compression.rb
2c5dd6ca541b3882499d11197647ef71c956b80b
[rails.git] / lib / output_compression / output_compression.rb
1 # OutputCompression
2 # Rails output compression filters
3 #
4 # Adds two classmethods to ActionController that can be used as after-filters:
5 # strip_whitespace and compress_output.
6 # If you use page-caching, you MUST specify the compress_output filter AFTER
7 # caches_page, otherwise the compressed data will be cached instead of the HTML
8 #
9 # class MyController < ApplicationController
10 #  after_filter :strip_whitespace
11 #  caches_page :index
12 #  after_filter :compress_output
13 # end
14
15 begin
16   require 'zlib'
17   require 'stringio'
18   GZIP_SUPPORTED = true
19 rescue
20   GZIP_SUPPORTED = false
21 end
22
23 module CompressionSystem
24   def compress_output
25     return unless accepts_gzip?
26     output = StringIO.new
27     def output.close
28       # Zlib does a close. Bad Zlib...
29       rewind
30     end
31     gz = Zlib::GzipWriter.new(output)
32     gz.write(response.body)
33     gz.close
34     if output.length < response.body.length
35       @old_response_body = response.body
36       response.body = output.string
37       response.headers['Content-encoding'] = @compression_encoding
38     end
39   end
40
41   def accepts_gzip?
42     return false unless GZIP_SUPPORTED
43     accepts = request.env['HTTP_ACCEPT_ENCODING']
44     return false unless accepts && accepts =~ /(x-gzip|gzip)/
45     @compression_encoding = $1
46     true
47   end
48
49   def strip_whitespace
50     response.body.gsub!(/()|(.*?<\/script>)|()|()|\s+/m) do |m|
51       if m =~ /^()(.*?)<\/script>$/m
52         $1 + $2.strip.gsub(/\s+/, ' ').gsub('', "\n-->") + ''
53       elsif m =~ /^$/m
54         ''
55       elsif m =~ /^<(textarea|pre)/
56         m
57       else ' '
58       end
59     end
60     response.body.gsub! /\s+\s+/, '>'
61   end
62 end
63
64 class ActionController::Base
65   include CompressionSystem
66 end