Class: Rack::Diet

Inherits:
Object
  • Object
show all
Defined in:
lib/rack/diet.rb,
lib/rack/diet/version.rb

Constant Summary collapse

ALLOWED_HOSTS =
%w(localhost 127.0.0.1)
VERSION =
"0.1.0"

Instance Method Summary collapse

Constructor Details

#initialize(app, allowed_hosts: ALLOWED_HOSTS) ⇒ Diet

Returns a new instance of Diet.



9
10
11
12
# File 'lib/rack/diet.rb', line 9

def initialize(app, allowed_hosts: ALLOWED_HOSTS)
  @app = app
  @allowed_hosts = allowed_hosts + [nil]
end

Instance Method Details

#call(env) ⇒ Object



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
# File 'lib/rack/diet.rb', line 14

def call(env)
  status, headers, body = @app.call(env)

  if headers.fetch("Content-Type", "").match /text\/html/
    page = ::Nokogiri::HTML(body.enum_for(:each).to_a.join)
    page.css('script[src]')
      .select { |node| !@allowed_hosts.include?(URI(node["src"]).host) }
      .each   { |node| node.remove }
    page.css('script:not([src])')
      .select { |node| node.text.match /\.src\s*=/ }
      .each   { |node| node.remove }
    page.css('noscript')
      .each { |node| node.remove }
    page.css('link[rel="stylesheet"]')
      .select { |node| !@allowed_hosts.include?(URI(node["href"]).host) }
      .each   { |node| node.remove }
    page.css('head')
      .each { |node| node.add_child <<~EOS
        <style>
          * { animation-duration: 0s !important; }
        </style>
      EOS
      }

    Rack::Response.new(page.to_s, status, headers).to_a
  else
    Rack::Response.new(body, status, headers).to_a
  end
end