logstash-input-http_bold 3.4.1-java

Sign up to get free protection for your applications and to get access to all the features.
@@ -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