apachecrunch 0.4 → 0.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,88 @@
1
+ require 'test/stub'
2
+ require 'test/mock'
3
+
4
+ class TestLogParser < Test::Unit::TestCase
5
+ def setup
6
+ @entry_parser = StubEntryParser.new
7
+ @inst = ApacheCrunch::LogParser.new(@entry_parser)
8
+ end
9
+
10
+ def teardown
11
+ @inst = nil
12
+ end
13
+
14
+ # Tests setting the log file to a given file
15
+ def test_set_file
16
+ first_log_file = MockFile.new
17
+ assert_nothing_thrown("#{@inst.class}#set_file! threw an exception") do
18
+ @inst.set_file!(first_log_file)
19
+ end
20
+
21
+ second_log_file = MockFile.new
22
+ assert_nothing_thrown("#{@inst.class}#set_file! threw an exception") do
23
+ @inst.set_file!(second_log_file)
24
+ end
25
+ assert_equal(1, first_log_file.close_count,
26
+ "#{@inst.class}#set_file! didn't close old file")
27
+ end
28
+
29
+ # Tests replacing the log file with another file
30
+ def test_replace_file
31
+ mock_file_class = MockFileClass.new
32
+ @inst.dep_inject!(mock_file_class)
33
+
34
+ first_log_file = MockFile.new
35
+ first_log_file.path = "/first/path"
36
+ @inst.set_file!(first_log_file)
37
+
38
+ second_log_file = MockFile.new
39
+ second_log_file.path = "/second/path"
40
+ assert_nothing_thrown("#{@inst.class}#replace_file! threw an exception") do
41
+ @inst.replace_file!(second_log_file)
42
+ end
43
+ assert_equal([["/second/path", "/first/path"]], mock_file_class.rename_calls,
44
+ "#{@inst.class}#replace_file! didn't move the file into place")
45
+ assert_equal(1, first_log_file.close_count,
46
+ "#{@inst.class}#replace_file! didn't close old file")
47
+ end
48
+
49
+ # Tests resetting the log file to its beginning
50
+ def test_reset_file
51
+ mock_file_class = MockFileClass.new
52
+ @inst.dep_inject!(mock_file_class)
53
+
54
+ log_file = MockFile.new
55
+ @inst.set_file!(log_file)
56
+
57
+ assert_nothing_thrown("#{@inst.class}#reset_file! threw an exception") do
58
+ @inst.reset_file!
59
+ end
60
+ assert_equal(1, log_file.close_count,
61
+ "#{@inst.class}#reset_file! didn't close the log file")
62
+ assert_equal(1, mock_file_class.open_calls.length,
63
+ "#{@inst.class}#reset_file! didn't reopen the log file")
64
+ end
65
+
66
+ # Tests retrieving the next entry in the log
67
+ def test_next_entry
68
+ @entry_parser.parse_return_values = [
69
+ StubEntry.new,
70
+ StubEntry.new,
71
+ nil,
72
+ StubEntry.new
73
+ ]
74
+
75
+ log_file = MockFile.new
76
+ log_file.lines = ["a\n", "b\n", "c\n", "d\n"]
77
+
78
+ @inst.set_file!(log_file)
79
+ @inst.set_format!(StubFormat.new)
80
+ assert_instance_of(StubEntry, @inst.next_entry,
81
+ "#{@inst.class}#next_entry returned wrong type of thing")
82
+ assert_instance_of(StubEntry, @inst.next_entry,
83
+ "#{@inst.class}#next_entry returned wrong second value")
84
+ assert_instance_of(StubEntry, @inst.next_entry,
85
+ "#{@inst.class}#next_entry returned wrong value when it should have skipped a malformatted entry")
86
+ assert_nil(@inst.next_entry, "#{@inst.class}#next_entry returned non-nil at EOF")
87
+ end
88
+ end
@@ -0,0 +1,36 @@
1
+ require 'test/stub'
2
+
3
+ class TestRawValueFetcher < Test::Unit::TestCase
4
+ def setup
5
+ @inst = ApacheCrunch::RawValueFetcher.new
6
+ end
7
+
8
+ def teardown
9
+ @inst = nil
10
+ end
11
+
12
+ # Tests a successful fetch call
13
+ def test_fetch
14
+ entry = StubEntry.new
15
+ alnum_element = StubElement.new
16
+ alnum_element.populate!(StubAlphanumericFormatToken.new, "foo123")
17
+ num_element = StubElement.new
18
+ num_element.populate!(StubNumericFormatToken.new, 54321)
19
+
20
+ entry.captured_elements = {:alnum => alnum_element, :num => num_element}
21
+ assert_equal("foo123", @inst.fetch(entry, StubAlphanumericFormatToken.new.name))
22
+ assert_equal(54321, @inst.fetch(entry, StubNumericFormatToken.new.name))
23
+ end
24
+
25
+ # Tests a fetch call for an element that's not there
26
+ def test_fetch_missing
27
+ entry = StubEntry.new
28
+ alnum_element = StubElement.new
29
+ alnum_element.populate!(StubAlphanumericFormatToken.new, "foo123")
30
+ num_element = StubElement.new
31
+ num_element.populate!(StubNumericFormatToken.new, 54321)
32
+
33
+ entry.captured_elements = {:alnum => alnum_element, :num => num_element}
34
+ assert_nil(@inst.fetch(entry, :missing_element))
35
+ end
36
+ end
@@ -0,0 +1,17 @@
1
+ class TestReqheaderToken < Test::Unit::TestCase
2
+ def setup
3
+ @inst = ApacheCrunch::RegexToken.new
4
+ end
5
+
6
+ def teardown
7
+ @inst = nil
8
+ end
9
+
10
+ # Tests that the token figures out its name correctly from the header
11
+ def test_name
12
+ @inst.populate!("foobar", "[A-Za-z0-9]+")
13
+
14
+ assert_equal(:regex_foobar, @inst.name,
15
+ "#{@inst.class} got wrong name based on regex name 'foobar'")
16
+ end
17
+ end
@@ -0,0 +1,41 @@
1
+ require 'test/stub'
2
+
3
+ class TestReqFirstlineDerivationRule < Test::Unit::TestCase
4
+ def setup
5
+ @inst = ApacheCrunch::ReqFirstlineDerivationRule.new
6
+ end
7
+
8
+ def teardown
9
+ @inst = nil
10
+ end
11
+
12
+ def test_derive
13
+ expected_names = @inst.target_names
14
+ datasets = [
15
+ ["GET / HTTP/1.1", {:req_method => "GET",
16
+ :url_path => "/",
17
+ :query_string => "",
18
+ :protocol => "HTTP/1.1"}],
19
+ ["HEAD /?herp=derp&foo=bar HTTP/1.0", {:req_method => "HEAD",
20
+ :url_path => "/",
21
+ :query_string => "?herp=derp&foo=bar",
22
+ :protocol => "HTTP/1.0"}],
23
+ ["POST /some/page?never=gonna HTTP/1.1", {:req_method => "POST",
24
+ :url_path => "/some/page",
25
+ :query_string => "?never=gonna",
26
+ :protocol => "HTTP/1.1"}]
27
+ ]
28
+
29
+ expected_names = @inst.target_names
30
+ datasets.each do |ds|
31
+ firstline_value = ds[0]
32
+ expected_values = ds[1]
33
+
34
+ expected_names = [:req_method, :url_path, :query_string, :protocol]
35
+ expected_names.each do |name|
36
+ assert_equal(expected_values[name], @inst.derive(name, firstline_value),
37
+ "#{@inst.class}#derive returned wrong value for element '#{name}'")
38
+ end
39
+ end
40
+ end
41
+ end
@@ -0,0 +1,26 @@
1
+ class TestReqheaderToken < Test::Unit::TestCase
2
+ def setup
3
+ @inst = ApacheCrunch::ReqheaderToken.new
4
+ end
5
+
6
+ def teardown
7
+ @inst = nil
8
+ end
9
+
10
+ # Tests that the token figures out its name correctly from the header
11
+ def test_name
12
+ datasets = [
13
+ ['Host', :reqheader_host],
14
+ ['X-Two-Words', :reqheader_x_two_words]
15
+ ]
16
+
17
+ datasets.each do |ds|
18
+ header_name = ds[0]
19
+ expected_token_name = ds[1]
20
+
21
+ @inst.populate!(header_name)
22
+ assert_equal(expected_token_name, @inst.name,
23
+ "#{@inst.class} got wrong name based on header name '#{header_name}'")
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,27 @@
1
+ require 'test/stub'
2
+
3
+ class TestStringToken < Test::Unit::TestCase
4
+ def setup
5
+ @inst = ApacheCrunch::StringToken.new
6
+ end
7
+
8
+ def teardown
9
+ @inst = nil
10
+ end
11
+
12
+ def test_regex
13
+ datasets = [
14
+ [' ', '\ '],
15
+ [' {has (regex [chars', '\ \{has\ \(regex\ \[chars']
16
+ ]
17
+
18
+ datasets.each do |ds|
19
+ string_value = ds[0]
20
+ expected_regex = ds[1]
21
+
22
+ @inst.populate!(string_value)
23
+ assert_equal(expected_regex, @inst.regex,
24
+ "#{@inst.class}#regex returned incorrect value")
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,29 @@
1
+ require 'test/stub'
2
+
3
+ class TestTimeDerivationRule < Test::Unit::TestCase
4
+ def setup
5
+ @inst = ApacheCrunch::TimeDerivationRule.new
6
+ end
7
+
8
+ def teardown
9
+ @inst = nil
10
+ end
11
+
12
+ # Tests that the expected list of derived elements matches what actually gets derived
13
+ def test_derive
14
+ expected_names = [:year, :month, :day, :hour, :minute, :second]
15
+ expected_values = {
16
+ :year => 2011,
17
+ :month => 7,
18
+ :day => 15,
19
+ :hour => 9,
20
+ :minute => 55,
21
+ :second => 41
22
+ }
23
+
24
+ expected_names.each do |name|
25
+ assert_equal(expected_values[name], @inst.derive(name, "[15/Jul/2011:09:55:41 +0400]"),
26
+ "#{@inst.class}#derive_all returned incorrect value for element #{name}")
27
+ end
28
+ end
29
+ end
metadata CHANGED
@@ -1,12 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: apachecrunch
3
3
  version: !ruby/object:Gem::Version
