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