View Javadoc
1   /*
2    * Copyright 2020 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.handler.codec.Headers;
19  import io.netty.util.AsciiString;
20  import org.jetbrains.annotations.Nullable;
21  
22  import java.util.Iterator;
23  import java.util.Map.Entry;
24  
25  public interface Http3Headers extends Headers<CharSequence, CharSequence, Http3Headers> {
26  
27      /**
28       * HTTP/2 (and HTTP/3) pseudo-headers names.
29       */
30      enum PseudoHeaderName {
31          /**
32           * {@code :method}.
33           */
34          METHOD(":method", true, 0x1),
35  
36          /**
37           * {@code :scheme}.
38           */
39          SCHEME(":scheme", true, 0x2),
40  
41          /**
42           * {@code :authority}.
43           */
44          AUTHORITY(":authority", true, 0x4),
45  
46          /**
47           * {@code :path}.
48           */
49          PATH(":path", true, 0x8),
50  
51          /**
52           * {@code :status}.
53           */
54          STATUS(":status", false, 0x10);
55  
56          private static final char PSEUDO_HEADER_PREFIX = ':';
57          private static final byte PSEUDO_HEADER_PREFIX_BYTE = (byte) PSEUDO_HEADER_PREFIX;
58  
59          private final AsciiString value;
60          private final boolean requestOnly;
61          // The position of the bit in the flag indicates the type of the header field
62          private final int flag;
63          private static final CharSequenceMap<PseudoHeaderName> PSEUDO_HEADERS = new CharSequenceMap<PseudoHeaderName>();
64  
65          static {
66              for (PseudoHeaderName pseudoHeader : PseudoHeaderName.values()) {
67                  PSEUDO_HEADERS.add(pseudoHeader.value(), pseudoHeader);
68              }
69          }
70  
71          PseudoHeaderName(String value, boolean requestOnly, int flag) {
72              this.value = AsciiString.cached(value);
73              this.requestOnly = requestOnly;
74              this.flag = flag;
75          }
76  
77          public AsciiString value() {
78              // Return a slice so that the buffer gets its own reader index.
79              return value;
80          }
81  
82          /**
83           * Indicates whether the specified header follows the pseudo-header format (begins with ':' character)
84           *
85           * @param headerName    the header name to check.
86           * @return              {@code true} if the header follow the pseudo-header format
87           */
88          public static boolean hasPseudoHeaderFormat(CharSequence headerName) {
89              if (headerName instanceof AsciiString) {
90                  final AsciiString asciiHeaderName = (AsciiString) headerName;
91                  return asciiHeaderName.length() > 0 && asciiHeaderName.byteAt(0) == PSEUDO_HEADER_PREFIX_BYTE;
92              } else {
93                  return headerName.length() > 0 && headerName.charAt(0) == PSEUDO_HEADER_PREFIX;
94              }
95          }
96  
97          /**
98           * Indicates whether the given header name is a valid HTTP/3 pseudo header.
99           *
100          * @param name  the header name.
101          * @return      {@code true} if the given header name is a valid HTTP/3 pseudo header, {@code false} otherwise.
102          */
103         public static boolean isPseudoHeader(CharSequence name) {
104             return PSEUDO_HEADERS.contains(name);
105         }
106 
107         /**
108          * Returns the {@link PseudoHeaderName} corresponding to the specified header name.
109          *
110          * @param name  the header name.
111          * @return corresponding {@link PseudoHeaderName} if any, {@code null} otherwise.
112          */
113         @Nullable
114         public static PseudoHeaderName getPseudoHeader(CharSequence name) {
115             return PSEUDO_HEADERS.get(name);
116         }
117 
118         /**
119          * Indicates whether the pseudo-header is to be used in a request context.
120          *
121          * @return {@code true} if the pseudo-header is to be used in a request context
122          */
123         public boolean isRequestOnly() {
124             return requestOnly;
125         }
126 
127         public int getFlag() {
128              return flag;
129         }
130     }
131 
132     /**
133      * Returns an iterator over all HTTP/3 headers. The iteration order is as follows:
134      *   1. All pseudo headers (order not specified).
135      *   2. All non-pseudo headers (in insertion order).
136      */
137     @Override
138     Iterator<Entry<CharSequence, CharSequence>> iterator();
139 
140     /**
141      * Equivalent to {@link #getAll(Object)} but no intermediate list is generated.
142      * @param name the name of the header to retrieve
143      * @return an {@link Iterator} of header values corresponding to {@code name}.
144      */
145     Iterator<CharSequence> valueIterator(CharSequence name);
146 
147     /**
148      * Sets the {@link PseudoHeaderName#METHOD} header
149      *
150      * @param value the value for the header.
151      * @return      this instance itself.
152      */
153     Http3Headers method(CharSequence value);
154 
155     /**
156      * Sets the {@link PseudoHeaderName#SCHEME} header
157      *
158      * @param value the value for the header.
159      * @return      this instance itself.
160      */
161     Http3Headers scheme(CharSequence value);
162 
163     /**
164      * Sets the {@link PseudoHeaderName#AUTHORITY} header
165      *
166      * @param value the value for the header.
167      * @return      this instance itself.
168      */
169     Http3Headers authority(CharSequence value);
170 
171     /**
172      * Sets the {@link PseudoHeaderName#PATH} header
173      *
174      * @param value the value for the header.
175      * @return      this instance itself.
176      */
177     Http3Headers path(CharSequence value);
178 
179     /**
180      * Sets the {@link PseudoHeaderName#STATUS} header
181      *
182      * @param value the value for the header.
183      * @return      this instance itself.
184      */
185     Http3Headers status(CharSequence value);
186 
187     /**
188      * Gets the {@link PseudoHeaderName#METHOD} header or {@code null} if there is no such header
189      *
190      * @return the value of the header.
191      */
192     @Nullable
193     CharSequence method();
194 
195     /**
196      * Gets the {@link PseudoHeaderName#SCHEME} header or {@code null} if there is no such header
197      *
198      * @return the value of the header.
199      */
200     @Nullable
201     CharSequence scheme();
202 
203     /**
204      * Gets the {@link PseudoHeaderName#AUTHORITY} header or {@code null} if there is no such header
205      *
206      * @return the value of the header.
207      */
208     @Nullable
209     CharSequence authority();
210 
211     /**
212      * Gets the {@link PseudoHeaderName#PATH} header or {@code null} if there is no such header
213      *
214      * @return the value of the header.
215      */
216     @Nullable
217     CharSequence path();
218 
219     /**
220      * Gets the {@link PseudoHeaderName#STATUS} header or {@code null} if there is no such header
221      *
222      * @return the value of the header.
223      */
224     @Nullable
225     CharSequence status();
226 
227     /**
228      * Returns {@code true} if a header with the {@code name} and {@code value} exists, {@code false} otherwise.
229      * <p>
230      * If {@code caseInsensitive} is {@code true} then a case insensitive compare is done on the value.
231      *
232      * @param name              the name of the header to find
233      * @param value             the value of the header to find
234      * @param caseInsensitive   {@code true} then a case insensitive compare is run to compare values.
235      * otherwise a case sensitive compare is run to compare values.
236      * @return                  {@code true} if its contained, {@code false} otherwise.
237      */
238     boolean contains(CharSequence name, CharSequence value, boolean caseInsensitive);
239 }