spec/outputs/http_spec.rb in logstash-output-http-5.2.5 vs spec/outputs/http_spec.rb in logstash-output-http-5.3.0

- old
+ new

@@ -1,10 +1,13 @@ require "logstash/devutils/rspec/spec_helper" require "logstash/outputs/http" require "logstash/codecs/plain" require "thread" require "sinatra" +require "webrick" +require "webrick/https" +require 'openssl' require_relative "../supports/compressed_requests" PORT = rand(65535-1024) + 1025 class LogStash::Outputs::Http @@ -20,15 +23,26 @@ # class TestApp < Sinatra::Base # on the fly uncompress gzip content use CompressedRequests - # disable WEBrick logging + set :environment, :production + set :sessions, false + + @@server_settings = { + :AccessLog => [], # disable WEBrick logging + :Logger => WEBrick::BasicLog::new(nil, WEBrick::BasicLog::FATAL) + } + def self.server_settings - { :AccessLog => [], :Logger => WEBrick::BasicLog::new(nil, WEBrick::BasicLog::FATAL) } + @@server_settings end + def self.server_settings=(settings) + @@server_settings = settings + end + def self.multiroute(methods, path, &block) methods.each do |method| method.to_sym self.send method, path, &block end @@ -70,42 +84,42 @@ [200, "Done Retrying"] end end end -RSpec.configure do |config| +RSpec.configure do #http://stackoverflow.com/questions/6557079/start-and-call-ruby-http-server-in-the-same-script - def sinatra_run_wait(app, opts) + def start_app_and_wait(app, opts = {}) queue = Queue.new - t = java.lang.Thread.new( - proc do - begin - app.run!(opts) do |server| - queue.push("started") - end - rescue => e - puts "Error in webserver thread #{e}" - # ignore + Thread.start do + begin + app.start!({ server: 'WEBrick', port: PORT }.merge opts) do |server| + queue.push(server) end + rescue => e + warn "Error starting app: #{e.inspect}" # ignore end - ) - t.daemon = true - t.start - queue.pop # blocks until the run! callback runs - end + end - config.before(:suite) do - sinatra_run_wait(TestApp, :port => PORT, :server => 'webrick') - puts "Test webserver on port #{PORT}" + queue.pop # blocks until the start! callback runs end end describe LogStash::Outputs::Http do # Wait for the async request to finish in this spinlock # Requires pool_max to be 1 + before(:all) do + @server = start_app_and_wait(TestApp) + end + + after(:all) do + @server.shutdown # WEBrick::HTTPServer + TestApp.stop! rescue nil + end + let(:port) { PORT } let(:event) { LogStash::Event.new({"message" => "hi"}) } let(:url) { "http://localhost:#{port}/good" } @@ -395,6 +409,78 @@ describe "integration test with gzip compression" do include_examples("integration tests") do let(:base_config) { { "http_compression" => true } } end end +end + +describe LogStash::Outputs::Http do # different block as we're starting web server with TLS + + @@default_server_settings = TestApp.server_settings.dup + + before do + cert, key = WEBrick::Utils.create_self_signed_cert 2048, [["CN", ssl_cert_host]], "Logstash testing" + TestApp.server_settings = @@default_server_settings.merge({ + :SSLEnable => true, + :SSLVerifyClient => OpenSSL::SSL::VERIFY_NONE, + :SSLCertificate => cert, + :SSLPrivateKey => key + }) + + TestApp.last_request = nil + + @server = start_app_and_wait(TestApp) + end + + after do + @server.shutdown # WEBrick::HTTPServer + + TestApp.stop! rescue nil + TestApp.server_settings = @@default_server_settings + end + + let(:ssl_cert_host) { 'localhost' } + + let(:port) { PORT } + let(:url) { "https://localhost:#{port}/good" } + let(:method) { "post" } + + let(:config) { { "url" => url, "http_method" => method } } + + subject { LogStash::Outputs::Http.new(config) } + + before { subject.register } + after { subject.close } + + let(:last_request) { TestApp.last_request } + let(:last_request_body) { last_request.body.read } + + let(:event) { LogStash::Event.new("message" => "hello!") } + + context 'with default (full) verification' do + + let(:config) { super() } # 'ssl_verification_mode' => 'full' + + it "does NOT process the request (due client protocol exception)" do + # Manticore's default verification does not accept self-signed certificates! + Thread.start do + subject.multi_receive [ event ] + end + sleep 1.5 + + expect(last_request).to be nil + end + + end + + context 'with verification disabled' do + + let(:config) { super().merge 'ssl_verification_mode' => 'none' } + + it "should process the request" do + subject.multi_receive [ event ] + expect(last_request_body).to include '"message":"hello!"' + end + + end + end