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.Date;
19 import java.util.Set;
20 import java.util.TreeSet;
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54 public class CookieEncoder {
55
56 private final Set<Cookie> cookies = new TreeSet<Cookie>();
57 private final boolean server;
58
59
60
61
62
63
64
65
66 public CookieEncoder(boolean server) {
67 this.server = server;
68 }
69
70
71
72
73
74 public void addCookie(String name, String value) {
75 cookies.add(new DefaultCookie(name, value));
76 }
77
78
79
80
81 public void addCookie(Cookie cookie) {
82 cookies.add(cookie);
83 }
84
85
86
87
88
89
90 public String encode() {
91 String answer;
92 if (server) {
93 answer = encodeServerSide();
94 } else {
95 answer = encodeClientSide();
96 }
97 cookies.clear();
98 return answer;
99 }
100
101 private String encodeServerSide() {
102 StringBuilder sb = new StringBuilder();
103
104 for (Cookie cookie: cookies) {
105 add(sb, cookie.getName(), cookie.getValue());
106
107 if (cookie.getMaxAge() >= 0) {
108 if (cookie.getVersion() == 0) {
109 addUnquoted(sb, CookieHeaderNames.EXPIRES,
110 new CookieDateFormat().format(
111 new Date(System.currentTimeMillis() +
112 cookie.getMaxAge() * 1000L)));
113 } else {
114 add(sb, CookieHeaderNames.MAX_AGE, cookie.getMaxAge());
115 }
116 }
117
118 if (cookie.getPath() != null) {
119 if (cookie.getVersion() > 0) {
120 add(sb, CookieHeaderNames.PATH, cookie.getPath());
121 } else {
122 addUnquoted(sb, CookieHeaderNames.PATH, cookie.getPath());
123 }
124 }
125
126 if (cookie.getDomain() != null) {
127 if (cookie.getVersion() > 0) {
128 add(sb, CookieHeaderNames.DOMAIN, cookie.getDomain());
129 } else {
130 addUnquoted(sb, CookieHeaderNames.DOMAIN, cookie.getDomain());
131 }
132 }
133 if (cookie.isSecure()) {
134 sb.append(CookieHeaderNames.SECURE);
135 sb.append((char) HttpCodecUtil.SEMICOLON);
136 }
137 if (cookie.isHttpOnly()) {
138 sb.append(CookieHeaderNames.HTTPONLY);
139 sb.append((char) HttpCodecUtil.SEMICOLON);
140 }
141 if (cookie.getVersion() >= 1) {
142 if (cookie.getComment() != null) {
143 add(sb, CookieHeaderNames.COMMENT, cookie.getComment());
144 }
145
146 add(sb, CookieHeaderNames.VERSION, 1);
147
148 if (cookie.getCommentUrl() != null) {
149 addQuoted(sb, CookieHeaderNames.COMMENTURL, cookie.getCommentUrl());
150 }
151
152 if(!cookie.getPorts().isEmpty()) {
153 sb.append(CookieHeaderNames.PORT);
154 sb.append((char) HttpCodecUtil.EQUALS);
155 sb.append((char) HttpCodecUtil.DOUBLE_QUOTE);
156 for (int port: cookie.getPorts()) {
157 sb.append(port);
158 sb.append((char) HttpCodecUtil.COMMA);
159 }
160 sb.setCharAt(sb.length() - 1, (char) HttpCodecUtil.DOUBLE_QUOTE);
161 sb.append((char) HttpCodecUtil.SEMICOLON);
162 }
163 if (cookie.isDiscard()) {
164 sb.append(CookieHeaderNames.DISCARD);
165 sb.append((char) HttpCodecUtil.SEMICOLON);
166 }
167 }
168 }
169
170 sb.setLength(sb.length() - 1);
171 return sb.toString();
172 }
173
174 private String encodeClientSide() {
175 StringBuilder sb = new StringBuilder();
176
177 for (Cookie cookie: cookies) {
178 if (cookie.getVersion() >= 1) {
179 add(sb, '$' + CookieHeaderNames.VERSION, 1);
180 }
181
182 add(sb, cookie.getName(), cookie.getValue());
183
184 if (cookie.getPath() != null) {
185 add(sb, '$' + CookieHeaderNames.PATH, cookie.getPath());
186 }
187
188 if (cookie.getDomain() != null) {
189 add(sb, '$' + CookieHeaderNames.DOMAIN, cookie.getDomain());
190 }
191
192 if (cookie.getVersion() >= 1) {
193 if(!cookie.getPorts().isEmpty()) {
194 sb.append('$');
195 sb.append(CookieHeaderNames.PORT);
196 sb.append((char) HttpCodecUtil.EQUALS);
197 sb.append((char) HttpCodecUtil.DOUBLE_QUOTE);
198 for (int port: cookie.getPorts()) {
199 sb.append(port);
200 sb.append((char) HttpCodecUtil.COMMA);
201 }
202 sb.setCharAt(sb.length() - 1, (char) HttpCodecUtil.DOUBLE_QUOTE);
203 sb.append((char) HttpCodecUtil.SEMICOLON);
204 }
205 }
206 }
207
208 sb.setLength(sb.length() - 1);
209 return sb.toString();
210 }
211
212 private static void add(StringBuilder sb, String name, String val) {
213 if (val == null) {
214 addQuoted(sb, name, "");
215 return;
216 }
217
218 for (int i = 0; i < val.length(); i ++) {
219 char c = val.charAt(i);
220 switch (c) {
221 case '\t': case ' ': case '"': case '(': case ')': case ',':
222 case '/': case ':': case ';': case '<': case '=': case '>':
223 case '?': case '@': case '[': case '\\': case ']':
224 case '{': case '}':
225 addQuoted(sb, name, val);
226 return;
227 }
228 }
229
230 addUnquoted(sb, name, val);
231 }
232
233 private static void addUnquoted(StringBuilder sb, String name, String val) {
234 sb.append(name);
235 sb.append((char) HttpCodecUtil.EQUALS);
236 sb.append(val);
237 sb.append((char) HttpCodecUtil.SEMICOLON);
238 }
239
240 private static void addQuoted(StringBuilder sb, String name, String val) {
241 if (val == null) {
242 val = "";
243 }
244
245 sb.append(name);
246 sb.append((char) HttpCodecUtil.EQUALS);
247 sb.append((char) HttpCodecUtil.DOUBLE_QUOTE);
248 sb.append(val.replace("\\", "\\\\").replace("\"", "\\\""));
249 sb.append((char) HttpCodecUtil.DOUBLE_QUOTE);
250 sb.append((char) HttpCodecUtil.SEMICOLON);
251 }
252
253 private static void add(StringBuilder sb, String name, int val) {
254 sb.append(name);
255 sb.append((char) HttpCodecUtil.EQUALS);
256 sb.append(val);
257 sb.append((char) HttpCodecUtil.SEMICOLON);
258 }
259 }