when iterating a NIOAsyncChannelInboundStream<HTTP2Frame.FramePayload>
, is there any point in checking the FramePayload
s for endStream
?
No, NIOAsyncChannel is half-closure aware and should appropriately terminate the inbound stream after that message.
this doesn’t seem to be the behavior i’m observing.
var body:[UInt8] = []
body.reserveCapacity(length)
while let payload:HTTP2Frame.FramePayload = try await inbound.next()
{
guard
case .data(let payload) = payload,
case .byteBuffer(let buffer) = payload.data
else
{
continue
}
if buffer.readableBytes <= length - body.count
{
buffer.withUnsafeReadableBytes { body += $0 }
Log[.debug] = "received \(body.count) of \(length) bytes (end of stream: \(payload.endStream))"
}
else
{
return .badRequest("Payload too large")
}
}
Log[.debug] = "stream finished"
debug: bound to :::8443
debug: received 21 of 21 bytes (end of stream: true)
one client timeout duration later…
debug: stream finished
should i file a bug?
Oh good catch, I went back and double-checked.
This is probably not a bug: you can still receive frames on a stream that has had END_STREAM set on it. In particular, WINDOW_UPDATE frames can still be received, and potentially other extension control frames.
For this reason, swift-nio-http2 doesn't send half-closure on END_STREAM, which means NIOAsyncChannel doesn't help you here.
Sorry to mislead you: in this case, END_STREAM is important and you should observe it.
Note, however, that if you also send END_STREAM then everything should tear itself down appropriately.