4
- hash: 3
5
- prerelease:
6
- segments:
7
- - 0
8
- - 4
9
- version: "0.4"
4
+ version: "0.5"
10
5
  platform: ruby
11
6
  authors:
12
7
  - Dan Slimmon
@@ -14,7 +9,7 @@ autorequire:
14
9
  bindir: bin
15
10
  cert_chain: []
16
11
 
17
- date: 2011-07-12 00:00:00 -04:00
12
+ date: 2011-09-17 00:00:00 -04:00
18
13
  default_executable:
19
14
  dependencies: []
20
15
 
@@ -31,20 +26,36 @@ extra_rdoc_files: []
31
26
 
32
27
  files:
33
28
  - lib/apachecrunch.rb
29
+ - lib/cast.rb
34
30
  - lib/config.rb
31
+ - lib/derivation.rb
32
+ - lib/element.rb
33
+ - lib/element_value_fetcher.rb
35
34
  - lib/entry.rb
36
35
  - lib/format.rb
37
- - lib/log_element.rb
36
+ - lib/format_token.rb
37
+ - lib/format_token_definition.rb
38
38
  - lib/log_parser.rb
39
39
  - lib/procedure_dsl.rb
40
40
  - lib/progress.rb
41
41
  - bin/apachecrunch
42
42
  - LICENSE
