class HTTPDisk::Grep::Main

Attributes

options[R]
success[R]

Public Class Methods

new(options) click to toggle source
# File lib/httpdisk/grep/main.rb, line 9
def initialize(options)
  @options = options
end

Public Instance Methods

paths() click to toggle source

file paths to be searched

# File lib/httpdisk/grep/main.rb, line 51
def paths
  # roots
  roots = options[:roots]
  roots = ['.'] if roots.empty?

  # find files in roots
  paths = roots.flat_map { Find.find(_1).to_a }.sort
  paths = paths.select { File.file?(_1) }

  # strip default './'
  paths = paths.map { _1.gsub(%r{^\./}, '') } if options[:roots].empty?
  paths
end
pattern() click to toggle source

regex pattern from options

# File lib/httpdisk/grep/main.rb, line 93
def pattern
  @pattern ||= Regexp.new(options[:pattern], Regexp::IGNORECASE)
end
prepare_body(payload) click to toggle source

convert raw body into something palatable for pattern matching

# File lib/httpdisk/grep/main.rb, line 66
def prepare_body(payload)
  body = payload.body

  if content_type = payload.headers['Content-Type']
    # Mismatches between Content-Type and body.encoding are fatal, so make
    # an effort to align them.
    if charset = content_type[/charset=([^;]+)/, 1]
      encoding = begin
        Encoding.find(charset)
      rescue StandardError
        nil
      end
      if encoding && body.encoding != encoding
        body.force_encoding(encoding)
      end
    end

    # pretty print json for easier searching
    if content_type =~ /\bjson\b/
      body = JSON.pretty_generate(JSON.parse(body))
    end
  end

  body
end
printer() click to toggle source

printer for output

# File lib/httpdisk/grep/main.rb, line 98
def printer
  @printer ||= case
  when options[:silent]
    Grep::SilentPrinter.new
  when options[:count]
    Grep::CountPrinter.new($stdout)
  when options[:head] || $stdout.tty?
    Grep::HeaderPrinter.new($stdout, options[:head])
  else
    Grep::TersePrinter.new($stdout)
  end
end
run() click to toggle source

Enumerate file paths one at a time. Returns true if matches were found.

# File lib/httpdisk/grep/main.rb, line 14
def run
  paths.each do
    begin
      run_one(_1)
    rescue StandardError => e
      if ENV['HTTPDISK_DEBUG']
        $stderr.puts
        $stderr.puts e.class
        $stderr.puts e.backtrace.join("\n")
      end
      raise CliError, "#{e.message[0, 70]} (#{_1})"
    end
  end
  success
end
run_one(path) click to toggle source
# File lib/httpdisk/grep/main.rb, line 30
def run_one(path)
  # read payload & body
  payload = Zlib::GzipReader.open(path, encoding: 'ASCII-8BIT') do
    Payload.read(_1)
  end
  body = prepare_body(payload)

  # collect all_matches
  all_matches = body.each_line.map do |line|
    [].tap do |matches|
      line.scan(pattern) { matches << Regexp.last_match }
    end
  end.reject(&:empty?)
  return if all_matches.empty?

  # print
  @success = true
  printer.print(path, payload, all_matches)
end