View Javadoc
1   /*
2    * Copyright 2014 The Netty Project
3    *
4    * The Netty Project licenses this file to you under the Apache License, version 2.0 (the
5    * "License"); you may not use this file except in compliance with the License. You may obtain a
6    * copy of the License at:
7    *
8    * http://www.apache.org/licenses/LICENSE-2.0
9    *
10   * Unless required by applicable law or agreed to in writing, software distributed under the License
11   * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
12   * or implied. See the License for the specific language governing permissions and limitations under
13   * the License.
14   */
15  
16  package io.netty.handler.codec.http2;
17  
18  import io.netty.handler.codec.Headers;
19  import io.netty.util.AsciiString;
20  import io.netty.util.internal.UnstableApi;
21  
22  import java.util.Iterator;
23  import java.util.Map.Entry;
24  
25  /**
26   * A collection of headers sent or received via HTTP/2.
27   */
28  @UnstableApi
29  public interface Http2Headers extends Headers<CharSequence, CharSequence, Http2Headers> {
30  
31      /**
32       * HTTP/2 pseudo-headers names.
33       */
34      enum PseudoHeaderName {
35          /**
36           * {@code :method}.
37           */
38          METHOD(":method", true),
39  
40          /**
41           * {@code :scheme}.
42           */
43          SCHEME(":scheme", true),
44  
45          /**
46           * {@code :authority}.
47           */
48          AUTHORITY(":authority", true),
49  
50          /**
51           * {@code :path}.
52           */
53          PATH(":path", true),
54  
55          /**
56           * {@code :status}.
57           */
58          STATUS(":status", false);
59  
60          private static final char PSEUDO_HEADER_PREFIX = ':';
61          private static final byte PSEUDO_HEADER_PREFIX_BYTE = (byte) PSEUDO_HEADER_PREFIX;
62  
63          private final AsciiString value;
64          private final boolean requestOnly;
65          private static final CharSequenceMap<PseudoHeaderName> PSEUDO_HEADERS = new CharSequenceMap<PseudoHeaderName>();
66  
67          static {
68              for (PseudoHeaderName pseudoHeader : PseudoHeaderName.values()) {
69                  PSEUDO_HEADERS.add(pseudoHeader.value(), pseudoHeader);
70              }
71          }
72  
73          PseudoHeaderName(String value, boolean requestOnly) {
74              this.value = AsciiString.cached(value);
75              this.requestOnly = requestOnly;
76          }
77  
78          public AsciiString value() {
79              // Return a slice so that the buffer gets its own reader index.
80              return value;
81          }
82  
83          /**
84           * Indicates whether the specified header follows the pseudo-header format (begins with ':' character)
85           *
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/2 pseudo header.
99           */
100         public static boolean isPseudoHeader(CharSequence header) {
101             return PSEUDO_HEADERS.contains(header);
102         }
103 
104         /**
105          * Returns the {@link PseudoHeaderName} corresponding to the specified header name.
106          *
107          * @return corresponding {@link PseudoHeaderName} if any, {@code null} otherwise.
108          */
109         public static PseudoHeaderName getPseudoHeader(CharSequence header) {
110             return PSEUDO_HEADERS.get(header);
111         }
112 
113         /**
114          * Indicates whether the pseudo-header is to be used in a request context.
115          *
116          * @return {@code true} if the pseudo-header is to be used in a request context
117          */
118         public boolean isRequestOnly() {
119             return requestOnly;
120         }
121     }
122 
123     /**
124      * Returns an iterator over all HTTP/2 headers. The iteration order is as follows:
125      *   1. All pseudo headers (order not specified).
126      *   2. All non-pseudo headers (in insertion order).
127      */
128     @Override
129     Iterator<Entry<CharSequence, CharSequence>> iterator();
130 
131     /**
132      * Equivalent to {@link #getAll(Object)} but no intermediate list is generated.
133      * @param name the name of the header to retrieve
134      * @return an {@link Iterator} of header values corresponding to {@code name}.
135      */
136     Iterator<CharSequence> valueIterator(CharSequence name);
137 
138     /**
139      * Sets the {@link PseudoHeaderName#METHOD} header or {@code null} if there is no such header
140      */
141     Http2Headers method(CharSequence value);
142 
143     /**
144      * Sets the {@link PseudoHeaderName#SCHEME} header if there is no such header
145      */
146     Http2Headers scheme(CharSequence value);
147 
148     /**
149      * Sets the {@link PseudoHeaderName#AUTHORITY} header or {@code null} if there is no such header
150      */
151     Http2Headers authority(CharSequence value);
152 
153     /**
154      * Sets the {@link PseudoHeaderName#PATH} header or {@code null} if there is no such header
155      */
156     Http2Headers path(CharSequence value);
157 
158     /**
159      * Sets the {@link PseudoHeaderName#STATUS} header or {@code null} if there is no such header
160      */
161     Http2Headers status(CharSequence value);
162 
163     /**
164      * Gets the {@link PseudoHeaderName#METHOD} header or {@code null} if there is no such header
165      */
166     CharSequence method();
167 
168     /**
169      * Gets the {@link PseudoHeaderName#SCHEME} header or {@code null} if there is no such header
170      */
171     CharSequence scheme();
172 
173     /**
174      * Gets the {@link PseudoHeaderName#AUTHORITY} header or {@code null} if there is no such header
175      */
176     CharSequence authority();
177 
178     /**
179      * Gets the {@link PseudoHeaderName#PATH} header or {@code null} if there is no such header
180      */
181     CharSequence path();
182 
183     /**
184      * Gets the {@link PseudoHeaderName#STATUS} header or {@code null} if there is no such header
185      */
186     CharSequence status();
187 
188     /**
189      * Returns {@code true} if a header with the {@code name} and {@code value} exists, {@code false} otherwise.
190      * <p>
191      * If {@code caseInsensitive} is {@code true} then a case insensitive compare is done on the value.
192      *
193      * @param name the name of the header to find
194      * @param value the value of the header to find
195      * @param caseInsensitive {@code true} then a case insensitive compare is run to compare values.
196      * otherwise a case sensitive compare is run to compare values.
197      */
198     boolean contains(CharSequence name, CharSequence value, boolean caseInsensitive);
199 }