Skip to content

Commit 3bb2108

Browse files
committed
♻️ Extract send_command_with_continuations method
Abstracts running a command with a continuation handler. In the base specifications (both RFC-3501 and RFC-9051), the only command to need this is `AUTHENTICATE`. The only other continuations are for sending literals, which are simple command arguments. Are there any IMAP extensions that use continuations in this way? Even with only one command, this still makes that code a little more readable. More importantly, it also simplifies the creation of a generic SASL protocol adapter, for use by `net-sasl`, `net-pop`, and others.
1 parent 80c6e96 commit 3bb2108

File tree

1 file changed

+17
-8
lines changed

1 file changed

+17
-8
lines changed

lib/net/imap.rb

Lines changed: 17 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1256,14 +1256,11 @@ def authenticate(mechanism, *creds, sasl_ir: true, **props, &callback)
12561256
response = authenticator.process(nil)
12571257
cmdargs << (response.empty? ? "=" : [response].pack("m0"))
12581258
end
1259-
result = send_command(*cmdargs) do |resp|
1260-
if resp.instance_of?(ContinuationRequest)
1261-
challenge = resp.data.text.unpack1("m")
1262-
response = authenticator.process(challenge)
1263-
response = [response].pack("m0")
1264-
put_string(response + CRLF)
1265-
end
1266-
end
1259+
result = send_command_with_continuations(*cmdargs) {|data|
1260+
challenge = data.unpack1("m")
1261+
response = authenticator.process challenge
1262+
[response].pack("m0")
1263+
}
12671264
if authenticator.respond_to?(:done?) && !authenticator.done?
12681265
logout!
12691266
raise SASL::AuthenticationIncomplete, result
@@ -2571,6 +2568,18 @@ def capabilities_from_resp_code(resp)
25712568

25722569
#############################
25732570

2571+
# Calls send_command, yielding the text of each ContinuationRequest and
2572+
# responding with each block result. Returns TaggedResponse. Raises
2573+
# NoResponseError or BadResponseError.
2574+
def send_command_with_continuations(cmd, *args)
2575+
send_command(cmd, *args) do |server_response|
2576+
if server_response.instance_of?(ContinuationRequest)
2577+
client_response = yield server_response.data.text
2578+
put_string(client_response + CRLF)
2579+
end
2580+
end
2581+
end
2582+
25742583
def send_command(cmd, *args, &block)
25752584
synchronize do
25762585
args.each do |i|

0 commit comments

Comments
 (0)