Skip to content

Commit b3a883e

Browse files
Improve connect methods' block behavior (#505)
* Fixed `TCP.connect`, `UDP.connect`, `POP3.connect`, `SMTP.connect`, and `HTTP.connect` to close the connection even if the given block raises an exception. * Ensure that `TCP.connect`, `UDP.connect`, `POP3.connect`, `SMTP.connect`, and `HTTP.connect` returns the return value of the block. --------- Co-authored-by: Postmodern <postmodern.mod3@gmail.com>
1 parent 0b7efc4 commit b3a883e

File tree

11 files changed

+149
-11
lines changed

11 files changed

+149
-11
lines changed

ChangeLog.md

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,11 @@
1+
### 1.0.6 / 2024-XX-XX
2+
3+
* {Ronin::Support::Network::TCP.connect}, {Ronin::Support::Network::UDP.connect}, and
4+
{Ronin::Support::Network::HTTP.connect}, when given a block, now returns the block's return value.
5+
* {Ronin::Support::Network::TCP.connect} and {Ronin::Support::Network::UDP.connect} properly closes the
6+
socket when passed a block that raises an exception.
7+
8+
19
### 1.0.5 / 2023-12-27
210

311
* Fixed a bug in {Ronin::Support::Binary::Stream::Methods#read_string} on Ruby
@@ -704,4 +712,3 @@
704712
* Require combinatorics ~> 0.3.
705713
* Require uri-query_params ~> 0.5, >= 0.5.2.
706714
* Require data_paths ~> 0.2, >= 0.2.1.
707-

lib/ronin/support/network/http.rb

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -473,8 +473,11 @@ def self.connect(host,port, ssl: port == 443, **kwargs)
473473
http = new(host,port, ssl: ssl, **kwargs)
474474

475475
if block_given?
476-
yield http
477-
http.close
476+
begin
477+
yield http
478+
ensure
479+
http.close
480+
end
478481
else
479482
return http
480483
end

lib/ronin/support/network/pop3/mixin.rb

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -100,8 +100,11 @@ def pop3_connect(host, port: DEFAULT_PORT,
100100
pop3.start(user,password)
101101

102102
if block_given?
103-
yield pop3
104-
pop3.finish
103+
begin
104+
yield pop3
105+
ensure
106+
pop3.finish
107+
end
105108
else
106109
return pop3
107110
end

lib/ronin/support/network/smtp/mixin.rb

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -164,8 +164,11 @@ def smtp_connect(host, user: ,
164164
smtp.start(helo,user,password,auth)
165165

166166
if block_given?
167-
yield smtp
168-
smtp.finish
167+
begin
168+
yield smtp
169+
ensure
170+
smtp.finish
171+
end
169172
else
170173
return smtp
171174
end

lib/ronin/support/network/tcp.rb

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -131,8 +131,11 @@ def self.connect(host,port, bind_host: nil, bind_port: nil)
131131
end
132132

133133
if block_given?
134-
yield socket
135-
socket.close
134+
begin
135+
yield socket
136+
ensure
137+
socket.close
138+
end
136139
else
137140
return socket
138141
end

lib/ronin/support/network/udp.rb

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -137,8 +137,11 @@ def self.connect(host,port, bind_host: nil, bind_port: nil)
137137
socket.connect(host,port)
138138

139139
if block_given?
140-
yield socket
141-
socket.close
140+
begin
141+
yield socket
142+
ensure
143+
socket.close
144+
end
142145
else
143146
return socket
144147
end

spec/network/http_spec.rb

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -442,6 +442,14 @@
442442
described_class.connect(host,port,&b)
443443
}.to yield_with_args(described_class)
444444
end
445+
446+
it "must return the block's return value" do
447+
returned_value = described_class.connect(host,port) do
448+
:return_value
449+
end
450+
451+
expect(returned_value).to eq(:return_value)
452+
end
445453
end
446454
end
447455

spec/network/pop3/mixin_spec.rb

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,16 @@
5858
expect(yielded_pop3).to be_kind_of(Net::POP3)
5959
end
6060

61+
it "must return the block's return value" do
62+
pending "need valid POP3 credentials"
63+
64+
returned_value = subject.pop3_connect(host, port: port, ssl: true) do |pop3|
65+
:return_value
66+
end
67+
68+
expect(returned_value).to be(:return_value)
69+
end
70+
6171
it "must finish the POP3 session after yielding it" do
6272
pending "need valid POP3 credentials"
6373

@@ -72,6 +82,26 @@
7282
expect(was_started).to be(true)
7383
expect(pop3).to_not be_started
7484
end
85+
86+
context "when the block raises an exception" do
87+
it "must finish the POP3 session after yielding it" do
88+
pending "need valid POP3 credentials"
89+
90+
pop3 = nil
91+
was_started = nil
92+
93+
expect do
94+
subject.pop3_connect(host, port: port, ssl: true) do |yielded_pop3|
95+
pop3 = yielded_pop3
96+
was_started = pop3.started?
97+
raise "test exception"
98+
end
99+
end.to raise_error("test exception")
100+
101+
expect(was_started).to be(true)
102+
expect(pop3).to_not be_started
103+
end
104+
end
75105
end
76106
end
77107
end

spec/network/smtp/mixin_spec.rb

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,16 @@
5656
expect(yielded_smtp).to be_kind_of(Net::SMTP)
5757
end
5858

59+
it "must return the block's return value" do
60+
pending "need valid SMTP credentials"
61+
62+
returned_value = subject.smtp_connect(host) do |smtp|
63+
:return_value
64+
end
65+
66+
expect(returned_value).to be(:return_value)
67+
end
68+
5969
it "must finish the SMTP session after yielding it" do
6070
pending "need valid SMTP credentials"
6171

@@ -70,6 +80,26 @@
7080
expect(was_started).to be(true)
7181
expect(smtp).to_not be_started
7282
end
83+
84+
context "when the block raises an exception" do
85+
it "must finish the SMTP session after yielding it" do
86+
pending "need valid SMTP credentials"
87+
88+
smtp = nil
89+
was_started = nil
90+
91+
expect do
92+
subject.smtp_connect(host) do |yielded_smtp|
93+
smtp = yielded_smtp
94+
was_started = smtp.started?
95+
raise "test exception"
96+
end
97+
end.to raise_error("test exception")
98+
99+
expect(was_started).to be(true)
100+
expect(smtp).to_not be_started
101+
end
102+
end
73103
end
74104
end
75105
end

spec/network/tcp_spec.rb

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,30 @@
108108
expect(socket).to be_closed
109109
end
110110

111+
it "must return the block's return value" do
112+
returned_value = subject.connect(host,port) do |socket|
113+
:return_value
114+
end
115+
116+
expect(returned_value).to eq(:return_value)
117+
end
118+
119+
context "when the block raises an exception" do
120+
it "must close the TCPSocket" do
121+
socket = nil
122+
123+
expect do
124+
subject.connect(host,port) do |yielded_socket|
125+
socket = yielded_socket
126+
raise "test exception"
127+
end
128+
end.to raise_error("test exception")
129+
130+
expect(socket).to be_kind_of(TCPSocket)
131+
expect(socket).to be_closed
132+
end
133+
end
134+
111135
context "when given the bind_port: keyword argument" do
112136
let(:bind_port) { 1024 + rand(65535 - 1024) }
113137

spec/network/udp_spec.rb

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,30 @@
103103
expect(socket).to be_closed
104104
end
105105

106+
it "must return the block's return value" do
107+
returned_value = subject.connect(host,port) do |socket|
108+
:return_value
109+
end
110+
111+
expect(returned_value).to eq(:return_value)
112+
end
113+
114+
context "when the block raises an exception" do
115+
it "must close the UDPSocket" do
116+
socket = nil
117+
118+
expect do
119+
subject.connect(host,port) do |yielded_socket|
120+
socket = yielded_socket
121+
raise "test exception"
122+
end
123+
end.to raise_error("test exception")
124+
125+
expect(socket).to be_kind_of(UDPSocket)
126+
expect(socket).to be_closed
127+
end
128+
end
129+
106130
context "when given the bind_port: keyword argument" do
107131
it "must bind to the local port" do
108132
bound_port = nil

0 commit comments

Comments
 (0)