Class: Fluoride::Analyzer::Parser

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

Defined Under Namespace

Classes: Patterner, RoutePattern

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initializeParser

Returns a new instance of Parser.



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

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.



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

def counts
  @counts
end

#exceptionsObject (readonly)

Returns the value of attribute exceptions.



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

def exceptions
  @exceptions
end

#filesObject

Returns the value of attribute files.



8
9
10
# File 'lib/fluoride-analyzer/parser.rb', line 8

def files
  @files
end

#limitObject

Returns the value of attribute limit.



8
9
10
# File 'lib/fluoride-analyzer/parser.rb', line 8

def limit
  @limit
end

#resultsObject (readonly)

Returns the value of attribute results.



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

def results
  @results
end

#target_pathObject

Returns the value of attribute target_path.



8
9
10
# File 'lib/fluoride-analyzer/parser.rb', line 8

def target_path
  @target_path
end

Instance Method Details

#collect_record(file, record, index) ⇒ Object



209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
# File 'lib/fluoride-analyzer/parser.rb', line 209

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)


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

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



31
32
33
# File 'lib/fluoride-analyzer/parser.rb', line 31

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

#excluded_pathsObject



35
36
37
# File 'lib/fluoride-analyzer/parser.rb', line 35

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

#format_record(record, path_params) ⇒ Object



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

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



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

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



247
248
249
250
251
252
253
254
255
256
257
258
259
# File 'lib/fluoride-analyzer/parser.rb', line 247

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



205
206
207
# File 'lib/fluoride-analyzer/parser.rb', line 205

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

#post_params(record) ⇒ Object



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

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