Class: Lumberjack::Server
- Inherits:
-
Object
- Object
- Lumberjack::Server
- Defined in:
- lib/lumberjack/server.rb
Constant Summary collapse
- SOCKET_TIMEOUT =
seconds
1
Instance Attribute Summary collapse
-
#port ⇒ Object
readonly
Returns the value of attribute port.
Instance Method Summary collapse
- #accept(&block) ⇒ Object
- #accept_ssl(tcp_socket) ⇒ Object
- #close ⇒ Object
- #closed? ⇒ Boolean
-
#initialize(options = {}) ⇒ Server
constructor
Create a new Lumberjack server.
-
#run(&block) ⇒ Object
def initialize.
-
#ssl? ⇒ Boolean
def run.
Constructor Details
#initialize(options = {}) ⇒ Server
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)
25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 |
# File 'lib/lumberjack/server.rb', line 25 def initialize(={}) @options = { :port => 0, :address => "0.0.0.0", :ssl => true, :ssl_certificate => nil, :ssl_key => nil, :ssl_key_passphrase => nil }.merge() if @options[:ssl] [:ssl_certificate, :ssl_key].each do |k| if @options[k].nil? raise "You must specify #{k} in Lumberjack::Server.new(...)" end end end @server = TCPServer.new(@options[:address], @options[:port]) @close = Concurrent::AtomicBoolean.new # Query the port in case the port number is '0' # TCPServer#addr == [ address_family, port, address, address ] @port = @server.addr[1] if @options[:ssl] # load SSL certificate @ssl = OpenSSL::SSL::SSLContext.new @ssl.cert = OpenSSL::X509::Certificate.new(File.read(@options[:ssl_certificate])) @ssl.key = OpenSSL::PKey::RSA.new(File.read(@options[:ssl_key]), @options[:ssl_key_passphrase]) end end |
Instance Attribute Details
#port ⇒ Object (readonly)
Returns the value of attribute port.
14 15 16 |
# File 'lib/lumberjack/server.rb', line 14 def port @port end |
Instance Method Details
#accept(&block) ⇒ Object
79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 |
# File 'lib/lumberjack/server.rb', line 79 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) ⇒ Object
103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 |
# File 'lib/lumberjack/server.rb', line 103 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 ⇒ Object
124 125 126 127 |
# File 'lib/lumberjack/server.rb', line 124 def close @close.make_true @server.close unless @server.closed? end |
#closed? ⇒ Boolean
120 121 122 |
# File 'lib/lumberjack/server.rb', line 120 def closed? @close.value end |
#run(&block) ⇒ Object
def initialize
60 61 62 63 64 65 66 67 68 69 70 71 72 73 |
# File 'lib/lumberjack/server.rb', line 60 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| connection.run(&block) end end end |
#ssl? ⇒ Boolean
def run
75 76 77 |
# File 'lib/lumberjack/server.rb', line 75 def ssl? @ssl end |