Class: Fluoride::Analyzer::Parser

Inherits:
Object
  • Object
show all
Defined in:
lib/fluoride-analyzer/parser.rb

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initializeParser

Returns a new instance of Parser.



13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
# File 'lib/fluoride-analyzer/parser.rb', line 13

def initialize
  @exceptions = []
  @counts = {
    :excluded => 0,
    :unrecognized => 0,
    :no_matching_route => 0,
    :exceptions => 0
  }
  @results = Hash.new do|results, pattern| #PATH PATTERN
    results[pattern] = Hash.new do |by_method, method| #METHOD
      by_method[method] = Hash.new do |records, status| #STATUS CODE
        records[status] = Hash.new do |record, key| #formatted record
          record[key] = []
        end
      end
    end
  end
  @limit = -1
end

Instance Attribute Details

#countsObject (readonly)

Returns the value of attribute counts.



11
12
13
# File 'lib/fluoride-analyzer/parser.rb', line 11

def counts
  @counts
end

#exceptionsObject (readonly)

Returns the value of attribute exceptions.



11
12
13
# File 'lib/fluoride-analyzer/parser.rb', line 11

def exceptions
  @exceptions
end

#filesObject

Returns the value of attribute files.



10
11
12
# File 'lib/fluoride-analyzer/parser.rb', line 10

def files
  @files
end

#limitObject

Returns the value of attribute limit.



10
11
12
# File 'lib/fluoride-analyzer/parser.rb', line 10

def limit
  @limit
end

#resultsObject (readonly)

Returns the value of attribute results.



11
12
13
# File 'lib/fluoride-analyzer/parser.rb', line 11

def results
  @results
end

Instance Method Details

#collect_record(file, record, index) ⇒ Object



102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
# File 'lib/fluoride-analyzer/parser.rb', line 102

def collect_record(file, record, index)
  if exclude?(record)
    @counts[:excluded] += 1
    return
  end

  request_env = {
    "REQUEST_METHOD" => record['request']['method'].to_s.upcase,
    "PATH_INFO"  => record['request']['path'],
  }
  unless request_env['REQUEST_METHOD'] == "GET"
    request_env['rack.input'] = StringIO.new(record['request']['body'])
  end

  pattern = patterner.build(request_env)

  route = pattern.route

  if route.nil?
    @counts[:unrecognized] += 1
    return
  end

  if pattern.path_spec == :unrecognized
    @counts[:no_matching_route] += 1
    warn "Unrecognized route: #{record['request']['path'].inspect}"
  else
    route_path = pattern.path_spec
    path_params = Hash[pattern.segment_keys.map do |key|
      [key, params[key]]
    end]
  end

  formatted_record = format_record(record, path_params).merge(post_params(record))

  self.results[route_path][record['request']['method']][record['response']['status']][formatted_record] << [file, index]
end

#exclude?(record) ⇒ Boolean

Returns:

  • (Boolean)


41
42
43
44
45
46
47
48
49
50
51
52
53
54
# File 'lib/fluoride-analyzer/parser.rb', line 41

def exclude?(record)
  return true if record['type'] == 'exception_raised'

  if excluded_content_types.any?{ |reg| reg =~ record['response']['headers']['Content-Type'] }
    return true
  end
  if excluded_paths.any?{|req| req =~ record['request']['path']}
    return true
  end
  return false
rescue
  warn "Exception raised while filtering record: #{record.inspect}"
  raise
end

#excluded_content_typesObject



33
34
35
# File 'lib/fluoride-analyzer/parser.rb', line 33

def excluded_content_types
  [ %r[image], %r[text/css], %r[javascript], %r[shockwave] ]
end

#excluded_pathsObject



37
38
39
# File 'lib/fluoride-analyzer/parser.rb', line 37

def excluded_paths
  [ %r[^/images], %r[\.ttf\z], %r[\.woff\z] ]
end

#format_record(record, path_params) ⇒ Object



56
57
58
59
60
61
62
63
64
65
66
# File 'lib/fluoride-analyzer/parser.rb', line 56

def format_record(record, path_params)
  {
    'path' => record['request']['path'],
    'query_params' => record['request']['query_params'],
    'content-type' => record['request']['content_type'],
    'path_params' => path_params,
    'redirect_location' => record['response']['headers']['Location'],
    'host' => record['request']['host']
    #'accept' => record['request']['accept']
  }
end

#formatted_resultsObject



68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
# File 'lib/fluoride-analyzer/parser.rb', line 68

def formatted_results
  formatted = {}
  results.each do |pattern, methods|
    frmt_methods = formatted[pattern] = {}
    methods.each do |method, status|
      frmt_statuses = frmt_methods[method] = {}
      status.each do |code, requests|
        frmt_statuses[code] = requests.keys.map do |req_hash|
          hash = req_hash.dup
          hash['sources'] = Hash[requests[req_hash]]
          hash
        end
      end
    end
  end
  formatted
end

#parse_stream(file, string) ⇒ Object



140
141
142
143
144
145
146
147
148
149
150
151
152
# File 'lib/fluoride-analyzer/parser.rb', line 140

def parse_stream(file, string)
  stream = YAML.load_stream(string)
  stream = stream.documents if stream.respond_to? :documents

  stream.each_with_index do |record, index|
    collect_record(file, record, index)
  end
rescue ArgumentError => ex
  @exceptions << [ex, file]
rescue Exception => ex
  @exceptions << [ex, file]
  raise
end

#patternerObject



98
99
100
# File 'lib/fluoride-analyzer/parser.rb', line 98

def patterner
  @patterner ||= Patterner.for(Rails.application.routes)
end

#post_params(record) ⇒ Object



86
87
88
89
90
91
92
93
94
95
96
# File 'lib/fluoride-analyzer/parser.rb', line 86

def post_params(record)
  return {} unless %w{POST PUT}.include?(record['request']['method'])
  unless record['request']['content_type'].nil? or
    %r[^application/x-www-form-urlencoded.*] =~ record['request']['content_type']
    return {}
  end

  form_hash = Rack::Utils.parse_nested_query(record['request']['body'])

  { 'post_params' => form_hash }
end