Ensure that handlers added with first:true are in proper order. (#118)
Motivation: Right now addHandlers(first:) does not actually add handlers at the front of the pipeline: it just adds them *backwards* at the end of the pipeline. That's definitely not right. Modifications: Pass the first: flag into the call to add each specific handler to ensure they're actually put at the front of the pipeline. Result: Handlers added to the front of the pipeline actually are.
This commit is contained in:
parent
684ae3d933
commit
43dd9c0b33
|
@ -697,7 +697,7 @@ extension ChannelPipeline {
|
|||
handlers = handlers.reversed()
|
||||
}
|
||||
|
||||
return EventLoopFuture<Void>.andAll(handlers.map { add(handler: $0) }, eventLoop: eventLoop)
|
||||
return EventLoopFuture<Void>.andAll(handlers.map { add(handler: $0, first: first) }, eventLoop: eventLoop)
|
||||
}
|
||||
|
||||
/// Adds the provided channel handlers to the pipeline in the order given, taking account
|
||||
|
|
|
@ -34,6 +34,7 @@ extension ChannelPipelineTest {
|
|||
("testWriteAfterClose", testWriteAfterClose),
|
||||
("testOutboundNextForInboundOnlyIsCorrect", testOutboundNextForInboundOnlyIsCorrect),
|
||||
("testChannelInfrastructureIsNotLeaked", testChannelInfrastructureIsNotLeaked),
|
||||
("testAddingHandlersFirstWorks", testAddingHandlersFirstWorks),
|
||||
]
|
||||
}
|
||||
}
|
||||
|
|
|
@ -350,4 +350,58 @@ class ChannelPipelineTest: XCTestCase {
|
|||
XCTAssertNoThrow(try loop.syncShutdownGracefully())
|
||||
}()
|
||||
}
|
||||
|
||||
func testAddingHandlersFirstWorks() throws {
|
||||
final class ReceiveIntHandler: ChannelInboundHandler {
|
||||
typealias InboundIn = Int
|
||||
|
||||
var intReadCount = 0
|
||||
|
||||
func channelRead(ctx: ChannelHandlerContext, data: NIOAny) {
|
||||
if data.tryAs(type: Int.self) != nil {
|
||||
self.intReadCount += 1
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
final class TransformStringToIntHandler: ChannelInboundHandler {
|
||||
typealias InboundIn = String
|
||||
typealias InboundOut = Int
|
||||
|
||||
func channelRead(ctx: ChannelHandlerContext, data: NIOAny) {
|
||||
if let dataString = data.tryAs(type: String.self) {
|
||||
ctx.fireChannelRead(self.wrapInboundOut(dataString.count))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
final class TransformByteBufferToStringHandler: ChannelInboundHandler {
|
||||
typealias InboundIn = ByteBuffer
|
||||
typealias InboundOut = String
|
||||
|
||||
func channelRead(ctx: ChannelHandlerContext, data: NIOAny) {
|
||||
if var buffer = data.tryAs(type: ByteBuffer.self) {
|
||||
ctx.fireChannelRead(self.wrapInboundOut(buffer.readString(length: buffer.readableBytes)!))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let channel = EmbeddedChannel()
|
||||
defer {
|
||||
XCTAssertNoThrow(try channel.finish())
|
||||
}
|
||||
let countHandler = ReceiveIntHandler()
|
||||
var buffer = channel.allocator.buffer(capacity: 12)
|
||||
buffer.write(staticString: "hello, world")
|
||||
|
||||
XCTAssertNoThrow(try channel.pipeline.add(handler: countHandler).wait())
|
||||
XCTAssertFalse(try channel.writeInbound(buffer))
|
||||
XCTAssertEqual(countHandler.intReadCount, 0)
|
||||
|
||||
try channel.pipeline.addHandlers(TransformByteBufferToStringHandler(),
|
||||
TransformStringToIntHandler(),
|
||||
first: true).wait()
|
||||
XCTAssertFalse(try channel.writeInbound(buffer))
|
||||
XCTAssertEqual(countHandler.intReadCount, 1)
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue