View Javadoc
1   /*
2    * Copyright 2021 The Netty Project
3    *
4    * The Netty Project licenses this file to you under the Apache License,
5    * version 2.0 (the "License"); you may not use this file except in compliance
6    * with the License. You may obtain a copy of the License at:
7    *
8    *   https://www.apache.org/licenses/LICENSE-2.0
9    *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12   * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13   * License for the specific language governing permissions and limitations
14   * under the License.
15   */
16  package io.netty.handler.codec.http3;
17  
18  import io.netty.channel.ChannelHandlerContext;
19  import io.netty.channel.ChannelPromise;
20  import io.netty.util.ReferenceCountUtil;
21  import io.netty.util.internal.StringUtil;
22  import org.jetbrains.annotations.Nullable;
23  
24  final class Http3FrameValidationUtils {
25  
26      private Http3FrameValidationUtils() {
27          // no instances
28      }
29  
30      @SuppressWarnings("unchecked")
31      private static <T> T cast(Object msg) {
32          return (T) msg;
33      }
34  
35      private static <T> boolean isValid(Class<T> frameType, Object msg) {
36          return frameType.isInstance(msg);
37      }
38  
39      /**
40       * Check if the passed {@code msg} is of the {@code expectedFrameType} and return the expected type, else return
41       * {@code null}.
42       *
43       * @param expectedFrameType {@link Class} of the expected frame type.
44       * @param msg to validate.
45       * @param <T> Expected type.
46       * @return {@code msg} as expected frame type or {@code null} if it can not be converted to the expected type.
47       */
48      @Nullable
49      static <T> T validateFrameWritten(Class<T> expectedFrameType, Object msg) {
50          if (isValid(expectedFrameType, msg)) {
51              return cast(msg);
52          }
53          return null;
54      }
55  
56      /**
57       * Check if the passed {@code msg} is of the {@code expectedFrameType} and return the expected type, else return
58       * {@code null}.
59       *
60       * @param expectedFrameType {@link Class} of the expected frame type.
61       * @param msg to validate.
62       * @param <T> Expected type.
63       * @return {@code msg} as expected frame type or {@code null} if it can not be converted to the expected type.
64       */
65      @Nullable
66      static <T> T validateFrameRead(Class<T> expectedFrameType, Object msg) {
67          if (isValid(expectedFrameType, msg)) {
68              return cast(msg);
69          }
70          return null;
71      }
72  
73      /**
74       * Handle unexpected frame type by failing the passed {@link ChannelPromise}.
75       *
76       * @param promise to fail.
77       * @param frame which is unexpected.
78       */
79      static void frameTypeUnexpected(ChannelPromise promise, Object frame) {
80          String type = StringUtil.simpleClassName(frame);
81          ReferenceCountUtil.release(frame);
82          promise.setFailure(new Http3Exception(Http3ErrorCode.H3_FRAME_UNEXPECTED,
83                  "Frame of type " + type + " unexpected"));
84      }
85  
86      /**
87       * Handle unexpected frame type by propagating a connection error with code:
88       * {@link Http3ErrorCode#H3_FRAME_UNEXPECTED}.
89       *
90       * @param ctx to use for propagation of failure.
91       * @param frame which is unexpected.
92       */
93      static void frameTypeUnexpected(ChannelHandlerContext ctx, Object frame) {
94          ReferenceCountUtil.release(frame);
95          Http3CodecUtils.connectionError(ctx, Http3ErrorCode.H3_FRAME_UNEXPECTED, "Frame type unexpected", true);
96      }
97  }