i had naïvely tried merging NIOAsyncChannelInboundStream
into another AsyncThrowingStream
, as i mentioned in another thread. but then i wondered what would happen if an attacker spammed a ton of HTTP/2 frames, or even if a legitimate user had a long-running file upload.
extension AsyncSequence where Element:Sendable
{
consuming
func forward<T>(
to stream:AsyncThrowingStream<T, any Error>.Continuation,
by transform:(Element) throws -> T ) async rethrows
{
do
{
for try await element:Element in self
{
stream.yield(try transform(element))
}
stream.finish()
}
catch let error
{
stream.finish(throwing: error)
}
}
}
as i understand it, iterating NIOAsyncChannelInboundStream
destroys any backpressure that might have been in effect for that stream. as a short term fix, i could apply .bufferingOldest(10)
to the stream buffering policy, but that would probably break the file uploads.
so maybe this is not the way to inject additional events into a NIOAsyncChannelInboundStream
. in which case, what should i be doing instead?
while researching the subject, i considered using AsyncChannel
. but according to this post AsyncChannel
doesn’t really have great performance for this sort of thing. AsyncChannel
also belongs to the swift-async-algorithms
package, which is very new and has not yet gone through the process of dividing its code into smaller modules. notably, adding a dependency to it would not only pull in all of the AsyncAlgorithms
module, but also all three constituent modules of the swift-collections
package, only one of which is a constituent of swift-nio-http
itself.