Sha256: 57fdd4b2dd1d5ec1cbd8f3ff2b2929f086d658ee3e683318bc4fd785b144c773

Contents?: true

Size: 1.29 KB

Versions: 1

Compression:

Stored size: 1.29 KB

Contents

require 'rack/nokogiri/version'

require 'rack'
require 'nokogiri'

module Rack
  class Nokogiri
    include Rack::Utils

    def initialize(app, opts = {}, &block)
      @app = app
      @opts = opts.select {|key, value| [:css, :xpath].include?(key) }
      @block = block
    end

    def call(env)
      status, headers, response = @app.call(env)
      headers = HeaderHash.new(headers)

      if should_process?(status, headers)
        content = extract_content(response)

        doc = ::Nokogiri::HTML(content)
        process_nodes(doc)
        content = doc.to_html

        headers['content-length'] = bytesize(content).to_s
        response = [content]
      end

      [status, headers, response]
    end

    def should_process?(status, headers)
      !STATUS_WITH_NO_ENTITY_BODY.include?(status) &&
         !headers['transfer-encoding'] &&
          headers['content-type'] &&
          headers['content-type'].include?('text/html')
    end

    def extract_content(response)
      response.reduce('') { |memo, part| memo + part }
    end

    def process_nodes(doc)
      nodes = ::Nokogiri::XML::NodeSet.new(doc)
      nodes += doc.css(@opts[:css])     unless @opts[:css].nil?
      nodes += doc.xpath(@opts[:xpath]) unless @opts[:xpath].nil?
      @block.call(nodes) unless nodes.empty?
    end

  end
end

Version data entries

1 entries across 1 versions & 1 rubygems

Version Path
rack-nokogiri-0.1.0 lib/rack/nokogiri.rb