logstash-input-http_bold 3.4.1-java

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,16 @@
1
+ # encoding: utf-8
2
+ require "jars/installer"
3
+ require "fileutils"
4
+
5
+ desc "vendor"
6
+ task :vendor do
7
+ exit(1) unless system './gradlew vendor'
8
+ version = File.read("VERSION").strip
9
+ end
10
+
11
+ desc "clean"
12
+ task :clean do
13
+ ["build", "vendor/jar-dependencies", "Gemfile.lock"].each do |p|
14
+ FileUtils.rm_rf(p)
15
+ end
16
+ end
@@ -0,0 +1,34 @@
1
+ HTTP_INPUT_VERSION = File.read(File.expand_path(File.join(File.dirname(__FILE__), "VERSION"))).strip unless defined?(HTTP_INPUT_VERSION)
2
+
3
+ Gem::Specification.new do |s|
4
+ s.name = 'logstash-input-http_bold'
5
+ s.version = HTTP_INPUT_VERSION
6
+ s.licenses = ['Apache License (2.0)']
7
+ s.summary = "Receives events over HTTP or HTTPS"
8
+ s.description = "This gem is a Logstash plugin required to be installed on top of the Logstash core pipeline using $LS_HOME/bin/logstash-plugin install gemname. This gem is not a stand-alone program"
9
+ s.authors = ["Elastic"]
10
+ s.email = 'info@elastic.co'
11
+ s.homepage = "http://www.elastic.co/guide/en/logstash/current/index.html"
12
+ s.require_paths = ["lib", "vendor/jar-dependencies"]
13
+
14
+ # Files
15
+ s.files = Dir["lib/**/*","spec/**/*","*.gemspec","*.md","CONTRIBUTORS","Gemfile","LICENSE","NOTICE.TXT", "vendor/jar-dependencies/**/*.jar", "vendor/jar-dependencies/**/*.rb", "VERSION", "docs/**/*"]
16
+ # Tests
17
+ s.test_files = s.files.grep(%r{^(test|spec|features)/})
18
+
19
+ # Special flag to let us know this is actually a logstash plugin
20
+ s.metadata = { "logstash_plugin" => "true", "logstash_group" => "input" }
21
+
22
+ # Gem dependencies
23
+ s.add_runtime_dependency "logstash-core-plugin-api", ">= 1.60", "<= 2.99"
24
+ s.add_runtime_dependency 'logstash-codec-plain'
25
+ s.add_runtime_dependency 'jar-dependencies', '~> 0.3', '>= 0.3.4'
26
+ s.add_runtime_dependency 'logstash-mixin-ecs_compatibility_support', '~>1.2'
27
+
28
+ s.add_development_dependency 'logstash-devutils'
29
+ s.add_development_dependency 'logstash-codec-json'
30
+ s.add_development_dependency 'logstash-codec-json_lines'
31
+ s.add_development_dependency 'manticore'
32
+
33
+ s.platform = "java"
34
+ end
@@ -0,0 +1,570 @@
1
+ require "logstash/devutils/rspec/spec_helper"
2
+ require "logstash/devutils/rspec/shared_examples"
3
+ require "logstash/inputs/http"
4
+ require "json"
5
+ require "manticore"
6
+ require "stud/temporary"
7
+ require "zlib"
8
+ require "stringio"
9
+ require 'logstash/plugin_mixins/ecs_compatibility_support/spec_helper'
10
+
11
+ java_import "io.netty.handler.ssl.util.SelfSignedCertificate"
12
+
13
+ describe LogStash::Inputs::Http do
14
+
15
+ before do
16
+ srand(RSpec.configuration.seed)
17
+ end
18
+
19
+ let(:client) { Manticore::Client.new(client_options) }
20
+ let(:client_options) { { } }
21
+ let(:logstash_queue) { Queue.new }
22
+ let(:port) { rand(5000) + 1025 }
23
+
24
+ it_behaves_like "an interruptible input plugin" do
25
+ let(:config) { { "port" => port } }
26
+ end
27
+
28
+ after :each do
29
+ client.clear_pending
30
+ client.close
31
+ subject.stop
32
+ end
33
+
34
+ describe "request handling" do
35
+ subject { LogStash::Inputs::Http.new("port" => port) }
36
+
37
+ before :each do
38
+ setup_server_client
39
+ end
40
+
41
+ describe "handling overflowing requests with a 429" do
42
+ let(:logstash_queue_size) { rand(10) + 1 }
43
+ let(:max_pending_requests) { rand(5) + 1 }
44
+ let(:threads) { rand(4) + 1 }
45
+ let(:logstash_queue) { SizedQueue.new(logstash_queue_size) }
46
+ let(:client_options) { {
47
+ "request_timeout" => 0.1,
48
+ "connect_timeout" => 3,
49
+ "socket_timeout" => 0.1
50
+ } }
51
+
52
+ subject { described_class.new("port" => port, "threads" => threads, "max_pending_requests" => max_pending_requests) }
53
+
54
+ context "when sending more requests than queue slots" do
55
+ it "should block when the queue is full" do
56
+ # these will queue and return 200
57
+ logstash_queue_size.times.each do |i|
58
+ response = client.post("http://127.0.0.1:#{port}", :body => '{}').call
59
+ expect(response.code).to eq(200)
60
+ end
61
+
62
+ # these will block
63
+ (threads + max_pending_requests).times.each do |i|
64
+ expect {
65
+ client.post("http://127.0.0.1:#{port}", :body => '{}').call
66
+ }.to raise_error(Manticore::SocketTimeout)
67
+ end
68
+
69
+ # by now we should be rejecting with 429
70
+ response = client.post("http://127.0.0.1:#{port}", :body => '{}').call
71
+ expect(response.code).to eq(429)
72
+ end
73
+ end
74
+ end
75
+
76
+ context "with default codec" do
77
+ subject { LogStash::Inputs::Http.new("port" => port) }
78
+ context "when receiving a text/plain request" do
79
+ it "should process the request normally" do
80
+ client.post("http://127.0.0.1:#{port}/meh.json",
81
+ :headers => { "content-type" => "text/plain" },
82
+ :body => "hello").call
83
+ event = logstash_queue.pop
84
+ expect(event.get("message")).to eq("hello")
85
+ end
86
+ end
87
+ context "when receiving a deflate compressed text/plain request" do
88
+ it "should process the request normally" do
89
+ client.post("http://127.0.0.1:#{port}/meh.json",
90
+ :headers => { "content-type" => "text/plain", "content-encoding" => "deflate" },
91
+ :body => Zlib::Deflate.deflate("hello")).call
92
+ event = logstash_queue.pop
93
+ expect(event.get("message")).to eq("hello")
94
+ end
95
+ end
96
+ context "when receiving a deflate text/plain request that cannot be decompressed" do
97
+ let(:response) do
98
+ response = client.post("http://127.0.0.1:#{port}/meh.json",
99
+ :headers => { "content-type" => "text/plain", "content-encoding" => "deflate" },
100
+ :body => "hello").call
101
+ end
102
+ it "should respond with 400" do
103
+ expect(response.code).to eq(400)
104
+ end
105
+ end
106
+ context "when receiving a gzip compressed text/plain request" do
107
+ it "should process the request normally" do
108
+ wio = StringIO.new("w")
109
+ z = Zlib::GzipWriter.new(wio)
110
+ z.write("hello")
111
+ z.close
112
+ entity = org.apache.http.entity.ByteArrayEntity.new(wio.string.to_java_bytes)
113
+ response = client.post("http://127.0.0.1:#{port}",
114
+ :headers => { "Content-Encoding" => "gzip" },
115
+ :entity => entity).call
116
+ expect(response.code).to eq(200)
117
+ event = logstash_queue.pop
118
+ expect(event.get("message")).to eq("hello")
119
+ end
120
+ end
121
+ context "when receiving a gzip text/plain request that cannot be decompressed" do
122
+ let(:response) do
123
+ client.post("http://127.0.0.1:#{port}",
124
+ :headers => { "Content-Encoding" => "gzip" },
125
+ :body => Zlib::Deflate.deflate("hello")).call
126
+ end
127
+ it "should respond with 400" do
128
+ expect(response.code).to eq(400)
129
+ end
130
+ end
131
+ context "when receiving an application/json request" do
132
+ it "should parse the json body" do
133
+ client.post("http://127.0.0.1:#{port}/meh.json",
134
+ :headers => { "content-type" => "application/json" },
135
+ :body => { "message_body" => "Hello" }.to_json).call
136
+ event = logstash_queue.pop
137
+ expect(event.get("message_body")).to eq("Hello")
138
+ end
139
+ end
140
+ end
141
+
142
+ context "with json codec" do
143
+ subject { LogStash::Inputs::Http.new("port" => port, "codec" => "json") }
144
+ it "should parse the json body" do
145
+ response = client.post("http://127.0.0.1:#{port}/meh.json", :body => { "message" => "Hello" }.to_json).call
146
+ event = logstash_queue.pop
147
+ expect(event.get("message")).to eq("Hello")
148
+ end
149
+ end
150
+
151
+ context "with json_lines codec without final delimiter" do
152
+ subject { LogStash::Inputs::Http.new("port" => port, "codec" => "json_lines") }
153
+ let(:line1) { '{"foo": 1}' }
154
+ let(:line2) { '{"foo": 2}' }
155
+ it "should parse all json_lines in body including last one" do
156
+ client.post("http://localhost:#{port}/meh.json", :body => "#{line1}\n#{line2}").call
157
+ expect(logstash_queue.size).to eq(2)
158
+ event = logstash_queue.pop
159
+ expect(event.get("foo")).to eq(1)
160
+ event = logstash_queue.pop
161
+ expect(event.get("foo")).to eq(2)
162
+ end
163
+ end
164
+
165
+ context "when using a custom codec mapping" do
166
+ subject { LogStash::Inputs::Http.new("port" => port,
167
+ "additional_codecs" => { "application/json" => "plain" }) }
168
+ it "should decode the message accordingly" do
169
+ body = { "message" => "Hello" }.to_json
170
+ client.post("http://127.0.0.1:#{port}/meh.json",
171
+ :headers => { "content-type" => "application/json" },
172
+ :body => body).call
173
+ event = logstash_queue.pop
174
+ expect(event.get("message")).to eq(body)
175
+ end
176
+ end
177
+
178
+ context "when receiving a content-type with a charset" do
179
+ subject { LogStash::Inputs::Http.new("port" => port,
180
+ "additional_codecs" => { "application/json" => "plain" }) }
181
+ it "should decode the message accordingly" do
182
+ body = { "message" => "Hello" }.to_json
183
+ client.post("http://127.0.0.1:#{port}/meh.json",
184
+ :headers => { "content-type" => "application/json; charset=utf-8" },
185
+ :body => body).call
186
+ event = logstash_queue.pop
187
+ expect(event.get("message")).to eq(body)
188
+ end
189
+ end
190
+
191
+ context "when using custom headers" do
192
+ let(:custom_headers) { { 'access-control-allow-origin' => '*' } }
193
+ subject { LogStash::Inputs::Http.new("port" => port, "response_headers" => custom_headers) }
194
+
195
+ describe "the response" do
196
+ it "should include the custom headers" do
197
+ response = client.post("http://127.0.0.1:#{port}/meh", :body => "hello").call
198
+ expect(response.headers.to_hash).to include(custom_headers)
199
+ end
200
+ end
201
+ end
202
+ describe "basic auth" do
203
+ user = "test"; password = "pwd"
204
+ subject { LogStash::Inputs::Http.new("port" => port, "user" => user, "password" => password) }
205
+ let(:auth_token) { Base64.strict_encode64("#{user}:#{password}") }
206
+ context "when client doesn't present auth token" do
207
+ let!(:response) { client.post("http://127.0.0.1:#{port}/meh", :body => "hi").call }
208
+ it "should respond with 401" do
209
+ expect(response.code).to eq(401)
210
+ end
211
+ it 'should include a WWW-Authenticate: Basic header' do
212
+ expect(response['WWW-Authenticate']).to_not be_nil
213
+
214
+ expect(response['WWW-Authenticate']).to start_with('Basic realm=')
215
+ end
216
+ it "should not generate an event" do
217
+ expect(logstash_queue).to be_empty
218
+ end
219
+ end
220
+ context "when client presents incorrect auth token" do
221
+ let!(:response) do
222
+ client.post("http://127.0.0.1:#{port}/meh",
223
+ :headers => {
224
+ "content-type" => "text/plain",
225
+ "authorization" => "Basic meh"
226
+ },
227
+ :body => "hi").call
228
+ end
229
+ it "should respond with 401" do
230
+ expect(response.code).to eq(401)
231
+ end
232
+ it 'should not include a WWW-Authenticate header' do
233
+ expect(response['WWW-Authenticate']).to be_nil
234
+ end
235
+ it "should not generate an event" do
236
+ expect(logstash_queue).to be_empty
237
+ end
238
+ end
239
+ context "when client presents correct auth token" do
240
+ let!(:response) do
241
+ client.post("http://127.0.0.1:#{port}/meh",
242
+ :headers => {
243
+ "content-type" => "text/plain",
244
+ "authorization" => "Basic #{auth_token}"
245
+ }, :body => "hi").call
246
+ end
247
+ it "should respond with 200" do
248
+ expect(response.code).to eq(200)
249
+ end
250
+ it "should generate an event" do
251
+ expect(logstash_queue).to_not be_empty
252
+ end
253
+ end
254
+ end
255
+
256
+ describe "HTTP Protocol Handling" do
257
+ context "when an HTTP1.1 request is made" do
258
+ let(:protocol_version) do
259
+ Java::OrgApacheHttp::HttpVersion::HTTP_1_1
260
+ end
261
+ it "responds with a HTTP1.1 response" do
262
+ response = client.post("http://127.0.0.1:#{port}", :body => "hello")
263
+ response.request.set_protocol_version(protocol_version)
264
+ response.call
265
+ response_protocol_version = response.instance_variable_get(:@response).get_protocol_version
266
+ expect(response_protocol_version).to eq(protocol_version)
267
+ end
268
+ end
269
+ context "when an HTTP1.0 request is made" do
270
+ let(:protocol_version) do
271
+ Java::OrgApacheHttp::HttpVersion::HTTP_1_0
272
+ end
273
+ it "responds with a HTTP1.0 response" do
274
+ response = client.post("http://127.0.0.1:#{port}", :body => "hello")
275
+ response.request.set_protocol_version(protocol_version)
276
+ response.call
277
+ response_protocol_version = response.instance_variable_get(:@response).get_protocol_version
278
+ expect(response_protocol_version).to eq(protocol_version)
279
+ end
280
+ end
281
+ end
282
+ describe "return code" do
283
+ it "responds with a 200" do
284
+ response = client.post("http://127.0.0.1:#{port}", :body => "hello")
285
+ response.call
286
+ expect(response.code).to eq(200)
287
+ end
288
+ context "when response_code is configured" do
289
+ let(:code) { 202 }
290
+ subject { LogStash::Inputs::Http.new("port" => port, "response_code" => code) }
291
+ it "responds with the configured code" do
292
+ response = client.post("http://127.0.0.1:#{port}", :body => "hello")
293
+ response.call
294
+ expect(response.code).to eq(202)
295
+ end
296
+ end
297
+ end
298
+ end
299
+
300
+ describe "ECS support", :ecs_compatibility_support, :aggregate_failures do
301
+ ecs_compatibility_matrix(:disabled, :v1) do |ecs_select|
302
+ let(:host_field) { ecs_select[disabled: "[host]", v1: "[host][ip]"] }
303
+ let(:header_field) { ecs_select[disabled: "headers", v1: "[@metadata][input][http][request][headers]"] }
304
+ let(:http_version_field) { ecs_select[disabled: "[headers][http_version]", v1: "[http][version]"] }
305
+ let(:user_agent_field) { ecs_select[disabled: "[headers][http_user_agent]", v1: "[user_agent][original]"] }
306
+ let(:http_host_field) { "[headers][http_host]" }
307
+ let(:domain_field) { "[url][domain]" }
308
+ let(:port_field) { "[url][port]" }
309
+ let(:request_method_field) { ecs_select[disabled: "[headers][request_method]", v1: "[http][method]"] }
310
+ let(:request_path_field) { ecs_select[disabled: "[headers][request_path]", v1: "[url][path]"] }
311
+ let(:content_length_field) { ecs_select[disabled: "[headers][content_length]", v1: "[http][request][body][bytes]"] }
312
+ let(:content_type_field) { ecs_select[disabled: "[headers][content_type]", v1: "[http][request][mime_type]"] }
313
+
314
+ before :each do
315
+ allow_any_instance_of(described_class).to receive(:ecs_compatibility).and_return(ecs_compatibility)
316
+ setup_server_client
317
+ end
318
+
319
+ describe "remote host" do
320
+ subject { LogStash::Inputs::Http.new(config.merge("port" => port)) }
321
+ context "by default" do
322
+ let(:config) { {} }
323
+ it "is written to the \"host\" field" do
324
+ client.post("http://localhost:#{port}/meh.json",
325
+ :headers => { "content-type" => "text/plain" },
326
+ :body => "hello").call
327
+ event = logstash_queue.pop
328
+ expect(event.get(host_field)).to eq("127.0.0.1")
329
+ end
330
+ end
331
+
332
+ context "when using remote_host_target_field" do
333
+ let(:config) { { "remote_host_target_field" => "remote_host" } }
334
+ it "is written to the value of \"remote_host_target_field\" property" do
335
+ client.post("http://localhost:#{port}/meh.json",
336
+ :headers => { "content-type" => "text/plain" },
337
+ :body => "hello").call
338
+ event = logstash_queue.pop
339
+ expect(event.get("remote_host")).to eq("127.0.0.1")
340
+ end
341
+ end
342
+ end
343
+
344
+ describe "request headers" do
345
+ subject { LogStash::Inputs::Http.new(config.merge("port" => port)) }
346
+ context "by default" do
347
+ let(:config) { {} }
348
+ it "are written to the \"headers\" field" do
349
+ client.post("http://localhost:#{port}/meh.json",
350
+ :headers => { "content-type" => "text/plain" },
351
+ :body => "hello").call
352
+ event = logstash_queue.pop
353
+ expect(event.get(header_field)).to be_a(Hash)
354
+ expect(event.get(request_method_field)).to eq("POST")
355
+ expect(event.get(request_path_field)).to eq("/meh.json")
356
+ expect(event.get(http_version_field)).to eq("HTTP/1.1")
357
+ expect(event.get(user_agent_field)).to include("Manticore")
358
+ if ecs_compatibility == :disabled
359
+ expect(event.get(http_host_field)).to eq("localhost:#{port}")
360
+ else
361
+ expect(event.get(domain_field)).to eq("localhost")
362
+ expect(event.get(port_field)).to eq(port)
363
+ end
364
+
365
+ expect(event.get(content_length_field)).to eq("5")
366
+ expect(event.get(content_type_field)).to eq("text/plain")
367
+ end
368
+ end
369
+ context "when using request_headers_target_field" do
370
+ let(:config) { { "request_headers_target_field" => "request_headers" } }
371
+ it "are written to the field set in \"request_headers_target_field\"" do
372
+ client.post("http://localhost:#{port}/meh.json",
373
+ :headers => { "content-type" => "text/plain" },
374
+ :body => "hello").call
375
+ event = logstash_queue.pop
376
+ expect(event.get("request_headers")).to be_a(Hash)
377
+ expect(event.get("request_headers")).to include("request_method" => "POST")
378
+ expect(event.get("request_headers")).to include("request_path" => "/meh.json")
379
+ expect(event.get("request_headers")).to include("http_version" => "HTTP/1.1")
380
+ expect(event.get("request_headers")["http_user_agent"]).to include("Manticore")
381
+ expect(event.get("request_headers")).to include("http_host" => "localhost:#{port}")
382
+ expect(event.get("request_headers")).to include("content_length" => "5")
383
+ expect(event.get("request_headers")).to include("content_type" => "text/plain")
384
+ end
385
+ end
386
+ end
387
+ end
388
+ end
389
+
390
+ # wait until server is ready
391
+ def setup_server_client
392
+ subject.register
393
+ t = Thread.new { subject.run(logstash_queue) }
394
+ ok = false
395
+ until ok
396
+ begin
397
+ client.post("http://127.0.0.1:#{port}", :body => '{}').call
398
+ rescue => e
399
+ # retry
400
+ else
401
+ ok = true
402
+ end
403
+ sleep 0.01
404
+ end
405
+ logstash_queue.pop if logstash_queue.size == 1 # pop test event
406
+ end
407
+
408
+ describe "parse domain host" do
409
+ let(:localhost) { "localhost" }
410
+ let(:ipv6) { "2001:db8::8a2e:370:7334" }
411
+
412
+ it "should parse in IPV4 format with port" do
413
+ domain, port = LogStash::Inputs::Http.get_domain_port("#{localhost}:8080")
414
+ expect(domain).to eq(localhost)
415
+ expect(port).to eq(8080)
416
+ end
417
+
418
+ it "should parse in IPV4 format without port" do
419
+ domain, port = LogStash::Inputs::Http.get_domain_port(localhost)
420
+ expect(domain).to eq(localhost)
421
+ expect(port).to be_nil
422
+ end
423
+
424
+ it "should parse in IPV6 format with port" do
425
+ domain, port = LogStash::Inputs::Http.get_domain_port("[#{ipv6}]:8080")
426
+ expect(domain).to eq(ipv6)
427
+ expect(port).to eq(8080)
428
+ end
429
+
430
+ it "should parse in IPV6 format without port" do
431
+ domain, port = LogStash::Inputs::Http.get_domain_port("#{ipv6}")
432
+ expect(domain).to eq(ipv6)
433
+ expect(port).to be_nil
434
+ end
435
+ end
436
+
437
+ context "with :ssl => false" do
438
+ subject { LogStash::Inputs::Http.new("port" => port, "ssl" => false) }
439
+ it "should not raise exception" do
440
+ expect { subject.register }.to_not raise_exception
441
+ end
442
+ end
443
+ context "with :ssl => true" do
444
+ context "without :ssl_certificate" do
445
+ subject { LogStash::Inputs::Http.new("port" => port, "ssl" => true) }
446
+ it "should raise exception" do
447
+ expect { subject.register }.to raise_exception(LogStash::ConfigurationError)
448
+ end
449
+ end
450
+ context "with :ssl_certificate" do
451
+ let(:ssc) { SelfSignedCertificate.new }
452
+ let(:ssl_certificate) { ssc.certificate }
453
+ let(:ssl_key) { ssc.private_key }
454
+
455
+ let(:config) do
456
+ { "port" => port, "ssl" => true, "ssl_certificate" => ssl_certificate.path, "ssl_key" => ssl_key.path }
457
+ end
458
+
459
+ after(:each) { ssc.delete }
460
+
461
+ subject { LogStash::Inputs::Http.new(config) }
462
+
463
+ it "should not raise exception" do
464
+ expect { subject.register }.to_not raise_exception
465
+ end
466
+
467
+ context "with ssl_verify_mode = none" do
468
+ subject { LogStash::Inputs::Http.new(config.merge("ssl_verify_mode" => "none")) }
469
+
470
+ it "should not raise exception" do
471
+ expect { subject.register }.to_not raise_exception
472
+ end
473
+ end
474
+ ["peer", "force_peer"].each do |verify_mode|
475
+ context "with ssl_verify_mode = #{verify_mode}" do
476
+ subject { LogStash::Inputs::Http.new("port" => port, "ssl" => true,
477
+ "ssl_certificate" => ssl_certificate.path,
478
+ "ssl_certificate_authorities" => ssl_certificate.path,
479
+ "ssl_key" => ssl_key.path,
480
+ "ssl_verify_mode" => verify_mode
481
+ ) }
482
+ it "should not raise exception" do
483
+ expect { subject.register }.to_not raise_exception
484
+ end
485
+ end
486
+ end
487
+ context "with verify_mode = none" do
488
+ subject { LogStash::Inputs::Http.new(config.merge("verify_mode" => "none")) }
489
+
490
+ it "should not raise exception" do
491
+ expect { subject.register }.to_not raise_exception
492
+ end
493
+ end
494
+ ["peer", "force_peer"].each do |verify_mode|
495
+ context "with verify_mode = #{verify_mode}" do
496
+ subject { LogStash::Inputs::Http.new("port" => port, "ssl" => true,
497
+ "ssl_certificate" => ssl_certificate.path,
498
+ "ssl_certificate_authorities" => ssl_certificate.path,
499
+ "ssl_key" => ssl_key.path,
500
+ "verify_mode" => verify_mode
501
+ ) }
502
+ it "should not raise exception" do
503
+ expect { subject.register }.to_not raise_exception
504
+ end
505
+ end
506
+ end
507
+
508
+ context "with invalid cipher_suites" do
509
+ let(:config) { super().merge("cipher_suites" => "TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA38") }
510
+
511
+ it "should raise a configuration error" do
512
+ expect( subject.logger ).to receive(:error) do |msg, opts|
513
+ expect( msg ).to match /.*?configuration invalid/
514
+ expect( opts[:message] ).to match /TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA38.*? not available/
515
+ end
516
+ expect { subject.register }.to raise_error(LogStash::ConfigurationError)
517
+ end
518
+ end
519
+
520
+ context "with invalid ssl certificate" do
521
+ before do
522
+ cert = File.readlines path = config["ssl_certificate"]
523
+ i = cert.index { |line| line.index('END CERTIFICATE') }
524
+ cert[i - 1] = ''
525
+ File.write path, cert.join("\n")
526
+ end
527
+
528
+ it "should raise a configuration error" do
529
+ expect( subject.logger ).to receive(:error) do |msg, opts|
530
+ expect( msg ).to match /SSL configuration invalid/
531
+ expect( opts[:message] ).to match /File does not contain valid certificate/i
532
+ end
533
+ expect { subject.register }.to raise_error(LogStash::ConfigurationError)
534
+ end
535
+ end
536
+
537
+ context "with invalid ssl key config" do
538
+ let(:config) { super().merge("ssl_key_passphrase" => "1234567890") }
539
+
540
+ it "should raise a configuration error" do
541
+ expect( subject.logger ).to receive(:error) do |msg, opts|
542
+ expect( msg ).to match /SSL configuration invalid/
543
+ expect( opts[:message] ).to match /File does not contain valid private key/i
544
+ end
545
+ expect { subject.register }.to raise_error(LogStash::ConfigurationError)
546
+ end
547
+ end
548
+
549
+ context "with invalid ssl certificate_authorities" do
550
+ let(:config) do
551
+ super().merge("ssl_verify_mode" => "peer",
552
+ "ssl_certificate_authorities" => [ ssc.certificate.path, ssc.private_key.path ])
553
+ end
554
+
555
+ it "should raise a cert error" do
556
+ expect( subject.logger ).to receive(:error) do |msg, opts|
557
+ expect( msg ).to match(/SSL configuration failed/), lambda { "unexpected: logger.error #{msg.inspect}, #{opts.inspect}" }
558
+ expect( opts[:message] ).to match /signed fields invalid/
559
+ end
560
+ begin
561
+ subject.register
562
+ rescue Java::JavaSecurityCert::CertificateParsingException
563
+ :pass
564
+ end
565
+ end
566
+ end
567
+
568
+ end
569
+ end
570
+ end