Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Acceptor host and port #42

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion lib/ione/io/acceptor.rb
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ class Acceptor
CONNECTED_STATE = 1
CLOSED_STATE = 2

attr_reader :backlog
attr_reader :backlog, :host, :port

# @private
def initialize(host, port, backlog, unblocker, reactor, socket_impl=nil)
Expand Down Expand Up @@ -51,6 +51,7 @@ def bind
retry
end
end
@host, @port = @io.local_address.ip_unpack
@state = CONNECTED_STATE
Future.resolved(self)
rescue => e
Expand Down
3 changes: 2 additions & 1 deletion lib/ione/io/connection.rb
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ module Io
# from and writing to the socket.
# @since v1.0.0
class Connection < BaseConnection
attr_reader :connection_timeout
attr_reader :connection_timeout, :local_host, :local_port

# @private
def initialize(host, port, connection_timeout, unblocker, clock, socket_impl=Socket)
Expand Down Expand Up @@ -37,6 +37,7 @@ def connect
end
rescue Errno::EISCONN
@state = CONNECTED_STATE
@local_host, @local_port = @io.local_address.ip_unpack
@connected_promise.fulfill(self)
rescue Errno::EINPROGRESS, Errno::EALREADY
if @clock.now - @connection_started_at > @connection_timeout
Expand Down
5 changes: 3 additions & 2 deletions lib/ione/io/io_reactor.rb
Original file line number Diff line number Diff line change
Expand Up @@ -300,7 +300,8 @@ def connect(host, port, options=nil, &block)
#
# @param host [String] the host to bind to, for example 127.0.0.1,
# 'example.com' – or '0.0.0.0' to bind to all interfaces
# @param port [Integer] the port to bind to
# @param port [Integer] the port to bind to – or 0 to bind to any
# available port
# @param options [Hash]
# @option options [Integer] :backlog (5) the maximum number of pending
# (unaccepted) connections, i.e. Socket::SOMAXCONN
Expand All @@ -311,7 +312,7 @@ def connect(host, port, options=nil, &block)
# bound. The value will be the acceptor, or when a block is given, the
# value returned by the block.
# @since v1.1.0
def bind(host, port, options=nil, &block)
def bind(host='0.0.0.0', port=0, options=nil, &block)
if options.is_a?(Integer) || options.nil?
backlog = options || 5
ssl_context = nil
Expand Down
3 changes: 3 additions & 0 deletions lib/ione/io/ssl_connection.rb
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ module Ione
module Io
# @private
class SslConnection < BaseConnection
attr_reader :local_host, :local_port

def initialize(host, port, io, unblocker, ssl_context=nil, socket_impl=OpenSSL::SSL::SSLSocket)
super(host, port, unblocker)
@socket_impl = socket_impl
Expand All @@ -23,6 +25,7 @@ def connect
@io = @socket_impl.new(@raw_io)
end
@io.connect_nonblock
@local_host, @local_port = @io.local_address.ip_unpack
@state = CONNECTED_STATE
@connected_promise.fulfill(self)
@connected_promise.future
Expand Down
50 changes: 48 additions & 2 deletions spec/ione/io/acceptor_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,15 @@ module Ione
module Io
describe Acceptor do
let :acceptor do
described_class.new('example.com', 4321, backlog, unblocker, reactor, socket_impl)
described_class.new(host, port, backlog, unblocker, reactor, socket_impl)
end

let :host do
'example.com'
end

let :port do
4321
end

let :backlog do
Expand All @@ -30,6 +38,10 @@ module Io
double(:socket)
end

let :local_address do
double(:local_address, ip_unpack: [host, port])
end

shared_context 'accepting_connections' do
let :client_socket do
double(:client_socket)
Expand All @@ -49,7 +61,7 @@ module Io

before do
socket_impl.stub(:getaddrinfo)
.with('example.com', 4321, nil, Socket::SOCK_STREAM)
.with('example.com', port, nil, Socket::SOCK_STREAM)
.and_return([[nil, 'PORT', nil, 'IP1', 'FAMILY1', 'TYPE1'], [nil, 'PORT', nil, 'IP2', 'FAMILY2', 'TYPE2']])
socket_impl.stub(:sockaddr_in)
.with('PORT', 'IP1')
Expand All @@ -66,6 +78,7 @@ module Io
socket.stub(:close)
socket.stub(:bind)
socket.stub(:listen)
socket.stub(:local_address).and_return(local_address)
end

describe '#bind' do
Expand Down Expand Up @@ -225,6 +238,39 @@ module Io
acceptor.to_io.should be_nil
end
end

describe '#host' do
let :local_address do
double(:local_address, ip_unpack: ['1.1.1.1', port])
end

it 'returns the host the server is listening on' do
acceptor.bind
acceptor.host.should eq('1.1.1.1')
end
end

describe '#port' do
it 'returns the port the server is listening on' do
acceptor.bind
acceptor.port.should eq(4321)
end

context 'when the requested port was 0' do
let :port do
0
end

let :local_address do
double(:local_address, ip_unpack: ['example.com', 65432])
end

it 'returns the port that was chosen for the server' do
acceptor.bind
acceptor.port.should eq(65432)
end
end
end
end
end
end
43 changes: 43 additions & 0 deletions spec/ione/io/connection_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,10 @@ module Io
double(:socket)
end

let :local_address do
double(:local_address, ip_unpack: ['1.2.3.4', 65432])
end

