add nio connection layer: tls bootstrap, response handler, command runner
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,57 @@
|
||||
import NIO
|
||||
import NIOIMAPCore
|
||||
@preconcurrency import NIOIMAP
|
||||
@preconcurrency import NIOSSL
|
||||
|
||||
actor IMAPConnection {
|
||||
private let host: String
|
||||
private let port: Int
|
||||
private let group: EventLoopGroup
|
||||
private var channel: Channel?
|
||||
private let responseHandler: IMAPResponseHandler
|
||||
|
||||
init(host: String, port: Int) {
|
||||
self.host = host
|
||||
self.port = port
|
||||
self.group = MultiThreadedEventLoopGroup(numberOfThreads: 1)
|
||||
self.responseHandler = IMAPResponseHandler()
|
||||
}
|
||||
|
||||
func connect() async throws {
|
||||
let sslContext = try NIOSSLContext(configuration: TLSConfiguration.makeClientConfiguration())
|
||||
let handler = responseHandler
|
||||
let hostname = host
|
||||
|
||||
let bootstrap = ClientBootstrap(group: group)
|
||||
.channelOption(ChannelOptions.socketOption(.so_reuseaddr), value: 1)
|
||||
.channelInitializer { channel in
|
||||
let sslHandler = try! NIOSSLClientHandler(context: sslContext, serverHostname: hostname)
|
||||
return channel.pipeline.addHandlers([
|
||||
sslHandler,
|
||||
IMAPClientHandler(),
|
||||
handler,
|
||||
])
|
||||
}
|
||||
|
||||
channel = try await bootstrap.connect(host: host, port: port).get()
|
||||
try await handler.waitForGreeting()
|
||||
}
|
||||
|
||||
func sendCommand(_ tag: String, command: CommandStreamPart) async throws -> [Response] {
|
||||
guard let channel else { throw IMAPError.notConnected }
|
||||
let handler = responseHandler
|
||||
return try await withCheckedThrowingContinuation { continuation in
|
||||
handler.sendCommand(tag: tag, continuation: continuation)
|
||||
channel.writeAndFlush(IMAPClientHandler.Message.part(command), promise: nil)
|
||||
}
|
||||
}
|
||||
|
||||
func disconnect() async throws {
|
||||
try await channel?.close()
|
||||
channel = nil
|
||||
}
|
||||
|
||||
func shutdown() async throws {
|
||||
try await group.shutdownGracefully()
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user