class RewriteRule

Attributes

line[RW]
possibilities[RW]
substitution[RW]

Public Class Methods

new(line, conditions = []) click to toggle source
# File lib/rewrite_rule.rb, line 9
def initialize(line, conditions = [])
  @line = line
  @conds = conditions

  self.parse line

  raise Untestable.new unless @conds.empty?
  raise InvalidRule.new unless valid?
end

Public Instance Methods

last?() click to toggle source
# File lib/rewrite_rule.rb, line 55
def last?
  !@flags.nil? && @flags.include?('L')
end
parse(line) click to toggle source

Parse an apache RewriteRule and transform it into a Ruby object

# File lib/rewrite_rule.rb, line 20
def parse(line)
  match_data = /RewriteRule[ ]+([^ ]+)[ ]+([^ ]+)([ ]+\[([^ ]+)\]\n?)?$/.match(line)

  return if match_data.nil?

  @regex = match_data[1]
  @possibilities = generate_possibilities @regex
  @substitution = match_data[2]
  @substitutions = @possibilities.map do |possibility|
    ::Redirects.substitute @substitution, possibility[:substituted_data]
  end
  @flags = match_data[4].nil? ? nil : match_data[4].split(',')

end
redirection?() click to toggle source
# File lib/rewrite_rule.rb, line 39
def redirection?
  !@flags.nil? && @flags.any?{ |flag| /^R/.match(flag) }
end
redirects() click to toggle source
# File lib/rewrite_rule.rb, line 43
def redirects
  @substitutions.map.with_index do |substitution, i|
    request = ::Redirects.substitute(@possibilities[i][:request_uri])
    response = substitution.nil? ? request : substitution
    { 
      :possibility => request,
      :substitution => response,
      :code => redirection_code(@flags)
    }
  end
end
valid?() click to toggle source
# File lib/rewrite_rule.rb, line 35
def valid?
  !@regex.nil? && !@substitution.nil?
end

Private Instance Methods

generate_possibilities(regex) click to toggle source
# File lib/rewrite_rule.rb, line 61
def generate_possibilities regex
  some = []
  base = regex.gsub(/\^|\$/,'')

  capture_regex = /\(([^)^(]+?)\)\??/
  match_data = capture_regex.match(base)
  substituted_data = []
  until match_data.nil?    
    matched = match_data[1]
    if /\.\*/.match(matched)
      # Match anything -> Replace by a random string
      matched = matched.gsub('.*', generate_random_string(0, 8))
    elsif /\?$/.match(match_data[0])            
      # Maybe regex -> Replace by match or by empty string
      matched = rand(2) == 0 ? matched : ''
    end
    
    base = base.gsub(match_data[0], matched)
    substituted_data << matched
    match_data = capture_regex.match(base)
  end

  any_regex = /(\.\*)/
  match_data = any_regex.match(base)
  until match_data.nil?
    matched = match_data[1]
    matched = matched.gsub('.*', generate_random_string(0, 8))
    base = base.gsub(match_data[0], matched)
    match_data = any_regex.match(base)
  end
  
  some << {
    :request_uri => "#{base}",
    :substituted_data => substituted_data
  }
end
generate_random_string(min, max) click to toggle source

Generate a string containing downcase letters, with a random length included between min and max

# File lib/rewrite_rule.rb, line 100
def generate_random_string min, max
  (min...rand(max)).map { (97 + rand(26)).chr }.join
end
redirection_code(flags) click to toggle source
# File lib/rewrite_rule.rb, line 104
def redirection_code flags
  redirect_regex = /^R=?([0-9]{3})?$/
  redirect_regex.match(flags.detect { |flag| redirect_regex.match(flag) })[1] || '302'
end