before do
socket_impl.stub(:getaddrinfo)
.with('example.com', 55555, nil, Socket::SOCK_STREAM)
Expand All @@ -42,6 +46,7 @@ module Io
before do
socket.stub(:connect_nonblock)
socket.stub(:close)
socket.stub(:local_address).and_return(local_address)
end

it_behaves_like 'a connection' do
Expand Down Expand Up @@ -324,6 +329,44 @@ module Io
end
end
end

describe '#local_host' do
context 'when not yet connected' do
it 'returns nil' do
handler.local_host.should be_nil
end
end

context 'when connected' do
before do
socket.stub(:connect_nonblock).and_raise(Errno::EISCONN)
end

it 'returns the hostname of the interface the socket is using' do
handler.connect
handler.local_host.should eq('1.2.3.4')
end
end
end

describe '#local_port' do
context 'when not yet connected' do
it 'returns nil' do
handler.local_host.should be_nil
end
end

context 'when connected' do
before do
socket.stub(:connect_nonblock).and_raise(Errno::EISCONN)
end

it 'returns the local port the socket is using' do
handler.connect
handler.local_port.should eq(65432)
end
end
end
end
end
end
69 changes: 59 additions & 10 deletions spec/ione/io/ssl_acceptor_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,15 @@ module Ione
module Io
describe SslAcceptor do
let :acceptor do
described_class.new('example.com', 4321, backlog = 3, unblocker, reactor, ssl_context, socket_impl, ssl_socket_impl)
described_class.new(host, port, backlog = 3, unblocker, reactor, ssl_context, socket_impl, ssl_socket_impl)
end

let :host do
'example.com'
end

let :port do
4321
end

let :unblocker do
Expand Down Expand Up @@ -42,22 +50,30 @@ module Io
double(:client_socket)
end

let :local_address do
double(:local_address, ip_unpack: [host, port])
end

before do
socket_impl.stub(:getaddrinfo).and_return([[nil, 'PORT', nil, 'IP1', 'FAMILY1', 'TYPE1']])
socket_impl.stub(:sockaddr_in).with('PORT', 'IP1').and_return('SOCKADDRX')
socket_impl.stub(:unpack_sockaddr_in).with('SOCKADDRX').and_return([3333, 'example.com'])
socket_impl.stub(:new).and_return(socket)
socket.stub(:bind)
socket.stub(:listen)
socket.stub(:accept_nonblock).and_return([client_socket, 'SOCKADDRX'])
socket.stub(:local_address).and_return(local_address)
ssl_socket_impl.stub(:new).with(client_socket, ssl_context).and_return(ssl_socket)
ssl_socket.stub(:accept_nonblock)
end

describe '#read' do
let :accepted_handlers do
[]
end

before do
socket_impl.stub(:getaddrinfo).and_return([[nil, 'PORT', nil, 'IP1', 'FAMILY1', 'TYPE1']])
socket_impl.stub(:sockaddr_in).with('PORT', 'IP1').and_return('SOCKADDRX')
socket_impl.stub(:unpack_sockaddr_in).with('SOCKADDRX').and_return([3333, 'example.com'])
socket_impl.stub(:new).and_return(socket)
socket.stub(:bind)
socket.stub(:listen)
socket.stub(:accept_nonblock).and_return([client_socket, 'SOCKADDRX'])
reactor.stub(:accept) { |h| accepted_handlers << h }
ssl_socket_impl.stub(:new).with(client_socket, ssl_context).and_return(ssl_socket)
ssl_socket.stub(:accept_nonblock)
end

it 'accepts a new connection' do
Expand Down Expand Up @@ -111,6 +127,39 @@ module Io
end
end
end

describe '#host' do
let :local_address do
double(:local_address, ip_unpack: ['1.1.1.1', port])
end

it 'returns the host the server is listening on' do
acceptor.bind
acceptor.host.should eq('1.1.1.1')
end
end

describe '#port' do
it 'returns the port the server is listening on' do
acceptor.bind
acceptor.port.should eq(4321)
end

context 'when the requested port was 0' do
let :port do
0
end

let :local_address do
double(:local_address, ip_unpack: ['example.com', 65432])
end

it 'returns the port that was chosen for the server' do
acceptor.bind
acceptor.port.should eq(65432)
end
end
end
end
end
end
35 changes: 35 additions & 0 deletions spec/ione/io/ssl_connection_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -31,13 +31,18 @@ module Io
double(:ssl_context)
end

let :local_addres do
double(:local_addres, ip_unpack: ['1.2.3.4', 65432])
end

before do
socket_impl.stub(:new).with(raw_socket, ssl_context).and_return(ssl_socket)
end

before do
ssl_socket.stub(:connect_nonblock)
ssl_socket.stub(:close)
ssl_socket.stub(:local_address).and_return(local_addres)
end

it_behaves_like 'a connection', skip_read: true do
Expand Down Expand Up @@ -178,6 +183,36 @@ module Io
handler.should be_closed
end
end

describe '#local_host' do
context 'when not yet connected' do
it 'returns nil' do
handler.local_host.should be_nil
end
end

context 'when connected' do
it 'returns the hostname of the interface the socket is using' do
handler.connect
handler.local_host.should eq('1.2.3.4')
end
end
end

describe '#local_port' do
context 'when not yet connected' do
it 'returns nil' do
handler.local_host.should be_nil
end
end

context 'when connected' do
it 'returns the local port the socket is using' do
handler.connect
handler.local_port.should eq(65432)
end
end
end
end
end
end