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 Http3Settings.NonStandardHttp3SettingsValidator nonStandardSettingsValidator,
33 Http3ControlStreamInboundHandler localControlStreamHandler,
34 Http3ControlStreamOutboundHandler remoteControlStreamHandler,
35 @Nullable LongFunction<ChannelHandler> unknownStreamHandlerFactory,
36 @Nullable LongFunction<ChannelHandler> pushStreamHandlerFactory,
37 Supplier<ChannelHandler> qpackEncoderHandlerFactory, Supplier<ChannelHandler> qpackDecoderHandlerFactory) {
38 super(codecFactory, nonStandardSettingsValidator,
39 localControlStreamHandler, remoteControlStreamHandler, unknownStreamHandlerFactory,
40 qpackEncoderHandlerFactory, qpackDecoderHandlerFactory);
41 this.pushStreamHandlerFactory = pushStreamHandlerFactory == null ? __ -> ReleaseHandler.INSTANCE :
42 pushStreamHandlerFactory;
43 }
44
45 @Override
46 void initPushStream(ChannelHandlerContext ctx, long pushId) {
47
48 Long maxPushId = remoteControlStreamHandler.sentMaxPushId();
49 if (maxPushId == null) {
50 Http3CodecUtils.connectionError(ctx, Http3ErrorCode.H3_ID_ERROR,
51 "Received push stream before sending MAX_PUSH_ID frame.", false);
52 } else if (maxPushId < pushId) {
53 Http3CodecUtils.connectionError(ctx, Http3ErrorCode.H3_ID_ERROR,
54 "Received push stream with ID " + pushId + " greater than the max push ID " + maxPushId
55 + '.', false);
56 } else {
57
58 final ChannelHandler pushStreamHandler = pushStreamHandlerFactory.apply(pushId);
59 ctx.pipeline().replace(this, null, pushStreamHandler);
60 }
61 }
62 }