1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package org.jboss.netty.handler.codec.http.cookie;
17
18 import java.util.Collections;
19 import java.util.Set;
20 import java.util.TreeSet;
21
22
23
24
25
26
27
28
29
30
31
32 public final class ServerCookieDecoder extends CookieDecoder {
33
34 private static final String RFC2965_VERSION = "$Version";
35
36 private static final String RFC2965_PATH = "$" + CookieHeaderNames.PATH;
37
38 private static final String RFC2965_DOMAIN = "$" + CookieHeaderNames.DOMAIN;
39
40 private static final String RFC2965_PORT = "$Port";
41
42
43
44
45
46 public static final ServerCookieDecoder STRICT = new ServerCookieDecoder(true);
47
48
49
50
51 public static final ServerCookieDecoder LAX = new ServerCookieDecoder(false);
52
53 private ServerCookieDecoder(boolean strict) {
54 super(strict);
55 }
56
57
58
59
60
61
62 public Set<Cookie> decode(String header) {
63 if (header == null) {
64 throw new NullPointerException("header");
65 }
66 final int headerLen = header.length();
67
68 if (headerLen == 0) {
69 return Collections.emptySet();
70 }
71
72 Set<Cookie> cookies = new TreeSet<Cookie>();
73
74 int i = 0;
75
76 boolean rfc2965Style = false;
77 if (header.regionMatches(true, 0, RFC2965_VERSION, 0, RFC2965_VERSION.length())) {
78
79 i = header.indexOf(';') + 1;
80 rfc2965Style = true;
81 }
82
83 loop: for (;;) {
84
85
86 for (;;) {
87 if (i == headerLen) {
88 break loop;
89 }
90 char c = header.charAt(i);
91 if (c == '\t' || c == '\n' || c == 0x0b || c == '\f'
92 || c == '\r' || c == ' ' || c == ',' || c == ';') {
93 i++;
94 continue;
95 }
96 break;
97 }
98
99 int nameBegin = i;
100 int nameEnd = i;
101 int valueBegin = -1;
102 int valueEnd = -1;
103
104 if (i != headerLen) {
105 keyValLoop: for (;;) {
106
107 char curChar = header.charAt(i);
108 if (curChar == ';') {
109
110 nameEnd = i;
111 valueBegin = valueEnd = -1;
112 break keyValLoop;
113
114 } else if (curChar == '=') {
115
116 nameEnd = i;
117 i++;
118 if (i == headerLen) {
119
120 valueBegin = valueEnd = 0;
121 break keyValLoop;
122 }
123
124 valueBegin = i;
125
126 int semiPos = header.indexOf(';', i);
127 valueEnd = i = semiPos > 0 ? semiPos : headerLen;
128 break keyValLoop;
129 } else {
130 i++;
131 }
132
133 if (i == headerLen) {
134
135 nameEnd = headerLen;
136 valueBegin = valueEnd = -1;
137 break;
138 }
139 }
140 }
141
142 if (rfc2965Style && (header.regionMatches(nameBegin, RFC2965_PATH, 0, RFC2965_PATH.length()) ||
143 header.regionMatches(nameBegin, RFC2965_DOMAIN, 0, RFC2965_DOMAIN.length()) ||
144 header.regionMatches(nameBegin, RFC2965_PORT, 0, RFC2965_PORT.length()))) {
145
146
147 continue;
148 }
149
150 DefaultCookie cookie = initCookie(header, nameBegin, nameEnd, valueBegin, valueEnd);
151 if (cookie != null) {
152 cookies.add(cookie);
153 }
154 }
155
156 return cookies;
157 }
158 }