1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package org.jboss.netty.handler.codec.http;
17
18 import java.util.List;
19
20 final class HttpCodecUtil {
21
22 static void validateHeaderName(String name) {
23 if (name == null) {
24 throw new NullPointerException("name");
25 }
26 for (int i = 0; i < name.length(); i ++) {
27 char c = name.charAt(i);
28 if (c > 127) {
29 throw new IllegalArgumentException(
30 "name contains non-ascii character: " + name);
31 }
32
33
34 switch (c) {
35 case '\t': case '\n': case 0x0b: case '\f': case '\r':
36 case ' ': case ',': case ':': case ';': case '=':
37 throw new IllegalArgumentException(
38 "name contains one of the following prohibited characters: " +
39 "=,;: \\t\\r\\n\\v\\f: " + name);
40 }
41 }
42 }
43
44 static void validateHeaderValue(String value) {
45 if (value == null) {
46 throw new NullPointerException("value");
47 }
48
49
50
51
52 int state = 0;
53
54 for (int i = 0; i < value.length(); i ++) {
55 char c = value.charAt(i);
56
57
58 switch (c) {
59 case 0x0b:
60 throw new IllegalArgumentException(
61 "value contains a prohibited character '\\v': " + value);
62 case '\f':
63 throw new IllegalArgumentException(
64 "value contains a prohibited character '\\f': " + value);
65 }
66
67
68 switch (state) {
69 case 0:
70 switch (c) {
71 case '\r':
72 state = 1;
73 break;
74 case '\n':
75 state = 2;
76 break;
77 }
78 break;
79 case 1:
80 switch (c) {
81 case '\n':
82 state = 2;
83 break;
84 default:
85 throw new IllegalArgumentException(
86 "Only '\\n' is allowed after '\\r': " + value);
87 }
88 break;
89 case 2:
90 switch (c) {
91 case '\t': case ' ':
92 state = 0;
93 break;
94 default:
95 throw new IllegalArgumentException(
96 "Only ' ' and '\\t' are allowed after '\\n': " + value);
97 }
98 }
99 }
100
101 if (state != 0) {
102 throw new IllegalArgumentException(
103 "value must not end with '\\r' or '\\n':" + value);
104 }
105 }
106
107 static boolean isTransferEncodingChunked(HttpMessage m) {
108 List<String> chunked = m.getHeaders(HttpHeaders.Names.TRANSFER_ENCODING);
109 if (chunked.isEmpty()) {
110 return false;
111 }
112
113 for (String v: chunked) {
114 if (v.equalsIgnoreCase(HttpHeaders.Values.CHUNKED)) {
115 return true;
116 }
117 }
118 return false;
119 }
120
121 static void removeTransferEncodingChunked(HttpMessage m) {
122 List<String> values = m.getHeaders(HttpHeaders.Names.TRANSFER_ENCODING);
123 values.remove(HttpHeaders.Values.CHUNKED);
124 m.setHeader(HttpHeaders.Names.TRANSFER_ENCODING, values);
125 }
126
127 static boolean isContentLengthSet(HttpMessage m) {
128 List<String> contentLength = m.getHeaders(HttpHeaders.Names.CONTENT_LENGTH);
129 return !contentLength.isEmpty();
130 }
131
132 private HttpCodecUtil() {
133 }
134 }