43
+ - test/mock.rb
43
44
  - test/runner.rb
44
45
  - test/stub.rb
45
- - test/test_entry.rb
46
+ - test/test_derived_value_fetcher.rb
47
+ - test/test_element.rb
48
+ - test/test_element_value_fetcher.rb
49
+ - test/test_entry_parser.rb
46
50
  - test/test_format.rb
47
51
  - test/test_format_parser.rb
52
+ - test/test_log_parser.rb
53
+ - test/test_raw_value_fetcher.rb
54
+ - test/test_regex_token.rb
55
+ - test/test_req_firstline_derivation_rule.rb
56
+ - test/test_reqheader_token.rb
57
+ - test/test_string_token.rb
58
+ - test/test_time_derivation_rule.rb
48
59
  has_rdoc: true
49
60
  homepage: https://github.com/danslimmon/apachecrunch/
50
61
  licenses:
@@ -55,27 +66,21 @@ rdoc_options: []
55
66
  require_paths:
56
67
  - lib
57
68
  required_ruby_version: !ruby/object:Gem::Requirement
58
- none: false
59
69
  requirements:
60
70
  - - ">="
61
71
  - !ruby/object:Gem::Version
62
- hash: 3
63
- segments:
64
- - 0
65
72
  version: "0"
73
+ version:
66
74
  required_rubygems_version: !ruby/object:Gem::Requirement
