1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package io.netty.handler.codec.http.cookie;
17
18 import static io.netty.handler.codec.http.cookie.CookieUtil.add;
19 import static io.netty.handler.codec.http.cookie.CookieUtil.addQuoted;
20 import static io.netty.handler.codec.http.cookie.CookieUtil.stringBuilder;
21 import static io.netty.handler.codec.http.cookie.CookieUtil.stripTrailingSeparator;
22 import static io.netty.handler.codec.http.cookie.CookieUtil.stripTrailingSeparatorOrNull;
23 import static io.netty.util.internal.ObjectUtil.checkNotNull;
24 import io.netty.handler.codec.http.HttpRequest;
25 import io.netty.util.internal.InternalThreadLocalMap;
26
27 import java.util.Arrays;
28 import java.util.Collection;
29 import java.util.Comparator;
30 import java.util.Iterator;
31 import java.util.List;
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50 public final class ClientCookieEncoder extends CookieEncoder {
51
52
53
54
55
56 public static final ClientCookieEncoder STRICT = new ClientCookieEncoder(true);
57
58
59
60
61
62 public static final ClientCookieEncoder LAX = new ClientCookieEncoder(false);
63
64 private ClientCookieEncoder(boolean strict) {
65 super(strict);
66 }
67
68
69
70
71
72
73
74
75
76
77 public String encode(String name, String value) {
78 return encode(new DefaultCookie(name, value));
79 }
80
81
82
83
84
85
86
87
88 public String encode(Cookie cookie) {
89 StringBuilder buf = stringBuilder();
90 encode(buf, checkNotNull(cookie, "cookie"));
91 return stripTrailingSeparator(buf);
92 }
93
94
95
96
97
98 private static final Comparator<Cookie> COOKIE_COMPARATOR = new Comparator<Cookie>() {
99 @Override
100 public int compare(Cookie c1, Cookie c2) {
101 String path1 = c1.path();
102 String path2 = c2.path();
103
104
105
106
107
108 int len1 = path1 == null ? Integer.MAX_VALUE : path1.length();
109 int len2 = path2 == null ? Integer.MAX_VALUE : path2.length();
110 int diff = len2 - len1;
111 if (diff != 0) {
112 return diff;
113 }
114
115
116 return -1;
117 }
118 };
119
120
121
122
123
124
125
126
127 public String encode(Cookie... cookies) {
128 if (checkNotNull(cookies, "cookies").length == 0) {
129 return null;
130 }
131
132 StringBuilder buf = stringBuilder();
133 if (strict) {
134 if (cookies.length == 1) {
135 encode(buf, cookies[0]);
136 } else {
137 Cookie[] cookiesSorted = Arrays.copyOf(cookies, cookies.length);
138 Arrays.sort(cookiesSorted, COOKIE_COMPARATOR);
139 for (Cookie c : cookiesSorted) {
140 encode(buf, c);
141 }
142 }
143 } else {
144 for (Cookie c : cookies) {
145 encode(buf, c);
146 }
147 }
148 return stripTrailingSeparatorOrNull(buf);
149 }
150
151
152
153
154
155
156
157
158 public String encode(Collection<? extends Cookie> cookies) {
159 if (checkNotNull(cookies, "cookies").isEmpty()) {
160 return null;
161 }
162
163 StringBuilder buf = stringBuilder();
164 if (strict) {
165 if (cookies.size() == 1) {
166 encode(buf, cookies.iterator().next());
167 } else {
168 Cookie[] cookiesSorted = cookies.toArray(new Cookie[cookies.size()]);
169 Arrays.sort(cookiesSorted, COOKIE_COMPARATOR);
170 for (Cookie c : cookiesSorted) {
171 encode(buf, c);
172 }
173 }
174 } else {
175 for (Cookie c : cookies) {
176 encode(buf, c);
177 }
178 }
179 return stripTrailingSeparatorOrNull(buf);
180 }
181
182
183
184
185
186
187
188 public String encode(Iterable<? extends Cookie> cookies) {
189 Iterator<? extends Cookie> cookiesIt = checkNotNull(cookies, "cookies").iterator();
190 if (!cookiesIt.hasNext()) {
191 return null;
192 }
193
194 StringBuilder buf = stringBuilder();
195 if (strict) {
196 Cookie firstCookie = cookiesIt.next();
197 if (!cookiesIt.hasNext()) {
198 encode(buf, firstCookie);
199 } else {
200 List<Cookie> cookiesList = InternalThreadLocalMap.get().arrayList();
201 cookiesList.add(firstCookie);
202 while (cookiesIt.hasNext()) {
203 cookiesList.add(cookiesIt.next());
204 }
205 Cookie[] cookiesSorted = cookiesList.toArray(new Cookie[cookiesList.size()]);
206 Arrays.sort(cookiesSorted, COOKIE_COMPARATOR);
207 for (Cookie c : cookiesSorted) {
208 encode(buf, c);
209 }
210 }
211 } else {
212 while (cookiesIt.hasNext()) {
213 encode(buf, cookiesIt.next());
214 }
215 }
216 return stripTrailingSeparatorOrNull(buf);
217 }
218
219 private void encode(StringBuilder buf, Cookie c) {
220 final String name = c.name();
221 final String value = c.value() != null ? c.value() : "";
222
223 validateCookie(name, value);
224
225 if (c.wrap()) {
226 addQuoted(buf, name, value);
227 } else {
228 add(buf, name, value);
229 }
230 }
231 }