1
2
3
4
5
6
7
8
9
10
11
12
13
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
27
28 @UnstableApi
29 public interface Http2Headers extends Headers<CharSequence, CharSequence, Http2Headers> {
30
31
32
33
34 enum PseudoHeaderName {
35
36
37
38 METHOD(":method", true),
39
40
41
42
43 SCHEME(":scheme", true),
44
45
46
47
48 AUTHORITY(":authority", true),
49
50
51
52
53 PATH(":path", true),
54
55
56
57
58 STATUS(":status", false),
59
60
61
62
63
64 PROTOCOL(":protocol", true);
65
66 private static final char PSEUDO_HEADER_PREFIX = ':';
67 private static final byte PSEUDO_HEADER_PREFIX_BYTE = (byte) PSEUDO_HEADER_PREFIX;
68
69 private final AsciiString value;
70 private final boolean requestOnly;
71
72 PseudoHeaderName(String value, boolean requestOnly) {
73 this.value = AsciiString.cached(value);
74 this.requestOnly = requestOnly;
75 }
76
77 public AsciiString value() {
78
79 return value;
80 }
81
82
83
84
85
86
87 public static boolean hasPseudoHeaderFormat(CharSequence headerName) {
88 if (headerName instanceof AsciiString) {
89 final AsciiString asciiHeaderName = (AsciiString) headerName;
90 return asciiHeaderName.length() > 0 && asciiHeaderName.byteAt(0) == PSEUDO_HEADER_PREFIX_BYTE;
91 } else {
92 return headerName.length() > 0 && headerName.charAt(0) == PSEUDO_HEADER_PREFIX;
93 }
94 }
95
96
97
98
99 public static boolean isPseudoHeader(CharSequence header) {
100 return getPseudoHeader(header) != null;
101 }
102
103
104
105
106 public static boolean isPseudoHeader(AsciiString header) {
107 return getPseudoHeader(header) != null;
108 }
109
110
111
112
113 public static boolean isPseudoHeader(String header) {
114 return getPseudoHeader(header) != null;
115 }
116
117
118
119
120
121
122 public static PseudoHeaderName getPseudoHeader(CharSequence header) {
123 if (header instanceof AsciiString) {
124 return getPseudoHeader((AsciiString) header);
125 }
126 return getPseudoHeaderName(header);
127 }
128
129 private static PseudoHeaderName getPseudoHeaderName(CharSequence header) {
130 int length = header.length();
131 if (length > 0 && header.charAt(0) == PSEUDO_HEADER_PREFIX) {
132 switch (length) {
133 case 5:
134
135 return ":path".contentEquals(header)? PATH : null;
136 case 7:
137
138 if (":method" == header) {
139 return METHOD;
140 }
141 if (":scheme" == header) {
142 return SCHEME;
143 }
144 if (":status" == header) {
145 return STATUS;
146 }
147 if (":method".contentEquals(header)) {
148 return METHOD;
149 }
150 if (":scheme".contentEquals(header)) {
151 return SCHEME;
152 }
153 return ":status".contentEquals(header)? STATUS : null;
154 case 9:
155
156 return ":protocol".contentEquals(header)? PROTOCOL : null;
157 case 10:
158
159 return ":authority".contentEquals(header)? AUTHORITY : null;
160 }
161 }
162 return null;
163 }
164
165
166
167
168
169
170 public static PseudoHeaderName getPseudoHeader(AsciiString header) {
171 int length = header.length();
172 if (length > 0 && header.charAt(0) == PSEUDO_HEADER_PREFIX) {
173 switch (length) {
174 case 5:
175
176 return PATH.value().equals(header) ? PATH : null;
177 case 7:
178 if (header == METHOD.value()) {
179 return METHOD;
180 }
181 if (header == SCHEME.value()) {
182 return SCHEME;
183 }
184 if (header == STATUS.value()) {
185 return STATUS;
186 }
187
188 if (METHOD.value().equals(header)) {
189 return METHOD;
190 }
191 if (SCHEME.value().equals(header)) {
192 return SCHEME;
193 }
194 return STATUS.value().equals(header)? STATUS : null;
195 case 9:
196
197 return PROTOCOL.value().equals(header)? PROTOCOL : null;
198 case 10:
199
200 return AUTHORITY.value().equals(header)? AUTHORITY : null;
201 }
202 }
203 return null;
204 }
205
206
207
208
209
210
211 public boolean isRequestOnly() {
212 return requestOnly;
213 }
214 }
215
216
217
218
219
220
221 @Override
222 Iterator<Entry<CharSequence, CharSequence>> iterator();
223
224
225
226
227
228
229 Iterator<CharSequence> valueIterator(CharSequence name);
230
231
232
233
234 Http2Headers method(CharSequence value);
235
236
237
238
239 Http2Headers scheme(CharSequence value);
240
241
242
243
244 Http2Headers authority(CharSequence value);
245
246
247
248
249 Http2Headers path(CharSequence value);
250
251
252
253
254 Http2Headers status(CharSequence value);
255
256
257
258
259 CharSequence method();
260
261
262
263
264 CharSequence scheme();
265
266
267
268
269 CharSequence authority();
270
271
272
273
274 CharSequence path();
275
276
277
278
279 CharSequence status();
280
281
282
283
284
285
286
287
288
289
290
291 boolean contains(CharSequence name, CharSequence value, boolean caseInsensitive);
292 }