67
- none: false
68
75
  requirements:
69
76
  - - ">="
70
77
  - !ruby/object:Gem::Version
71
- hash: 3
72
- segments:
73
- - 0
74
78
  version: "0"
79
+ version:
75
80
  requirements: []
76
81
 
77
82
  rubyforge_project:
78
- rubygems_version: 1.6.2
83
+ rubygems_version: 1.3.5
79
84
  signing_key:
80
85
  specification_version: 3
81
86
  summary: Apache log analysis tool designed for ease of use
data/lib/log_element.rb DELETED
@@ -1,351 +0,0 @@
1
- # Converts a string to an integer
2
- class IntegerCast
3
- def self.cast(string_value)
4
- string_value.to_i
5
- end
6
- end
7
-
8
-
9
- # Converts a CLF-formatted string to an integer
10
- #
11
- # "CLF-formatted" means that if the value is 0, the string will be a single hyphen instead of
12
- # a number. Like %b, for instance.
13
- class CLFIntegerCast
14
- def self.cast(string_value)
15
- if string_value == "-"
16
- return 0
17
- end
18
- string_value.to_i
19
- end
20
- end
21
-
22
-
23
- # An element in a log format. Abstract from which all elements inherit.
24
- #
25
- # Exposes:
26
- # abbrev: The Apache abbreviation for the element (such as "%h" or "%u" or "%{Referer}i")
27
- # name: A short name for the element (such as "remote_host", "remote_user", or "reqhead_referer")
28
- # regex: A regex that should match such an element ("[A-Za-z0-9.-]+", "[^:]+", ".+")
29
- #
30
- # If '_caster' is not nil, it should be a class with a method called "cast" that
31
- # transforms a string to the appropriate data type or format for consumption.
32
- # For example, the IntegerCast class transforms "562" to 562. The correct cast
33
- # of a string can then be performed by passing that string to this LogFormaElement
34
- # instance's "cast" method.
35
- #
36
- # 'derive_elements' manages elements that can be derived from the instance's value. See
37
- # ReqFirstlineElement for an example.
38
- class LogFormatElement
39
- @_caster = nil
40
-
41
- attr_accessor :abbrev, :name, :regex
42
- # Class variables that determine the _default_ for abbrev, name, and regex in an instance.
43
- # That is, an instance will initialize with these values for the instance variables @abbrev,
44
- # @name, and @regex.
45
- class << self; attr_accessor :abbrev, :name, :regex end
46
- # Additionally we need to access this from within the instance:
47
- class << self; attr_accessor :_caster end
48
-
49
- def initialize
50
- @abbrev = self.class.abbrev
51
- @name = self.class.name
52
- @regex = self.class.regex
53
- end
54
-
55
- # Casts a string found in the log to the correct type, using the class's @_caster attribute.
56
- def cast(string_value)
57
- if _caster.nil?
58
- return string_value
59
- else
60
- return _caster.cast(string_value)
61
- end
62
- end
63
-
64
- # Derives the named element (e.g. "url_path") from a given value for this one.
65
- #
66
- # See ReqFirstlineElement for an example.
67
- def self.derive(name, our_own_value)
68
- raise NotImplementedError
69
- end
70
-
71
- # Returns a list of the element classes that can be derived from this one.
72
- #
73
- # See ReqFirstlineElement for an example.
74
- def derived_elements
75
- []
76
- end
77
- end
78
-
79
-
80
- class RemoteHostElement < LogFormatElement
81
- @abbrev = "%h"
82
- @name = :remote_host
83
- @regex = %q![A-Za-z0-9.-]+!
84
- end
85
-
86
-
87
- class LogNameElement < LogFormatElement
88
- @abbrev = "%l"
89
- @name = :log_name
90
- @regex = %q!\S+!
91
- end
92
-
93
-
94
- class RemoteUserElement < LogFormatElement
95
- @abbrev = "%u"
96
- @name = :remote_user
97
- @regex = %q![^:]+!
98
- end
99
-
100
-
101
- class TimeElement < LogFormatElement
102
- @abbrev = "%t"
103
- @name = :time
104
- @regex = %q!\[\d\d/[A-Za-z]{3}/\d\d\d\d:\d\d:\d\d:\d\d [-+]\d\d\d\d\]!
105
-
106
- @_derivation_regex = nil
107
- @_month_map = {"Jan" => 1, "Feb" => 2, "Mar" => 3, "Apr" => 4, "May" => 5, "Jun" => 6,
108
- "Jul" => 7, "Aug" => 8, "Sep" => 9, "Oct" => 10, "Nov" => 11, "Dec" => 12}
109
-
110
- def self.derive(name, our_own_value)
111
- if @_derivation_regex.nil?
112
- @_derivation_regex = Regexp.compile(%q!^\[(\d\d)/([A-Za-z]{3})/(\d\d\d\d):(\d\d):(\d\d):(\d\d)!)
113
- end
114
-
115
- hsh = {}
116
- if our_own_value =~ @_derivation_regex
117
- hsh[:year] = $3.to_i
118
- hsh[:month] = @_month_map[$2]
119
- hsh[:day] = $1.to_i
120
-
121
- hsh[:hour] = $4.to_i
122
- hsh[:minute] = $5.to_i
123
- hsh[:second] = $6.to_i
124
- end
125
-
126
- hsh[name]
127
- end
128
-
129
- def derived_elements
130
- [YearElement, MonthElement, DayElement, HourElement, MinuteElement, SecondElement]
131
- end
132
- end
133
-
134
-
135
- # Elements derived from TimeElement
136
- class YearElement < LogFormatElement
137
- @name = :year
138
- @regex = %q!\d{4}!
139
- end
140
- class MonthElement < LogFormatElement
141
- @name = :month
142
- @regex = %q![A-Za-z]{3}!
143
- end
144
- class DayElement < LogFormatElement
145
- @name = :day
146
- @regex = %q!\d{2}!
147
- end
148
- class HourElement < LogFormatElement
149
- @name = :hour
150
- @regex = %q!\d{2}!
151
- end
152
- class MinuteElement < LogFormatElement
153
- @name = :minute
154
- @regex = %q!\d{2}!
155
- end
156
- class SecondElement < LogFormatElement
157
- @name = :second
158
- @regex = %q!\d{2}!
159
- end
160
-
161
-
162
- class ReqFirstlineElement < LogFormatElement
163
- @abbrev = "%r"
164
- @name = :req_firstline
165
- @regex = %q![^"]+!
166
-
167
- @_derivation_regex = nil
168
-
169
- def self.derive(name, our_own_value)
170
- if @_derivation_regex.nil?
171
- @_derivation_regex = Regexp.compile("^(#{ReqMethodElement.regex})\s+(#{UrlPathElement.regex})(#{QueryStringElement.regex})\s+(#{ProtocolElement.regex})$")
172
- end
173
-
174
- hsh = {}
175
- if our_own_value =~ @_derivation_regex
176
- hsh[ReqMethodElement.name] = $1
177
- hsh[UrlPathElement.name] = $2
178
- hsh[QueryStringElement.name] = $3
179
- hsh[ProtocolElement.name] = $4
180
- end
181
-
182
- hsh[name]
183
- end
184
-
185
- def derived_elements
186
- return [ReqMethodElement, UrlPathElement, QueryStringElement, ProtocolElement]
187
- end
188
- end
189
-
190
-
191
- class StatusElement < LogFormatElement
192
- @abbrev = "%s"
193
- @name = :status
194
- @regex = %q!\d+|-!
195
- end
196
-
197
-
198
- class BytesSentElement < LogFormatElement
199
- @abbrev = "%b"
200
- @name = :bytes_sent
201
- @regex = %q!\d+!
202
-
203
- @@_caster = IntegerCast
204
- end
205
-
206
-
207
- class BytesSentElement < LogFormatElement
208
- @abbrev = "%b"
209
- @name = :bytes_sent
210
- @regex = %q![\d-]+!
211
-
212
- @_caster = CLFIntegerCast
213
- end
214
-
215
-
216
- class BytesSentWithHeadersElement < LogFormatElement
217
- @abbrev = "%O"
218
- @name = :bytes_sent_with_headers
219
- @regex = %q!\d+!
220
-
221
- @_caster = IntegerCast
222
- end
223
-
224
-
225
- class ServeTimeMicroElement < LogFormatElement
226
- @abbrev = "%D"
227
- @name = :serve_time_micro
228
- @regex = %q!\d+!
229
-
230
- @_caster = IntegerCast
231
- end
232
-
233
-
234
- class UrlPathElement < LogFormatElement
235
- @abbrev = "%U"
236
- @name = :url_path
237
- @regex = %q!/[^?]*!
238
- end
239
-
240
-
241
- class QueryStringElement < LogFormatElement
242
- @abbrev = "%q"
243
- @name = :query_string
244
- @regex = %q!\??\S*!
245
- end
246
-
247
-
248
- class ReqMethodElement < LogFormatElement
249
- @abbrev = "%m"
250
- @name = :req_method
251
- @regex = %q![A-Z]+!
252
- end
253
-
254
-
255
- class ProtocolElement < LogFormatElement
256
- @abbrev = "%H"
257
- @name = :protocol
258
- @regex = %q!\S+!
259
- end
260
-
261
-
262
- class ReqheaderElement < LogFormatElement
263
- end
264
-
265
-
266
- class RegexElement < LogFormatElement
267
- end
268
-
269
-
270
- # Finds log format elements given information about them.
271
- class ElementDictionary
272
- @@_ELEMENTS = [
273
- RemoteHostElement,
274
- LogNameElement,
275
- RemoteUserElement,
276
- TimeElement,
277
- ReqFirstlineElement,
278
- StatusElement,
279
- BytesSentElement,
280
- BytesSentElement,
281
- BytesSentWithHeadersElement,
282
- ServeTimeMicroElement,
283
- UrlPathElement,
284
- QueryStringElement,
285
- ReqMethodElement,
286
- ProtocolElement
287
- ]
288
-
289
- # Returns the LogFormatElement subclass with the given format-string abbreviation.
290
- #
291
- # If none exists, returns nil.
292
- def self.find_by_abbrev(abbrev)
293
- @@_ELEMENTS.each do |element|
294
- if element.abbrev == abbrev
295
- return element
296
- end
297
- end
298
-
299
- nil
300
- end
301
- end
302
-
303
-
304
- # Generates LogFormatElement instances.
305
- #
306
- # This class does the work of figuring out which LogFormatElement subclass to make and makes it.
307
- class LogFormatElementFactory
308
- # Takes an Apache log format abbreviation and returns a corresponding LogFormatElement
309
- def from_abbrev(abbrev)
310
- element_cls = ElementDictionary.find_by_abbrev(abbrev)
311
- if element_cls
312
- # We found it in the dictionary, so just return an instance
313
- return element_cls.new
314
- elsif abbrev =~ /^%\{([A-Za-z0-9-]+)\}i/
315
- # HTTP request header
316
- return _reqheader_element(abbrev, $1)
317
- elsif abbrev =~ /^%\{(.*?):([^}]+)\}r/
318
- # Arbitrary regex
319
- return _regex_element(abbrev, $1, $2)
320
- end
321
-
322
- raise "Unknown element format '#{abbrev}'"
323
- end
324
-
325
- # Returns a format element based on an HTTP header
326
- def _reqheader_element(abbrev, header_name)
327
- element = ReqheaderElement.new
328
-
329
- element.abbrev = abbrev
330
- element.regex = %q![^"]*!
331
- element.name = _header_name_to_element_name(header_name)
332
-
333
- element
334
- end
335
-
336
- # Returns a format element based on an arbitrary regex
337
- def _regex_element(abbrev, regex_name, regex)
338
- element = RegexElement.new
339
-
340
- element.abbrev = abbrev
341
- element.regex = regex
342
- element.name = "regex_#{regex_name}".to_sym
343
-
344
- element
345
- end
346
-
347
- # Lowercases header name and turns hyphens into underscores
348
- def _header_name_to_element_name(header_name)
349
- ("reqheader_" + header_name.downcase().gsub("-", "_")).to_sym
350
- end
351
- end