logstash-filter-useragent 3.2.2-java → 3.3.2-java

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,105 +1,448 @@
1
1
  # encoding: utf-8
2
-
3
2
  require "logstash/devutils/rspec/spec_helper"
3
+ require 'logstash/plugin_mixins/ecs_compatibility_support/spec_helper'
4
4
  require "logstash/filters/useragent"
5
5
 
6
6
  describe LogStash::Filters::UserAgent do
7
7
 
8
- describe "defaults" do
9
- config <<-CONFIG
10
- filter {
11
- useragent {
12
- source => "message"
13
- target => "ua"
8
+ subject { LogStash::Filters::UserAgent.new(options) }
9
+
10
+ let(:options) { { 'source' => 'message' } }
11
+ let(:message) { "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/45.0.2454.85 Safari/537.36" }
12
+
13
+ let(:event) { LogStash::Event.new('message' => message) }
14
+
15
+ context 'with target', :ecs_compatibility_support do
16
+ ecs_compatibility_matrix(:disabled, :v1, :v8 => :v1) do |ecs_select|
17
+
18
+ let(:ecs_compatibility?) { ecs_select.active_mode != :disabled }
19
+
20
+ before(:each) do
21
+ allow_any_instance_of(described_class).to receive(:ecs_compatibility).and_return(ecs_compatibility)
22
+ end
23
+
24
+ config <<-CONFIG
25
+ filter {
26
+ useragent {
27
+ source => "message"
28
+ target => "ua"
29
+ }
14
30
  }
15
- }
16
- CONFIG
31
+ CONFIG
32
+
33
+ sample "Mozilla/5.0 (X11; Linux i686) AppleWebKit/537.31 (KHTML, like Gecko) Chrome/26.0.1410.63 Safari/537.31" do
34
+ expect( subject.to_hash ).to include("ua")
35
+ expect( subject.get("[ua][name]") ).to eql "Chrome"
36
+ if ecs_compatibility?
37
+ expect( subject.get("[ua][os][name]") ).to eql "Linux"
38
+ expect( subject.get("[ua][os][full]") ).to eql "Linux"
39
+ expect( subject.get("[ua][device][name]") ).to eql "Other"
40
+ ua_metadata = subject.get("[@metadata][filter][user_agent]")
41
+ expect( ua_metadata ).to include 'version' => { 'major' => '26', 'minor' => '0', 'patch' => '1410' }
42
+ expect( subject.get("[ua][version]") ).to eql "26.0.1410.63"
43
+ expect( subject.get("[ua]").keys ).to_not include 'major'
44
+ expect( subject.get("[ua]").keys ).to_not include 'minor'
45
+ else
46
+ expect( subject.get("[ua][os_name]") ).to eql "Linux"
47
+ expect( subject.get("[ua][os_full]") ).to eql "Linux"
48
+ expect( subject.get("[ua][os]") ).to eql "Linux"
49
+ expect( subject.get("[ua][device]") ).to eql "Other"
50
+ expect( subject.get("[ua][major]") ).to eql "26"
51
+ expect( subject.get("[ua][minor]") ).to eql "0"
52
+ end
53
+
54
+ expect( subject.get("[ua][name]").encoding ).to eql Encoding::UTF_8
55
+ end
56
+
57
+ sample "MacOutlook/16.24.0.190414 (Intelx64 Mac OS X Version 10.14.4 (Build 18E226))" do
58
+ expect( subject.to_hash ).to include("ua")
59
+ expect( subject.get("[ua][name]") ).to eql "MacOutlook"
60
+ if ecs_compatibility?
61
+ expect( subject.get("[ua][version]") ).to eql "16.24.0.190414"
62
+ expect( subject.get("[ua][os][full]") ).to eql "Mac OS X 10.14.4"
63
+ expect( subject.get("[ua][os][name]") ).to eql "Mac OS X"
64
+ expect( subject.get("[ua][os][version]") ).to eql '10.14.4'
65
+ expect( subject.get("[ua][device][name]") ).to eql 'Mac'
66
+
67
+ expect( subject.get("[ua][os][name]").encoding ).to eql Encoding::UTF_8
68
+ else
69
+ expect( subject.get("[ua][major]") ).to eql "16"
70
+ expect( subject.get("[ua][minor]") ).to eql "24"
71
+ expect( subject.get("[ua][patch]") ).to eql "0"
72
+ expect( subject.get("[ua][os_full]") ).to eql "Mac OS X 10.14.4"
73
+ expect( subject.get("[ua][os_name]") ).to eql "Mac OS X"
74
+ expect( subject.get("[ua][os_major]") ).to eql '10'
75
+ expect( subject.get("[ua][os_minor]") ).to eql '14'
76
+ expect( subject.get("[ua][device]") ).to eql 'Mac'
77
+
78
+ expect( subject.get("[ua][os]") ).to eql "Mac OS X"
79
+ expect( subject.get("[ua][os]").encoding ).to eql Encoding::UTF_8
80
+ end
81
+ end
82
+
83
+ # Safari 12 on Mojave
84
+ sample "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/12.0 Safari/605.1.15" do
85
+ expect( subject.to_hash ).to include("ua")
86
+ expect( subject.get("[ua][name]") ).to eql "Safari"
87
+ if ecs_compatibility?
88
+ expect( subject.get("[ua][version]") ).to eql "12.0"
89
+ expect( subject.get("[ua][os][full]") ).to eql "Mac OS X 10.14"
90
+ expect( subject.get("[ua][os][name]") ).to eql "Mac OS X"
91
+ expect( subject.get("[ua][os][version]") ).to eql '10.14'
92
+ ua_metadata = subject.get("[@metadata][filter][user_agent][os]")
93
+ expect( ua_metadata ).to include 'version' => { 'major' => '10', 'minor' => '14' }
94
+
95
+ expect( subject.get("[@metadata][filter][user_agent][os][version][major]").encoding ).to eql Encoding::UTF_8
96
+ else
97
+ expect( subject.get("[ua][major]") ).to eql "12"
98
+ expect( subject.get("[ua][minor]") ).to eql "0"
99
+ expect( subject.get("[ua][patch]") ).to be nil
100
+ expect( subject.get("[ua][os_full]") ).to eql "Mac OS X 10.14"
101
+ expect( subject.get("[ua][os_name]") ).to eql "Mac OS X"
102
+ expect( subject.get("[ua][os_major]") ).to eql '10'
103
+ expect( subject.get("[ua][os_minor]") ).to eql '14'
104
+
105
+ expect( subject.get("[ua][os_major]").encoding ).to eql Encoding::UTF_8
106
+ end
107
+ end
108
+
109
+ # Safari 7 on Mac OS X (Mavericks)
110
+ sample "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_9_3) AppleWebKit/537.75.14 (KHTML, like Gecko) Version/7.0.3 Safari/7046A194A" do
111
+ expect( subject.to_hash ).to include("ua")
112
+ expect( subject.get("[ua][name]") ).to eql "Safari"
113
+ if ecs_compatibility?
114
+ expect( subject.get("[ua][version]") ).to eql "7.0.3"
115
+ expect( subject.get("[ua][os][full]") ).to eql "Mac OS X 10.9.3"
116
+ expect( subject.get("[ua][os][name]") ).to eql "Mac OS X"
117
+ expect( subject.get("[ua][device][name]") ).to eql 'Mac'
118
+ else
119
+ expect( subject.get("[ua][major]") ).to eql "7"
120
+ expect( subject.get("[ua][minor]") ).to eql "0"
121
+ expect( subject.get("[ua][patch]") ).to eql "3"
122
+ expect( subject.get("[ua][os_full]") ).to eql "Mac OS X 10.9.3"
123
+ expect( subject.get("[ua][os_name]") ).to eql "Mac OS X"
124
+ expect( subject.get("[ua][os_major]") ).to eql '10'
125
+ expect( subject.get("[ua][os_minor]") ).to eql '9'
126
+ expect( subject.get("[ua][device]") ).to eql 'Mac'
127
+ end
128
+ end
129
+
130
+ sample "Mozilla/5.0 (Macintosh; Intel Mac OS X 10.11; rv:45.0) Gecko/20100101 Firefox/45.0" do
131
+ expect( subject.to_hash ).to include("ua")
132
+ expect( subject.get("[ua][name]") ).to eql "Firefox"
133
+ if ecs_compatibility?
134
+ expect( subject.get("[ua][version]") ).to eql "45.0"
135
+ expect( subject.get("[ua][os][full]") ).to eql "Mac OS X 10.11"
136
+ expect( subject.get("[ua][os][name]") ).to eql "Mac OS X"
137
+ expect( subject.get("[ua][os][version]") ).to eql '10.11'
138
+ expect( subject.get("[ua][device][name]") ).to eql 'Mac'
139
+ else
140
+ expect( subject.get("[ua][major]") ).to eql "45"
141
+ expect( subject.get("[ua][minor]") ).to eql "0"
142
+ expect( subject.get("[ua][patch]") ).to be nil
143
+ expect( subject.get("[ua][os_full]") ).to eql "Mac OS X 10.11"
144
+ expect( subject.get("[ua][os_name]") ).to eql "Mac OS X"
145
+ expect( subject.get("[ua][os_major]") ).to eql '10'
146
+ expect( subject.get("[ua][os_minor]") ).to eql '11'
147
+ expect( subject.get("[ua][device]") ).to eql 'Mac'
148
+ end
149
+ end
150
+
151
+ # IE7 Vista
152
+ sample "Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.0)" do
153
+ expect( subject.to_hash ).to include("ua")
154
+ if ecs_compatibility?
155
+ expect( subject.get("[ua][os][name]") ).to eql "Windows"
156
+ expect( subject.get("[ua][os][version]") ).to eql 'Vista'
157
+ expect( subject.get("[ua][device][name]") ).to eql 'Other'
158
+
159
+ expect( subject.get("[ua][device][name]").encoding ).to eql Encoding::UTF_8
160
+ else
161
+ expect( subject.get("[ua][os_name]") ).to eql "Windows"
162
+ expect( subject.get("[ua][os_major]") ).to eql 'Vista'
163
+ expect( subject.get("[ua][os_minor]") ).to be nil
164
+ expect( subject.get("[ua][device]") ).to eql 'Other'
165
+
166
+ expect( subject.get("[ua][device]").encoding ).to eql Encoding::UTF_8
167
+ end
168
+ end
169
+
170
+ # IE8 XP
171
+ sample "Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 5.1; Trident/4.0; .NET CLR 1.1.4322; .NET CLR 2.0.50727; .NET CLR 3.5.30729)" do
172
+ expect( subject.to_hash ).to include("ua")
173
+ expect( subject.get("[ua][name]") ).to eql 'IE'
174
+ if ecs_compatibility?
175
+ expect( subject.get("[ua][os][name]") ).to eql 'Windows'
176
+ expect( subject.get("[ua][os][version]") ).to eql 'XP'
177
+ expect( subject.get("[ua][device][name]") ).to eql 'Other'
178
+ else
179
+ expect( subject.get("[ua][os_name]") ).to eql 'Windows'
180
+ expect( subject.get("[ua][os_major]") ).to eql 'XP'
181
+ expect( subject.get("[ua][os_minor]") ).to be nil
182
+ expect( subject.get("[ua][device]") ).to eql 'Other'
183
+ end
184
+ end
185
+
186
+ # # Windows 8.1
187
+ sample "Mozilla/5.0 (Windows NT 6.3; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/42.0.2311.135 Safari/537.36 Edge/12.246" do
188
+ expect( subject.to_hash ).to include("ua")
189
+ expect( subject.get("[ua][name]") ).to eql 'Edge'
190
+ if ecs_compatibility?
191
+ expect( subject.get("[ua][os][name]") ).to eql 'Windows'
192
+ expect( subject.get("[ua][os][version]") ).to eql '8.1'
193
+ else
194
+ expect( subject.get("[ua][os_name]") ).to eql 'Windows'
195
+ expect( subject.get("[ua][os_major]") ).to eql '8'
196
+ expect( subject.get("[ua][os_minor]") ).to eql '1'
197
+ end
198
+ end
199
+
200
+ # Windows 10
201
+ sample "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/89.0.4389.90 Safari/537.36 Edg/89.0.774.50" do
202
+ expect( subject.to_hash ).to include("ua")
203
+ expect( subject.get("[ua][name]") ).to eql "Edge"
204
+ if ecs_compatibility?
205
+ expect( subject.get("[ua][version]") ).to eql "89.0.774.50"
206
+ expect( subject.get("[ua][os][full]") ).to eql "Windows 10"
207
+ expect( subject.get("[ua][os][name]") ).to eql "Windows"
208
+ expect( subject.get("[ua][os][version]") ).to eql '10'
209
+ ua_metadata = subject.get("[@metadata][filter][user_agent][os]")
210
+ expect( ua_metadata ).to include 'version' => { 'major' => '10' }
211
+ expect( subject.get("[ua][device][name]") ).to eql 'Other'
212
+ else
213
+ expect( subject.get("[ua][os_name]") ).to eql "Windows"
214
+ expect( subject.get("[ua][os_major]") ).to eql '10'
215
+ expect( subject.get("[ua][os_minor]") ).to be nil
216
+ expect( subject.get("[ua][device]") ).to eql 'Other'
217
+ end
218
+ end
219
+
220
+ # Chrome on Linux
221
+ sample "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/89.0.4389.90 Safari/537.36" do
222
+ expect( subject.to_hash ).to include("ua")
223
+ expect( subject.get("[ua][name]") ).to eql 'Chrome'
224
+ if ecs_compatibility?
225
+ expect( subject.get("[ua][os][name]") ).to eql "Linux"
226
+ expect( subject.get("[ua][os][version]") ).to be nil
227
+ expect( subject.get("[ua][device][name]") ).to eql 'Other'
228
+ else
229
+ expect( subject.get("[ua][os_name]") ).to eql "Linux"
230
+ expect( subject.get("[ua][os_major]") ).to be nil
231
+ expect( subject.get("[ua][os_minor]") ).to be nil
232
+ expect( subject.get("[ua][device]") ).to eql 'Other'
233
+ end
234
+ end
17
235
 
18
- sample "Mozilla/5.0 (X11; Linux i686) AppleWebKit/537.31 (KHTML, like Gecko) Chrome/26.0.1410.63 Safari/537.31" do
19
- insist { subject }.include?("ua")
20
- insist { subject.get("[ua][name]") } == "Chrome"
21
- insist { subject.get("[ua][os]") } == "Linux"
22
- insist { subject.get("[ua][major]") } == "26"
23
- insist { subject.get("[ua][minor]") } == "0"
24
236
  end
25
237
  end
26
238
 
27
- describe "manually specified regexes file" do
28
- config <<-CONFIG
29
- filter {
30
- useragent {
31
- source => "message"
32
- target => "ua"
33
- regexes => "build/resources/main/regexes.yaml"
239
+ context "manually specified regexes file", :ecs_compatibility_support do
240
+ ecs_compatibility_matrix(:disabled, :v1, :v8 => :v1) do |ecs_select|
241
+
242
+ let(:ecs_compatibility?) { ecs_select.active_mode != :disabled }
243
+
244
+ before(:each) do
245
+ allow_any_instance_of(described_class).to receive(:ecs_compatibility).and_return(ecs_compatibility)
246
+ end
247
+
248
+ config <<-CONFIG
249
+ filter {
250
+ useragent {
251
+ source => "message"
252
+ target => "[ua]"
253
+ regexes => "build/resources/main/regexes.yaml"
254
+ }
34
255
  }
35
- }
36
- CONFIG
256
+ CONFIG
257
+
258
+ sample "Mozilla/5.0 (X11; Linux i686) AppleWebKit/537.31 (KHTML, like Gecko) Chrome/26.0.1410.63 Safari/537.31" do
259
+ expect( subject.to_hash ).to include("ua")
260
+ if ecs_compatibility?
261
+ expect( subject.get("[ua][name]") ).to eql "Chrome"
262
+ expect( subject.get("[ua][os][name]") ).to eql "Linux"
263
+ expect( subject.get("[ua][version]") ).to eql "26.0.1410.63"
264
+ expect( subject.get("[@metadata][filter][user_agent][version][major]") ).to eql "26"
265
+ expect( subject.get("[@metadata][filter][user_agent][version][minor]") ).to eql "0"
266
+ else
267
+ expect( subject.get("[ua][name]") ).to eql "Chrome"
268
+ expect( subject.get("[ua][os]") ).to eql "Linux"
269
+ expect( subject.get("[ua][major]") ).to eql "26"
270
+ expect( subject.get("[ua][minor]") ).to eql "0"
271
+ end
272
+ end
37
273
 
38
- sample "Mozilla/5.0 (X11; Linux i686) AppleWebKit/537.31 (KHTML, like Gecko) Chrome/26.0.1410.63 Safari/537.31" do
39
- insist { subject }.include?("ua")
40
- insist { subject.get("[ua][name]") } == "Chrome"
41
- insist { subject.get("[ua][os]") } == "Linux"
42
- insist { subject.get("[ua][major]") } == "26"
43
- insist { subject.get("[ua][minor]") } == "0"
44
274
  end
45
275
  end
46
-
47
- describe "Without target field" do
48
- config <<-CONFIG
49
- filter {
50
- useragent {
51
- source => "message"
276
+
277
+ context "without target field", :ecs_compatibility_support do
278
+ ecs_compatibility_matrix(:disabled, :v1, :v8 => :v1) do |ecs_select|
279
+
280
+ let(:ecs_compatibility?) { ecs_select.active_mode != :disabled }
281
+
282
+ before(:each) do
283
+ allow_any_instance_of(described_class).to receive(:ecs_compatibility).and_return(ecs_compatibility)
284
+ end
285
+
286
+ config <<-CONFIG
287
+ filter {
288
+ useragent {
289
+ source => "message"
290
+ }
52
291
  }
53
- }
54
- CONFIG
292
+ CONFIG
293
+
294
+ sample "Mozilla/5.0 (X11; Linux i686) AppleWebKit/537.31 (KHTML, like Gecko) Chrome/26.0.1410.63 Safari/537.31" do
295
+ if ecs_compatibility? # [user_agent] default target in ECS
296
+ expect( subject.get("user_agent") ).to include 'name' => 'Chrome'
297
+ expect( subject.get("user_agent") ).to include 'os' => hash_including('name' => 'Linux')
298
+ expect( subject.get("user_agent") ).to include 'version' => '26.0.1410.63'
299
+ else
300
+ expect( subject.get("name") ).to eql "Chrome"
301
+ expect( subject.get("os_name") ).to eql "Linux"
302
+ expect( subject.get("os") ).to eql "Linux"
303
+ expect( subject.get("major") ).to eql "26"
304
+ expect( subject.get("minor") ).to eql "0"
305
+ expect( subject.get("patch") ).to eql "1410"
306
+ expect( subject.get("version") ).to eql "26.0.1410.63"
307
+ end
308
+ end
309
+ end
310
+ end
311
+
312
+ context "nested target field", :ecs_compatibility_support do
313
+ ecs_compatibility_matrix(:disabled, :v1, :v8 => :v1) do
314
+
315
+ before(:each) do
316
+ allow_any_instance_of(described_class).to receive(:ecs_compatibility).and_return(ecs_compatibility)
317
+ end
318
+
319
+ config <<-CONFIG
320
+ filter {
321
+ useragent {
322
+ source => "message"
323
+ target => "[foo][bar]"
324
+ }
325
+ }
326
+ CONFIG
327
+
328
+ # Facebook App User Agent
329
+ sample "Mozilla/5.0 (iPhone; CPU iPhone OS 13_3_1 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) " +
330
+ "Mobile/15E148 [FBAN/FBIOS;FBDV/iPhone11,8;FBMD/iPhone;FBSN/iOS;FBSV/13.3.1;FBSS/2;FBID/phone;FBLC/en_US;FBOP/5;FBCR/]" do
331
+ expect( subject ).to include 'foo'
332
+ expect( subject.get('foo') ).to include 'bar'
333
+ expect( subject.get('foo')['bar'] ).to include "name" => "Facebook"
334
+ end
335
+
336
+ end
337
+ end
338
+
339
+ context "without user agent", :ecs_compatibility_support do
340
+ ecs_compatibility_matrix(:disabled, :v1, :v8 => :v1) do |ecs_select|
341
+
342
+ let(:ecs_compatibility?) { ecs_select.active_mode != :disabled }
343
+
344
+ before(:each) do
345
+ allow_any_instance_of(described_class).to receive(:ecs_compatibility).and_return(ecs_compatibility)
346
+ end
347
+
348
+ config <<-CONFIG
349
+ filter {
350
+ useragent {
351
+ source => "message"
352
+ target => "ua"
353
+ }
354
+ }
355
+ CONFIG
356
+
357
+ sample "foo" => "bar" do
358
+ expect( subject.to_hash ).to_not include("ua")
359
+ end
360
+
361
+ sample "" do
362
+ expect( subject.to_hash ).to_not include("ua")
363
+ end
55
364
 
56
- sample "Mozilla/5.0 (X11; Linux i686) AppleWebKit/537.31 (KHTML, like Gecko) Chrome/26.0.1410.63 Safari/537.31" do
57
- insist { subject.get("name") } == "Chrome"
58
- insist { subject.get("os") } == "Linux"
59
- insist { subject.get("major") } == "26"
60
- insist { subject.get("minor") } == "0"
61
365
  end
62
366
  end
63
367
 
64
- describe "Without user agent" do
368
+ describe "non-exact UA data" do
65
369
  config <<-CONFIG
66
370
  filter {
67
371
  useragent {
68
372
  source => "message"
69
- target => "ua"
373
+ target => "user_agent"
70
374
  }
71
375
  }
72
376
  CONFIG
73
377
 
74
- sample "foo" => "bar" do
75
- reject { subject }.include?("ua")
378
+ sample 'Prefix DATA! Mozilla/5.0 (Android 11; Mobile; rv:68.0) Gecko/68.0 Firefox/86.0' do
379
+ expect( subject.to_hash ).to include("user_agent")
380
+ expect( subject.get('user_agent') ).to include "name" => "Firefox Mobile", "version" => '86.0', "os_name" => "Android"
76
381
  end
77
382
 
78
- sample "" do
79
- reject { subject }.include?("ua")
383
+ end
384
+
385
+ context "with prefix", :ecs_compatibility_support do
386
+ ecs_compatibility_matrix(:disabled, :v1, :v8 => :v1) do |ecs_select|
387
+
388
+ let(:message) { 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:78.0) Gecko/20100101 Firefox/78.0' }
389
+ let(:options) { super().merge('prefix' => 'pre_') }
390
+
391
+ before(:each) do
392
+ allow_any_instance_of(described_class).to receive(:ecs_compatibility).and_return(ecs_compatibility)
393
+ end
394
+
395
+ it 'works in legacy mode with prefix (without a warning)' do
396
+ expect( subject.logger ).to_not receive(:warn)
397
+ subject.register
398
+
399
+ subject.filter(event)
400
+
401
+ expect( event.to_hash ).to include('pre_name' => 'Firefox', 'pre_version' => '78.0')
402
+ end if ecs_select.active_mode == :disabled
403
+
404
+ it 'warns in ECS mode (and ignores prefix)' do
405
+ expect( subject.logger ).to receive(:warn).with %r{Field prefix isn't supported in ECS compatibility mode}
406
+ subject.register
407
+
408
+ subject.filter(event)
409
+
410
+ expect( event.to_hash.keys.find { |key| key.index('pre_') } ).to be nil
411
+ expect( event.get('user_agent').keys.find { |key| key.index('pre_') } ).to be nil
412
+ expect( event.get('user_agent') ).to include('name' => 'Firefox', 'version' => '78.0')
413
+ end if ecs_select.active_mode != :disabled
414
+
80
415
  end
81
416
  end
82
417
 
83
- describe "LRU object identity" do
84
- let(:ua_string) { "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/45.0.2454.85 Safari/537.36" }
85
- let(:uafilter) { LogStash::Filters::UserAgent.new("source" => "foo") }
86
- let(:ua_data) { uafilter.lookup_useragent(ua_string) }
418
+ context "no prefix", :ecs_compatibility_support do
419
+ ecs_compatibility_matrix(:disabled, :v1, :v8 => :v1) do
87
420
 
88
- subject(:target) { LogStash::Event.new("foo" => ua_string) }
421
+ let(:message) { 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:78.0) Gecko/20100101 Firefox/78.0' }
89
422
 
90
- before do
91
- uafilter.register
423
+ before(:each) do
424
+ allow_any_instance_of(described_class).to receive(:ecs_compatibility).and_return(ecs_compatibility)
425
+ end
426
+
427
+ it 'does not warn' do
428
+ expect( subject.logger ).to_not receive(:warn)
429
+ subject.register
430
+ end
92
431
 
93
- # Stub this out because this UA doesn't have this field
94
- allow(ua_data.userAgent).to receive(:patchMinor).and_return("foo")
432
+ end
433
+ end
434
+
435
+ describe "LRU object identity" do
95
436
 
96
- # expect(event).receive(:lookup_useragent)
97
- uafilter.filter(target)
437
+ let(:ua_data) { subject.send :lookup_useragent, message }
438
+
439
+ before do
440
+ subject.register
441
+ subject.filter(event)
98
442
  end
99
443
 
100
444
  {
101
445
  "name" => lambda {|uad| uad.userAgent.family},
102
- "os" => lambda {|uad| uad.os.family},
103
446
  "os_name" => lambda {|uad| uad.os.family},
104
447
  "os_major" => lambda {|uad| uad.os.major},
105
448
  "os_minor" => lambda {|uad| uad.os.minor},
@@ -107,11 +450,10 @@ describe LogStash::Filters::UserAgent do
107
450
  "major" => lambda {|uad| uad.userAgent.major},
108
451
  "minor" => lambda {|uad| uad.userAgent.minor},
109
452
  "patch" => lambda {|uad| uad.userAgent.patch},
110
- "build" => lambda {|uad| uad.userAgent.patchMinor}
111
453
  }.each do |field, uad_getter|
112
454
  context "for the #{field} field" do
113
- let(:value) {uad_getter.call(ua_data)}
114
- let(:target_field) { target.get(field)}
455
+ let(:value) { uad_getter.call(ua_data) }
456
+ let(:target_field) { event.get(field) }
115
457
 
116
458
  it "should not have a nil value" do
117
459
  expect(target_field).to be_truthy
@@ -124,6 +466,10 @@ describe LogStash::Filters::UserAgent do
124
466
  it "should dup/clone the field to prevent cache corruption" do
125
467
  expect(target_field.object_id).not_to eql(value.object_id)
126
468
  end
469
+
470
+ it "should be an utf-8 string" do
471
+ expect(target_field.encoding.name).to eql 'UTF-8'
472
+ end
127
473
  end
128
474
  end
129
475
  end
@@ -139,11 +485,25 @@ describe LogStash::Filters::UserAgent do
139
485
  CONFIG
140
486
 
141
487
  sample "Mozilla/5.0 (X11; Linux i686) AppleWebKit/537.31 (KHTML, like Gecko) Chrome/26.0.1410.63 Safari/537.31" do
142
- insist { subject.to_hash }.include?("message")
143
- insist { subject.get("[message][name]") } == "Chrome"
144
- insist { subject.get("[message][os]") } == "Linux"
145
- insist { subject.get("[message][major]") } == "26"
146
- insist { subject.get("[message][minor]") } == "0"
488
+ expect( subject.to_hash ).to include("message")
489
+ expect( subject.get("[message][name]") ).to eql "Chrome"
490
+ expect( subject.get("[message][os]") ).to eql "Linux"
491
+ expect( subject.get("[message][major]") ).to eql "26"
492
+ expect( subject.get("[message][minor]") ).to eql "0"
147
493
  end
148
494
  end
495
+
496
+ context 'exception handling' do
497
+
498
+ before do
499
+ subject.register
500
+ expect(subject).to receive(:lookup_useragent).and_raise RuntimeError.new('this is a test')
501
+ end
502
+
503
+ it 'errors do not propagate' do
504
+ expect(subject.logger).to receive(:error).with(/Unknown error while parsing user agent data/, hash_including(exception: RuntimeError, message: 'this is a test'))
505
+ expect { subject.filter(event) }.not_to raise_error
506
+ end
507
+
508
+ end
149
509
  end
data/version CHANGED
@@ -1 +1 @@
1
- 3.2.2
1
+ 3.3.2
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: logstash-filter-useragent
3
3
  version: !ruby/object:Gem::Version
4
- version: 3.2.2
4
+ version: 3.3.2
5
5
  platform: java
6
6
  authors:
7
7
  - Elastic
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2017-11-07 00:00:00.000000000 Z
11
+ date: 2021-11-10 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  requirement: !ruby/object:Gem::Requirement
@@ -30,6 +30,20 @@ dependencies:
30
30
  - - "<="
31
31
  - !ruby/object:Gem::Version
32
32
  version: '2.99'
33
+ - !ruby/object:Gem::Dependency
34
+ requirement: !ruby/object:Gem::Requirement
35
+ requirements:
36
+ - - "~>"
37
+ - !ruby/object:Gem::Version
38
+ version: '1.3'
39
+ name: logstash-mixin-ecs_compatibility_support
40
+ prerelease: false
41
+ type: :runtime
42
+ version_requirements: !ruby/object:Gem::Requirement
43
+ requirements:
44
+ - - "~>"
45
+ - !ruby/object:Gem::Version
46
+ version: '1.3'
33
47
  - !ruby/object:Gem::Dependency
34
48
  requirement: !ruby/object:Gem::Requirement
35
49
  requirements:
@@ -63,7 +77,7 @@ files:
63
77
  - lib/logstash/filters/useragent.rb
64
78
  - logstash-filter-useragent.gemspec
65
79
  - spec/filters/useragent_spec.rb
66
- - vendor/jar-dependencies/org/logstash/filters/logstash-filter-useragent/3.2.2/logstash-filter-useragent-3.2.2.jar
80
+ - vendor/jar-dependencies/org/logstash/filters/logstash-filter-useragent/3.3.2/logstash-filter-useragent-3.3.2.jar
67
81
  - version
68
82
  homepage: http://www.elastic.co/guide/en/logstash/current/index.html
69
83
  licenses:
@@ -87,8 +101,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
87
101
  - !ruby/object:Gem::Version
88
102
  version: '0'
89
103
  requirements: []
90
- rubyforge_project:
91
- rubygems_version: 2.6.11
104
+ rubygems_version: 3.1.6
92
105
  signing_key:
93
106
  specification_version: 4
94
107
  summary: Parses user agent strings into fields