1
18
19 package io.undertow.util;
20
21 import java.io.UnsupportedEncodingException;
22 import java.lang.reflect.Field;
23 import java.lang.reflect.Modifier;
24 import java.net.URLDecoder;
25 import java.security.AccessController;
26 import java.security.PrivilegedAction;
27 import java.util.Collections;
28 import java.util.HashMap;
29 import java.util.Map;
30
31
36 public final class Headers {
37
38 private Headers() {
39 }
40
41
42
43 public static final String ACCEPT_STRING = "Accept";
44 public static final String ACCEPT_CHARSET_STRING = "Accept-Charset";
45 public static final String ACCEPT_ENCODING_STRING = "Accept-Encoding";
46 public static final String ACCEPT_LANGUAGE_STRING = "Accept-Language";
47 public static final String ACCEPT_RANGES_STRING = "Accept-Ranges";
48 public static final String AGE_STRING = "Age";
49 public static final String ALLOW_STRING = "Allow";
50 public static final String AUTHENTICATION_INFO_STRING = "Authentication-Info";
51 public static final String AUTHORIZATION_STRING = "Authorization";
52 public static final String CACHE_CONTROL_STRING = "Cache-Control";
53 public static final String COOKIE_STRING = "Cookie";
54 public static final String COOKIE2_STRING = "Cookie2";
55 public static final String CONNECTION_STRING = "Connection";
56 public static final String CONTENT_DISPOSITION_STRING = "Content-Disposition";
57 public static final String CONTENT_ENCODING_STRING = "Content-Encoding";
58 public static final String CONTENT_LANGUAGE_STRING = "Content-Language";
59 public static final String CONTENT_LENGTH_STRING = "Content-Length";
60 public static final String CONTENT_LOCATION_STRING = "Content-Location";
61 public static final String CONTENT_MD5_STRING = "Content-MD5";
62 public static final String CONTENT_RANGE_STRING = "Content-Range";
63 public static final String CONTENT_SECURITY_POLICY_STRING = "Content-Security-Policy";
64 public static final String CONTENT_TYPE_STRING = "Content-Type";
65 public static final String DATE_STRING = "Date";
66 public static final String ETAG_STRING = "ETag";
67 public static final String EXPECT_STRING = "Expect";
68 public static final String EXPIRES_STRING = "Expires";
69 public static final String FORWARDED_STRING = "Forwarded";
70 public static final String FROM_STRING = "From";
71 public static final String HOST_STRING = "Host";
72 public static final String IF_MATCH_STRING = "If-Match";
73 public static final String IF_MODIFIED_SINCE_STRING = "If-Modified-Since";
74 public static final String IF_NONE_MATCH_STRING = "If-None-Match";
75 public static final String IF_RANGE_STRING = "If-Range";
76 public static final String IF_UNMODIFIED_SINCE_STRING = "If-Unmodified-Since";
77 public static final String LAST_MODIFIED_STRING = "Last-Modified";
78 public static final String LOCATION_STRING = "Location";
79 public static final String MAX_FORWARDS_STRING = "Max-Forwards";
80 public static final String ORIGIN_STRING = "Origin";
81 public static final String PRAGMA_STRING = "Pragma";
82 public static final String PROXY_AUTHENTICATE_STRING = "Proxy-Authenticate";
83 public static final String PROXY_AUTHORIZATION_STRING = "Proxy-Authorization";
84 public static final String RANGE_STRING = "Range";
85 public static final String REFERER_STRING = "Referer";
86 public static final String REFERRER_POLICY_STRING = "Referrer-Policy";
87 public static final String REFRESH_STRING = "Refresh";
88 public static final String RETRY_AFTER_STRING = "Retry-After";
89 public static final String SEC_WEB_SOCKET_ACCEPT_STRING = "Sec-WebSocket-Accept";
90 public static final String SEC_WEB_SOCKET_EXTENSIONS_STRING = "Sec-WebSocket-Extensions";
91 public static final String SEC_WEB_SOCKET_KEY_STRING = "Sec-WebSocket-Key";
92 public static final String SEC_WEB_SOCKET_KEY1_STRING = "Sec-WebSocket-Key1";
93 public static final String SEC_WEB_SOCKET_KEY2_STRING = "Sec-WebSocket-Key2";
94 public static final String SEC_WEB_SOCKET_LOCATION_STRING = "Sec-WebSocket-Location";
95 public static final String SEC_WEB_SOCKET_ORIGIN_STRING = "Sec-WebSocket-Origin";
96 public static final String SEC_WEB_SOCKET_PROTOCOL_STRING = "Sec-WebSocket-Protocol";
97 public static final String SEC_WEB_SOCKET_VERSION_STRING = "Sec-WebSocket-Version";
98 public static final String SERVER_STRING = "Server";
99 public static final String SERVLET_ENGINE_STRING = "Servlet-Engine";
100 public static final String SET_COOKIE_STRING = "Set-Cookie";
101 public static final String SET_COOKIE2_STRING = "Set-Cookie2";
102 public static final String SSL_CLIENT_CERT_STRING = "SSL_CLIENT_CERT";
103 public static final String SSL_CIPHER_STRING = "SSL_CIPHER";
104 public static final String SSL_SESSION_ID_STRING = "SSL_SESSION_ID";
105 public static final String SSL_CIPHER_USEKEYSIZE_STRING = "SSL_CIPHER_USEKEYSIZE";
106 public static final String STATUS_STRING = "Status";
107 public static final String STRICT_TRANSPORT_SECURITY_STRING = "Strict-Transport-Security";
108 public static final String TE_STRING = "TE";
109 public static final String TRAILER_STRING = "Trailer";
110 public static final String TRANSFER_ENCODING_STRING = "Transfer-Encoding";
111 public static final String UPGRADE_STRING = "Upgrade";
112 public static final String USER_AGENT_STRING = "User-Agent";
113 public static final String VARY_STRING = "Vary";
114 public static final String VIA_STRING = "Via";
115 public static final String WARNING_STRING = "Warning";
116 public static final String WWW_AUTHENTICATE_STRING = "WWW-Authenticate";
117 public static final String X_CONTENT_TYPE_OPTIONS_STRING = "X-Content-Type-Options";
118 public static final String X_DISABLE_PUSH_STRING = "X-Disable-Push";
119 public static final String X_FORWARDED_FOR_STRING = "X-Forwarded-For";
120 public static final String X_FORWARDED_PROTO_STRING = "X-Forwarded-Proto";
121 public static final String X_FORWARDED_HOST_STRING = "X-Forwarded-Host";
122 public static final String X_FORWARDED_PORT_STRING = "X-Forwarded-Port";
123 public static final String X_FORWARDED_SERVER_STRING = "X-Forwarded-Server";
124 public static final String X_FRAME_OPTIONS_STRING = "X-Frame-Options";
125 public static final String X_XSS_PROTECTION_STRING = "X-Xss-Protection";
126
127
128
129 public static final HttpString ACCEPT = new HttpString(ACCEPT_STRING, 1);
130 public static final HttpString ACCEPT_CHARSET = new HttpString(ACCEPT_CHARSET_STRING, 2);
131 public static final HttpString ACCEPT_ENCODING = new HttpString(ACCEPT_ENCODING_STRING, 3);
132 public static final HttpString ACCEPT_LANGUAGE = new HttpString(ACCEPT_LANGUAGE_STRING, 4);
133 public static final HttpString ACCEPT_RANGES = new HttpString(ACCEPT_RANGES_STRING, 5);
134 public static final HttpString AGE = new HttpString(AGE_STRING, 6);
135 public static final HttpString ALLOW = new HttpString(ALLOW_STRING, 7);
136 public static final HttpString AUTHENTICATION_INFO = new HttpString(AUTHENTICATION_INFO_STRING, 8);
137 public static final HttpString AUTHORIZATION = new HttpString(AUTHORIZATION_STRING, 9);
138 public static final HttpString CACHE_CONTROL = new HttpString(CACHE_CONTROL_STRING, 10);
139 public static final HttpString CONNECTION = new HttpString(CONNECTION_STRING, 11);
140 public static final HttpString CONTENT_DISPOSITION = new HttpString(CONTENT_DISPOSITION_STRING, 12);
141 public static final HttpString CONTENT_ENCODING = new HttpString(CONTENT_ENCODING_STRING, 13);
142 public static final HttpString CONTENT_LANGUAGE = new HttpString(CONTENT_LANGUAGE_STRING, 14);
143 public static final HttpString CONTENT_LENGTH = new HttpString(CONTENT_LENGTH_STRING, 15);
144 public static final HttpString CONTENT_LOCATION = new HttpString(CONTENT_LOCATION_STRING, 16);
145 public static final HttpString CONTENT_MD5 = new HttpString(CONTENT_MD5_STRING, 17);
146 public static final HttpString CONTENT_RANGE = new HttpString(CONTENT_RANGE_STRING, 18);
147 public static final HttpString CONTENT_SECURITY_POLICY = new HttpString(CONTENT_SECURITY_POLICY_STRING, 19);
148 public static final HttpString CONTENT_TYPE = new HttpString(CONTENT_TYPE_STRING, 20);
149 public static final HttpString COOKIE = new HttpString(COOKIE_STRING, 21);
150 public static final HttpString COOKIE2 = new HttpString(COOKIE2_STRING, 22);
151 public static final HttpString DATE = new HttpString(DATE_STRING, 23);
152 public static final HttpString ETAG = new HttpString(ETAG_STRING, 24);
153 public static final HttpString EXPECT = new HttpString(EXPECT_STRING, 25);
154 public static final HttpString EXPIRES = new HttpString(EXPIRES_STRING, 26);
155 public static final HttpString FORWARDED = new HttpString(FORWARDED_STRING, 27);
156 public static final HttpString FROM = new HttpString(FROM_STRING, 28);
157 public static final HttpString HOST = new HttpString(HOST_STRING, 29);
158 public static final HttpString IF_MATCH = new HttpString(IF_MATCH_STRING, 30);
159 public static final HttpString IF_MODIFIED_SINCE = new HttpString(IF_MODIFIED_SINCE_STRING, 31);
160 public static final HttpString IF_NONE_MATCH = new HttpString(IF_NONE_MATCH_STRING, 32);
161 public static final HttpString IF_RANGE = new HttpString(IF_RANGE_STRING, 33);
162 public static final HttpString IF_UNMODIFIED_SINCE = new HttpString(IF_UNMODIFIED_SINCE_STRING, 34);
163 public static final HttpString LAST_MODIFIED = new HttpString(LAST_MODIFIED_STRING, 35);
164 public static final HttpString LOCATION = new HttpString(LOCATION_STRING, 36);
165 public static final HttpString MAX_FORWARDS = new HttpString(MAX_FORWARDS_STRING, 37);
166 public static final HttpString ORIGIN = new HttpString(ORIGIN_STRING, 38);
167 public static final HttpString PRAGMA = new HttpString(PRAGMA_STRING, 39);
168 public static final HttpString PROXY_AUTHENTICATE = new HttpString(PROXY_AUTHENTICATE_STRING, 40);
169 public static final HttpString PROXY_AUTHORIZATION = new HttpString(PROXY_AUTHORIZATION_STRING, 41);
170 public static final HttpString RANGE = new HttpString(RANGE_STRING, 42);
171 public static final HttpString REFERER = new HttpString(REFERER_STRING, 43);
172 public static final HttpString REFERRER_POLICY = new HttpString(REFERRER_POLICY_STRING, 44);
173 public static final HttpString REFRESH = new HttpString(REFRESH_STRING, 45);
174 public static final HttpString RETRY_AFTER = new HttpString(RETRY_AFTER_STRING, 46);
175 public static final HttpString SEC_WEB_SOCKET_ACCEPT = new HttpString(SEC_WEB_SOCKET_ACCEPT_STRING, 47);
176 public static final HttpString SEC_WEB_SOCKET_EXTENSIONS = new HttpString(SEC_WEB_SOCKET_EXTENSIONS_STRING, 48);
177 public static final HttpString SEC_WEB_SOCKET_KEY = new HttpString(SEC_WEB_SOCKET_KEY_STRING, 49);
178 public static final HttpString SEC_WEB_SOCKET_KEY1 = new HttpString(SEC_WEB_SOCKET_KEY1_STRING, 50);
179 public static final HttpString SEC_WEB_SOCKET_KEY2 = new HttpString(SEC_WEB_SOCKET_KEY2_STRING, 51);
180 public static final HttpString SEC_WEB_SOCKET_LOCATION = new HttpString(SEC_WEB_SOCKET_LOCATION_STRING, 52);
181 public static final HttpString SEC_WEB_SOCKET_ORIGIN = new HttpString(SEC_WEB_SOCKET_ORIGIN_STRING, 53);
182 public static final HttpString SEC_WEB_SOCKET_PROTOCOL = new HttpString(SEC_WEB_SOCKET_PROTOCOL_STRING, 54);
183 public static final HttpString SEC_WEB_SOCKET_VERSION = new HttpString(SEC_WEB_SOCKET_VERSION_STRING, 55);
184 public static final HttpString SERVER = new HttpString(SERVER_STRING, 56);
185 public static final HttpString SERVLET_ENGINE = new HttpString(SERVLET_ENGINE_STRING, 57);
186 public static final HttpString SET_COOKIE = new HttpString(SET_COOKIE_STRING, 58);
187 public static final HttpString SET_COOKIE2 = new HttpString(SET_COOKIE2_STRING, 59);
188 public static final HttpString SSL_CIPHER = new HttpString(SSL_CIPHER_STRING, 60);
189 public static final HttpString SSL_CIPHER_USEKEYSIZE = new HttpString(SSL_CIPHER_USEKEYSIZE_STRING, 61);
190 public static final HttpString SSL_CLIENT_CERT = new HttpString(SSL_CLIENT_CERT_STRING, 62);
191 public static final HttpString SSL_SESSION_ID = new HttpString(SSL_SESSION_ID_STRING, 63);
192 public static final HttpString STATUS = new HttpString(STATUS_STRING, 64);
193 public static final HttpString STRICT_TRANSPORT_SECURITY = new HttpString(STRICT_TRANSPORT_SECURITY_STRING, 65);
194 public static final HttpString TE = new HttpString(TE_STRING, 66);
195 public static final HttpString TRAILER = new HttpString(TRAILER_STRING, 67);
196 public static final HttpString TRANSFER_ENCODING = new HttpString(TRANSFER_ENCODING_STRING, 68);
197 public static final HttpString UPGRADE = new HttpString(UPGRADE_STRING, 69);
198 public static final HttpString USER_AGENT = new HttpString(USER_AGENT_STRING, 70);
199 public static final HttpString VARY = new HttpString(VARY_STRING, 71);
200 public static final HttpString VIA = new HttpString(VIA_STRING, 72);
201 public static final HttpString WARNING = new HttpString(WARNING_STRING, 73);
202 public static final HttpString WWW_AUTHENTICATE = new HttpString(WWW_AUTHENTICATE_STRING, 74);
203 public static final HttpString X_CONTENT_TYPE_OPTIONS = new HttpString(X_CONTENT_TYPE_OPTIONS_STRING, 75);
204 public static final HttpString X_DISABLE_PUSH = new HttpString(X_DISABLE_PUSH_STRING, 76);
205 public static final HttpString X_FORWARDED_FOR = new HttpString(X_FORWARDED_FOR_STRING, 77);
206 public static final HttpString X_FORWARDED_HOST = new HttpString(X_FORWARDED_HOST_STRING, 78);
207 public static final HttpString X_FORWARDED_PORT = new HttpString(X_FORWARDED_PORT_STRING, 79);
208 public static final HttpString X_FORWARDED_PROTO = new HttpString(X_FORWARDED_PROTO_STRING, 80);
209 public static final HttpString X_FORWARDED_SERVER = new HttpString(X_FORWARDED_SERVER_STRING, 81);
210 public static final HttpString X_FRAME_OPTIONS = new HttpString(X_FRAME_OPTIONS_STRING, 82);
211 public static final HttpString X_XSS_PROTECTION = new HttpString(X_XSS_PROTECTION_STRING, 83);
212
213
214 public static final HttpString COMPRESS = new HttpString("compress");
215 public static final HttpString X_COMPRESS = new HttpString("x-compress");
216 public static final HttpString DEFLATE = new HttpString("deflate");
217 public static final HttpString IDENTITY = new HttpString("identity");
218 public static final HttpString GZIP = new HttpString("gzip");
219 public static final HttpString X_GZIP = new HttpString("x-gzip");
220
221
222
223 public static final HttpString CHUNKED = new HttpString("chunked");
224
225
226
227
228
229
230 public static final HttpString KEEP_ALIVE = new HttpString("keep-alive");
231 public static final HttpString CLOSE = new HttpString("close");
232
233
234 public static final String CONTENT_TRANSFER_ENCODING_STRING = "Content-Transfer-Encoding";
235 public static final HttpString CONTENT_TRANSFER_ENCODING = new HttpString(CONTENT_TRANSFER_ENCODING_STRING);
236
237
238 public static final HttpString BASIC = new HttpString("Basic");
239 public static final HttpString DIGEST = new HttpString("Digest");
240 public static final HttpString NEGOTIATE = new HttpString("Negotiate");
241
242
243 public static final HttpString ALGORITHM = new HttpString("algorithm");
244 public static final HttpString AUTH_PARAM = new HttpString("auth-param");
245 public static final HttpString CNONCE = new HttpString("cnonce");
246 public static final HttpString DOMAIN = new HttpString("domain");
247 public static final HttpString NEXT_NONCE = new HttpString("nextnonce");
248 public static final HttpString NONCE = new HttpString("nonce");
249 public static final HttpString NONCE_COUNT = new HttpString("nc");
250 public static final HttpString OPAQUE = new HttpString("opaque");
251 public static final HttpString QOP = new HttpString("qop");
252 public static final HttpString REALM = new HttpString("realm");
253 public static final HttpString RESPONSE = new HttpString("response");
254 public static final HttpString RESPONSE_AUTH = new HttpString("rspauth");
255 public static final HttpString STALE = new HttpString("stale");
256 public static final HttpString URI = new HttpString("uri");
257 public static final HttpString USERNAME = new HttpString("username");
258
259
260 private static final Map<String, HttpString> HTTP_STRING_MAP;
261
262 static {
263 Map<String, HttpString> map = AccessController.doPrivileged(new PrivilegedAction<Map<String, HttpString>>() {
264 @Override
265 public Map<String, HttpString> run() {
266 Map<String, HttpString> map = new HashMap<>();
267 Field[] fields = Headers.class.getDeclaredFields();
268 for(Field field : fields) {
269 if(Modifier.isStatic(field.getModifiers()) && field.getType() == HttpString.class) {
270 field.setAccessible(true);
271 try {
272 HttpString result = (HttpString) field.get(null);
273 map.put(result.toString(), result);
274 } catch (IllegalAccessException e) {
275 throw new RuntimeException(e);
276 }
277 }
278 }
279 return map;
280 }
281 });
282 HTTP_STRING_MAP = Collections.unmodifiableMap(map);
283 }
284
285 public static HttpString fromCache(String string) {
286 return HTTP_STRING_MAP.get(string);
287 }
288
289
299 @Deprecated
300 public static String extractTokenFromHeader(final String header, final String key) {
301 int pos = header.indexOf(' ' + key + '=');
302 if (pos == -1) {
303 if(!header.startsWith(key + '=')) {
304 return null;
305 }
306 pos = 0;
307 } else {
308 pos++;
309 }
310 int end;
311 int start = pos + key.length() + 1;
312 for (end = start; end < header.length(); ++end) {
313 char c = header.charAt(end);
314 if (c == ' ' || c == '\t' || c == ';') {
315 break;
316 }
317 }
318 return header.substring(start, end);
319 }
320
321
332 public static String extractQuotedValueFromHeader(final String header, final String key) {
333
334 int keypos = 0;
335 int pos = -1;
336 boolean whiteSpace = true;
337 boolean inQuotes = false;
338 for (int i = 0; i < header.length() - 1; ++i) {
339
340 char c = header.charAt(i);
341 if (inQuotes) {
342 if (c == '"') {
343 inQuotes = false;
344 }
345 } else {
346 if (key.charAt(keypos) == c && (whiteSpace || keypos > 0)) {
347 keypos++;
348 whiteSpace = false;
349 } else if (c == '"') {
350 keypos = 0;
351 inQuotes = true;
352 whiteSpace = false;
353 } else {
354 keypos = 0;
355 whiteSpace = c == ' ' || c == ';' || c == '\t';
356 }
357 if (keypos == key.length()) {
358 if (header.charAt(i + 1) == '=') {
359 pos = i + 2;
360 break;
361 } else {
362 keypos = 0;
363 }
364 }
365 }
366
367 }
368 if (pos == -1) {
369 return null;
370 }
371
372 int end;
373 int start = pos;
374 if (header.charAt(start) == '"') {
375 start++;
376 for (end = start; end < header.length(); ++end) {
377 char c = header.charAt(end);
378 if (c == '"') {
379 break;
380 }
381 }
382 return header.substring(start, end);
383
384 } else {
385
386 for (end = start; end < header.length(); ++end) {
387 char c = header.charAt(end);
388 if (c == ' ' || c == '\t' || c == ';') {
389 break;
390 }
391 }
392 return header.substring(start, end);
393 }
394 }
395
396
407 public static String extractQuotedValueFromHeaderWithEncoding(final String header, final String key) {
408 String value = extractQuotedValueFromHeader(header, key);
409 if (value != null) {
410 return value;
411 }
412 value = extractQuotedValueFromHeader(header , key + "*");
413 if(value != null) {
414 int characterSetDelimiter = value.indexOf('\'');
415 int languageDelimiter = value.lastIndexOf('\'', characterSetDelimiter + 1);
416 String characterSet = value.substring(0, characterSetDelimiter);
417 try {
418 String fileNameURLEncoded = value.substring(languageDelimiter + 1);
419 return URLDecoder.decode(fileNameURLEncoded, characterSet);
420 } catch (UnsupportedEncodingException e) {
421 throw new RuntimeException(e);
422 }
423 }
424 return null;
425 }
426 }
427