class Lumberjack::Beats::Server
Constants
- SOCKET_TIMEOUT
Attributes
port[R]
Public Class Methods
new(options={})
click to toggle source
Create a new Lumberjack
server.
-
options is a hash. Valid options are:
-
:port - the port to listen on
-
:address - the host/address to bind to
-
:ssl_certificate - the path to the ssl cert to use
-
:ssl_key - the path to the ssl key to use
-
:ssl_key_passphrase - the key passphrase (optional)
# File lib/lumberjack/beats/server.rb, line 25 def initialize(options={}) @options = { :port => 0, :address => "0.0.0.0", :ssl => true, :ssl_certificate => nil, :ssl_key => nil, :ssl_key_passphrase => nil, :ssl_certificate_authorities => nil, :ssl_verify_mode => :none # By default we dont verify client }.merge(options) if @options[:ssl] if verify_client?(@options[:ssl_verify_mode]) && certificate_authorities.empty? raise "When `ssl_verify_mode` is set to `peer` OR `force_peer` you need to specify the `ssl_certificate_authorities`" end if !verify_client?(@options[:ssl_verify_mode]) && certificate_authorities.size > 0 raise "When `ssl_certificate_authorities` is configured you need to set `ssl_verify_mode` to either `peer` or `force_peer`" end if @options[:ssl_certificate].nil? || @options[:ssl_key].nil? raise "You must specify `ssl_certificate` AND `ssl_key`" end end @server = TCPServer.new(@options[:address], @options[:port]) @close = Concurrent::AtomicBoolean.new @port = retrieve_current_port setup_ssl if ssl? end
Public Instance Methods
accept(&block)
click to toggle source
# File lib/lumberjack/beats/server.rb, line 91 def accept(&block) begin socket = @server.accept_nonblock # update the socket with a SSL layer socket = accept_ssl(socket) if ssl? if block_given? block.call(socket, self) else return Connection.new(socket, self) end rescue OpenSSL::SSL::SSLError, IOError, EOFError, Errno::EBADF socket.close rescue nil retry unless closed? rescue IO::WaitReadable, Errno::EAGAIN # Resource not ready yet, so lets try again begin IO.select([@server], nil, nil, SOCKET_TIMEOUT) retry unless closed? rescue IOError, Errno::EBADF => e # we currently closing raise e unless closed? end end end
accept_ssl(tcp_socket)
click to toggle source
# File lib/lumberjack/beats/server.rb, line 115 def accept_ssl(tcp_socket) ssl_socket = OpenSSL::SSL::SSLSocket.new(tcp_socket, @ssl) ssl_socket.sync_close begin ssl_socket.accept_nonblock return ssl_socket rescue IO::WaitReadable # handshake IO.select([ssl_socket], nil, nil, SOCKET_TIMEOUT) retry unless closed? rescue IO::WaitWritable # handshake IO.select(nil, [ssl_socket], nil, SOCKET_TIMEOUT) retry unless closed? end end
close()
click to toggle source
# File lib/lumberjack/beats/server.rb, line 136 def close @close.make_true @server.close unless @server.closed? end
closed?()
click to toggle source
# File lib/lumberjack/beats/server.rb, line 132 def closed? @close.value end
run(&block)
click to toggle source
Server#run
method, allow the library to manage all the connection threads, this handing is quite minimal and don't handler all the possible cases deconnection/connection.
To have a more granular control over the connection you should manage them yourself, see Server#accept
method which return a Connection
instance.
# File lib/lumberjack/beats/server.rb, line 65 def run(&block) while !closed? connection = accept # Some exception may occur in the accept loop # we will try again in the next iteration # unless the server is closing next unless connection Thread.new(connection) do |connection| begin connection.run(&block) rescue Lumberjack::Beats::Connection::ConnectionClosed # Connection will raise a wrapped exception upstream, # but if the threads are managed by the library we can simply ignore it. # # Note: This follow the previous behavior of the perfect silence. end end end end
ssl?()
click to toggle source
# File lib/lumberjack/beats/server.rb, line 87 def ssl? @options[:ssl] end
Private Instance Methods
jruby?()
click to toggle source
# File lib/lumberjack/beats/server.rb, line 176 def jruby? RUBY_PLATFORM == "java" end
retrieve_current_port()
click to toggle source
# File lib/lumberjack/beats/server.rb, line 147 def retrieve_current_port # Query the port in case the port number is '0' # TCPServer#addr == [ address_family, port, address, address ] @server.addr[1] end
server_certificate()
click to toggle source
# File lib/lumberjack/beats/server.rb, line 161 def server_certificate OpenSSL::X509::Certificate.new(File.read(@options[:ssl_certificate])) end
server_private_key()
click to toggle source
# File lib/lumberjack/beats/server.rb, line 157 def server_private_key OpenSSL::PKey::RSA.new(File.read(@options[:ssl_key]), @options[:ssl_key_passphrase]) end
setup_ssl()
click to toggle source
# File lib/lumberjack/beats/server.rb, line 203 def setup_ssl @ssl = OpenSSL::SSL::SSLContext.new # @ssl.verify_callback = lambda do |preverify_ok, context| # require "pry" # binding.pry # end @ssl.cert_store = trust_store @ssl.verify_mode = verify_mode # @ssl.ca_file = certificate_authorities.first @ssl.cert = server_certificate @ssl.key = server_private_key end
trust_store()
click to toggle source
# File lib/lumberjack/beats/server.rb, line 180 def trust_store store = OpenSSL::X509::Store.new if certificate_authorities.size > 0 certificate_authorities.each do |certificate_authority| if File.file?(certificate_authority) store.add_file(certificate_authority) else # `#add_path` is not implemented under jruby # so recursively try to load all the certificate from this directory # https://github.com/jruby/jruby-openssl/blob/master/src/main/java/org/jruby/ext/openssl/X509Store.java#L159 if jruby? Dir.glob(File.join(certificate_authority, "**", "*")).each { |f| store.add_file(f) } else store.add_path(certificate_authority) end end end end store end
verify_client?(mode)
click to toggle source
# File lib/lumberjack/beats/server.rb, line 142 def verify_client?(mode) mode = mode.to_sym mode == :peer || mode == :force_peer end
verify_mode()
click to toggle source
# File lib/lumberjack/beats/server.rb, line 165 def verify_mode case @options[:ssl_verify_mode].to_sym when :none OpenSSL::SSL::VERIFY_NONE when :peer OpenSSL::SSL::VERIFY_PEER when :force_peer OpenSSL::SSL::VERIFY_PEER | OpenSSL::SSL::VERIFY_FAIL_IF_NO_PEER_CERT end end