1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package io.netty.handler.codec.http3;
18
19 import io.netty.channel.ChannelHandler;
20 import io.netty.channel.ChannelHandlerContext;
21 import io.netty.handler.codec.http3.Http3FrameCodec.Http3FrameCodecFactory;
22 import org.jetbrains.annotations.Nullable;
23
24 import java.util.function.LongFunction;
25 import java.util.function.Supplier;
26
27 final class Http3UnidirectionalStreamInboundClientHandler extends Http3UnidirectionalStreamInboundHandler {
28 private final LongFunction<ChannelHandler> pushStreamHandlerFactory;
29
30 Http3UnidirectionalStreamInboundClientHandler(
31 Http3FrameCodecFactory codecFactory,
32 Http3ControlStreamInboundHandler localControlStreamHandler,
33 Http3ControlStreamOutboundHandler remoteControlStreamHandler,
34 @Nullable LongFunction<ChannelHandler> unknownStreamHandlerFactory,
35 @Nullable LongFunction<ChannelHandler> pushStreamHandlerFactory,
36 Supplier<ChannelHandler> qpackEncoderHandlerFactory, Supplier<ChannelHandler> qpackDecoderHandlerFactory) {
37 super(codecFactory, localControlStreamHandler, remoteControlStreamHandler, unknownStreamHandlerFactory,
38 qpackEncoderHandlerFactory, qpackDecoderHandlerFactory);
39 this.pushStreamHandlerFactory = pushStreamHandlerFactory == null ? __ -> ReleaseHandler.INSTANCE :
40 pushStreamHandlerFactory;
41 }
42
43 @Override
44 void initPushStream(ChannelHandlerContext ctx, long pushId) {
45
46 Long maxPushId = remoteControlStreamHandler.sentMaxPushId();
47 if (maxPushId == null) {
48 Http3CodecUtils.connectionError(ctx, Http3ErrorCode.H3_ID_ERROR,
49 "Received push stream before sending MAX_PUSH_ID frame.", false);
50 } else if (maxPushId < pushId) {
51 Http3CodecUtils.connectionError(ctx, Http3ErrorCode.H3_ID_ERROR,
52 "Received push stream with ID " + pushId + " greater than the max push ID " + maxPushId
53 + '.', false);
54 } else {
55
56 final ChannelHandler pushStreamHandler = pushStreamHandlerFactory.apply(pushId);
57 ctx.pipeline().replace(this, null, pushStreamHandler);
58 }
59 }
60 }