1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package io.netty.handler.codec.http3;
17
18 import io.netty.channel.ChannelHandlerContext;
19 import io.netty.channel.socket.ChannelInputShutdownReadComplete;
20
21 import static io.netty.handler.codec.http3.Http3RequestStreamValidationUtils.INVALID_FRAME_READ;
22 import static io.netty.handler.codec.http3.Http3RequestStreamValidationUtils.sendStreamAbandonedIfRequired;
23 import static io.netty.handler.codec.http3.Http3RequestStreamValidationUtils.validateDataFrameRead;
24 import static io.netty.handler.codec.http3.Http3RequestStreamValidationUtils.validateHeaderFrameRead;
25 import static io.netty.handler.codec.http3.Http3RequestStreamValidationUtils.validateOnStreamClosure;
26
27 final class Http3PushStreamClientValidationHandler
28 extends Http3FrameTypeInboundValidationHandler<Http3RequestStreamFrame> {
29 private final QpackAttributes qpackAttributes;
30 private final QpackDecoder qpackDecoder;
31 private final Http3RequestStreamCodecState decodeState;
32
33 private long expectedLength = -1;
34 private long seenLength;
35
36 Http3PushStreamClientValidationHandler(QpackAttributes qpackAttributes, QpackDecoder qpackDecoder,
37 Http3RequestStreamCodecState decodeState) {
38 super(Http3RequestStreamFrame.class);
39 this.qpackAttributes = qpackAttributes;
40 this.qpackDecoder = qpackDecoder;
41 this.decodeState = decodeState;
42 }
43
44 @Override
45 void channelRead(ChannelHandlerContext ctx, Http3RequestStreamFrame frame) {
46 if (frame instanceof Http3PushPromiseFrame) {
47 ctx.fireChannelRead(frame);
48 return;
49 }
50
51 if (frame instanceof Http3HeadersFrame) {
52 Http3HeadersFrame headersFrame = (Http3HeadersFrame) frame;
53 long maybeContentLength = validateHeaderFrameRead(headersFrame, ctx, decodeState);
54 if (maybeContentLength >= 0) {
55 expectedLength = maybeContentLength;
56 } else if (maybeContentLength == INVALID_FRAME_READ) {
57 return;
58 }
59 }
60
61 if (frame instanceof Http3DataFrame) {
62 final Http3DataFrame dataFrame = (Http3DataFrame) frame;
63 long maybeContentLength = validateDataFrameRead(dataFrame, ctx, expectedLength, seenLength, false);
64 if (maybeContentLength >= 0) {
65 seenLength = maybeContentLength;
66 } else if (maybeContentLength == INVALID_FRAME_READ) {
67 return;
68 }
69 }
70 ctx.fireChannelRead(frame);
71 }
72
73 @Override
74 public void userEventTriggered(ChannelHandlerContext ctx, Object evt) {
75 if (evt == ChannelInputShutdownReadComplete.INSTANCE) {
76 sendStreamAbandonedIfRequired(ctx, qpackAttributes, qpackDecoder, decodeState);
77 if (!validateOnStreamClosure(ctx, expectedLength, seenLength, false)) {
78 return;
79 }
80 }
81 ctx.fireUserEventTriggered(evt);
82 }
83
84 @Override
85 public boolean isSharable() {
86
87 return false;
88 }
89 }