1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28 package org.apache.hc.client5.http.impl.cookie;
29
30 import java.util.Arrays;
31 import java.util.Collections;
32 import java.util.List;
33
34 import org.apache.hc.client5.http.cookie.CommonCookieAttributeHandler;
35 import org.apache.hc.client5.http.cookie.Cookie;
36 import org.apache.hc.client5.http.cookie.CookieOrigin;
37 import org.apache.hc.client5.http.cookie.MalformedCookieException;
38 import org.apache.hc.client5.http.cookie.SetCookie;
39 import org.apache.hc.core5.http.Header;
40 import org.apache.hc.core5.http.message.BasicHeader;
41 import org.junit.Assert;
42 import org.junit.Test;
43 import org.mockito.ArgumentMatchers;
44 import org.mockito.Mockito;
45
46 public class TestRFC6265CookieSpec {
47
48 @Test
49 public void testParseCookieBasics() throws Exception {
50 final CommonCookieAttributeHandler h1 = Mockito.mock(CommonCookieAttributeHandler.class);
51 Mockito.when(h1.getAttributeName()).thenReturn("this");
52 final CommonCookieAttributeHandler h2 = Mockito.mock(CommonCookieAttributeHandler.class);
53 Mockito.when(h2.getAttributeName()).thenReturn("that");
54
55 final RFC6265CookieSpec cookiespec = new RFC6265CookieSpec(h1, h2);
56
57 final Header header = new BasicHeader("Set-Cookie", "name = value ; this = stuff;");
58 final CookieOrigin origin = new CookieOrigin("host", 80, "/path/", true);
59 final List<Cookie> cookies = cookiespec.parse(header, origin);
60
61 Assert.assertEquals(1, cookies.size());
62 final Cookie cookie = cookies.get(0);
63 Assert.assertEquals("name", cookie.getName());
64 Assert.assertEquals("value", cookie.getValue());
65 Assert.assertEquals("/path", cookie.getPath());
66 Assert.assertEquals("host", cookie.getDomain());
67 Assert.assertEquals("stuff", cookie.getAttribute("this"));
68 Assert.assertEquals(null, cookie.getAttribute("that"));
69
70 Mockito.verify(h1).parse(ArgumentMatchers.<SetCookie>any(), ArgumentMatchers.eq("stuff"));
71 Mockito.verify(h2, Mockito.never()).parse(ArgumentMatchers.<SetCookie>any(), ArgumentMatchers.anyString());
72 }
73
74 @Test
75 public void testParseCookieQuotedValue() throws Exception {
76 final RFC6265CookieSpec cookiespec = new RFC6265CookieSpec();
77
78 final Header header = new BasicHeader("Set-Cookie", "name = \" one, two, three; four \" ; this = stuff;");
79 final CookieOrigin origin = new CookieOrigin("host", 80, "/path/", true);
80 final List<Cookie> cookies = cookiespec.parse(header, origin);
81
82 Assert.assertEquals(1, cookies.size());
83 final Cookie cookie = cookies.get(0);
84 Assert.assertEquals("name", cookie.getName());
85 Assert.assertEquals(" one, two, three; four ", cookie.getValue());
86 Assert.assertEquals("stuff", cookie.getAttribute("this"));
87 }
88
89 @Test(expected = MalformedCookieException.class)
90 public void testParseCookieWrongHeader() throws Exception {
91 final RFC6265CookieSpec cookiespec = new RFC6265CookieSpec();
92
93 final Header header = new BasicHeader("Set-Cookie2", "blah");
94 final CookieOrigin origin = new CookieOrigin("host", 80, "/path/", true);
95 cookiespec.parse(header, origin);
96 }
97
98 @Test
99 public void testParseCookieMissingName() throws Exception {
100 final RFC6265CookieSpec cookiespec = new RFC6265CookieSpec();
101
102 final Header header = new BasicHeader("Set-Cookie", "=blah ; this = stuff;");
103 final CookieOrigin origin = new CookieOrigin("host", 80, "/path/", true);
104 final List<Cookie> cookies = cookiespec.parse(header, origin);
105 Assert.assertEquals(0, cookies.size());
106 }
107
108 @Test
109 public void testParseCookieMissingValue1() throws Exception {
110 final RFC6265CookieSpec cookiespec = new RFC6265CookieSpec();
111
112 final Header header = new BasicHeader("Set-Cookie", "blah");
113 final CookieOrigin origin = new CookieOrigin("host", 80, "/path/", true);
114 final List<Cookie> cookies = cookiespec.parse(header, origin);
115 Assert.assertEquals(0, cookies.size());
116 }
117
118 @Test(expected = MalformedCookieException.class)
119 public void testParseCookieMissingValue2() throws Exception {
120 final RFC6265CookieSpec cookiespec = new RFC6265CookieSpec();
121
122 final Header header = new BasicHeader("Set-Cookie", "blah;");
123 final CookieOrigin origin = new CookieOrigin("host", 80, "/path/", true);
124 cookiespec.parse(header, origin);
125 }
126
127 @Test
128 public void testParseCookieEmptyValue() throws Exception {
129 final RFC6265CookieSpec cookiespec = new RFC6265CookieSpec();
130
131 final Header header = new BasicHeader("Set-Cookie", "blah=;");
132 final CookieOrigin origin = new CookieOrigin("host", 80, "/path/", true);
133 final List<Cookie> cookies = cookiespec.parse(header, origin);
134 Assert.assertEquals(1, cookies.size());
135 final Cookie cookie = cookies.get(0);
136 Assert.assertEquals("blah", cookie.getName());
137 Assert.assertEquals("", cookie.getValue());
138 }
139
140 @Test
141 public void testParseCookieWithAttributes() throws Exception {
142 final CommonCookieAttributeHandler h1 = Mockito.mock(CommonCookieAttributeHandler.class);
143 Mockito.when(h1.getAttributeName()).thenReturn("this");
144 final CommonCookieAttributeHandler h2 = Mockito.mock(CommonCookieAttributeHandler.class);
145 Mockito.when(h2.getAttributeName()).thenReturn("that");
146
147 final RFC6265CookieSpec cookiespec = new RFC6265CookieSpec(h1, h2);
148
149 final Header header = new BasicHeader("Set-Cookie", "name = value ; p1 = v ; p2 = v,0; p3 ; p4");
150 final CookieOrigin origin = new CookieOrigin("host", 80, "/path/", true);
151 final List<Cookie> cookies = cookiespec.parse(header, origin);
152
153 Assert.assertEquals(1, cookies.size());
154 final Cookie cookie = cookies.get(0);
155 Assert.assertEquals("name", cookie.getName());
156 Assert.assertEquals("value", cookie.getValue());
157 Assert.assertEquals("v", cookie.getAttribute("p1"));
158 Assert.assertEquals("v,0", cookie.getAttribute("p2"));
159 Assert.assertTrue(cookie.containsAttribute("p3"));
160 Assert.assertTrue(cookie.containsAttribute("p4"));
161 Assert.assertFalse(cookie.containsAttribute("p5"));
162 }
163
164 @Test
165 public void testParseCookieWithAttributes2() throws Exception {
166 final CommonCookieAttributeHandler h1 = Mockito.mock(CommonCookieAttributeHandler.class);
167 Mockito.when(h1.getAttributeName()).thenReturn("this");
168 final CommonCookieAttributeHandler h2 = Mockito.mock(CommonCookieAttributeHandler.class);
169 Mockito.when(h2.getAttributeName()).thenReturn("that");
170
171 final RFC6265CookieSpec cookiespec = new RFC6265CookieSpec(h1, h2);
172
173 final Header header = new BasicHeader("Set-Cookie", "name = value ; p1 = v");
174 final CookieOrigin origin = new CookieOrigin("host", 80, "/path/", true);
175 final List<Cookie> cookies = cookiespec.parse(header, origin);
176
177 Assert.assertEquals(1, cookies.size());
178 final Cookie cookie = cookies.get(0);
179 Assert.assertEquals("name", cookie.getName());
180 Assert.assertEquals("value", cookie.getValue());
181 Assert.assertEquals("v", cookie.getAttribute("p1"));
182 }
183
184 @Test
185 public void testParseCookieWithAttributes3() throws Exception {
186 final CommonCookieAttributeHandler h1 = Mockito.mock(CommonCookieAttributeHandler.class);
187 Mockito.when(h1.getAttributeName()).thenReturn("this");
188 final CommonCookieAttributeHandler h2 = Mockito.mock(CommonCookieAttributeHandler.class);
189 Mockito.when(h2.getAttributeName()).thenReturn("that");
190
191 final RFC6265CookieSpec cookiespec = new RFC6265CookieSpec(h1, h2);
192
193 final Header header = new BasicHeader("Set-Cookie", "name = value ; p1 =");
194 final CookieOrigin origin = new CookieOrigin("host", 80, "/path/", true);
195 final List<Cookie> cookies = cookiespec.parse(header, origin);
196
197 Assert.assertEquals(1, cookies.size());
198 final Cookie cookie = cookies.get(0);
199 Assert.assertEquals("name", cookie.getName());
200 Assert.assertEquals("value", cookie.getValue());
201 Assert.assertEquals("", cookie.getAttribute("p1"));
202 }
203
204 @Test
205 public void testValidateCookieBasics() throws Exception {
206 final CommonCookieAttributeHandler h1 = Mockito.mock(CommonCookieAttributeHandler.class);
207 Mockito.when(h1.getAttributeName()).thenReturn("this");
208 final CommonCookieAttributeHandler h2 = Mockito.mock(CommonCookieAttributeHandler.class);
209 Mockito.when(h2.getAttributeName()).thenReturn("that");
210
211 final RFC6265CookieSpec cookiespec = new RFC6265CookieSpec(h1, h2);
212
213 final CookieOrigin origin = new CookieOrigin("host", 80, "/path/", true);
214 final BasicClientCookie cookie = new BasicClientCookie("name", "value");
215 cookiespec.validate(cookie, origin);
216
217 Mockito.verify(h1).validate(cookie, origin);
218 Mockito.verify(h2).validate(cookie, origin);
219 }
220
221 @Test
222 public void testMatchCookie() throws Exception {
223 final CommonCookieAttributeHandler h1 = Mockito.mock(CommonCookieAttributeHandler.class);
224 Mockito.when(h1.getAttributeName()).thenReturn("this");
225 final CommonCookieAttributeHandler h2 = Mockito.mock(CommonCookieAttributeHandler.class);
226 Mockito.when(h2.getAttributeName()).thenReturn("that");
227
228 final RFC6265CookieSpec cookiespec = new RFC6265CookieSpec(h1, h2);
229
230 final CookieOrigin origin = new CookieOrigin("host", 80, "/path/", true);
231 final BasicClientCookie cookie = new BasicClientCookie("name", "value");
232
233 Mockito.when(h1.match(cookie, origin)).thenReturn(true);
234 Mockito.when(h2.match(cookie, origin)).thenReturn(true);
235
236 Assert.assertTrue(cookiespec.match(cookie, origin));
237
238 Mockito.verify(h1).match(cookie, origin);
239 Mockito.verify(h2).match(cookie, origin);
240 }
241
242 @Test
243 public void testMatchCookieNoMatch() throws Exception {
244 final CommonCookieAttributeHandler h1 = Mockito.mock(CommonCookieAttributeHandler.class);
245 Mockito.when(h1.getAttributeName()).thenReturn("this");
246 final CommonCookieAttributeHandler h2 = Mockito.mock(CommonCookieAttributeHandler.class);
247 Mockito.when(h2.getAttributeName()).thenReturn("that");
248
249 final RFC6265CookieSpec cookiespec = new RFC6265CookieSpec(h1, h2);
250
251 final CookieOrigin origin = new CookieOrigin("host", 80, "/path/", true);
252 final BasicClientCookie cookie = new BasicClientCookie("name", "value");
253
254 Mockito.when(h1.match(cookie, origin)).thenReturn(false);
255 Mockito.when(h2.match(cookie, origin)).thenReturn(false);
256
257 Assert.assertFalse(cookiespec.match(cookie, origin));
258
259 Mockito.verify(h1).match(cookie, origin);
260 Mockito.verify(h2, Mockito.never()).match(cookie, origin);
261 }
262
263 @Test
264 public void testFormatCookiesBasics() throws Exception {
265 final Cookie cookie1 = new BasicClientCookie("name1", "value");
266
267 final RFC6265CookieSpec cookiespec = new RFC6265CookieSpec();
268 final List<Header> headers = cookiespec.formatCookies(Collections.singletonList(cookie1));
269 Assert.assertNotNull(headers);
270 Assert.assertEquals(1, headers.size());
271 final Header header = headers.get(0);
272 Assert.assertEquals("Cookie", header.getName());
273 Assert.assertEquals("name1=value", header.getValue());
274 }
275
276 @Test
277 public void testFormatCookiesIllegalCharsInValue() throws Exception {
278 final Cookie cookie1 = new BasicClientCookie("name1", "value");
279 final Cookie cookie2 = new BasicClientCookie("name2", "some value");
280 final Cookie cookie3 = new BasicClientCookie("name3", "\"\\\"");
281 final RFC6265CookieSpec cookiespec = new RFC6265CookieSpec();
282 final List<Header> headers = cookiespec.formatCookies(Arrays.asList(cookie1, cookie2, cookie3));
283 Assert.assertNotNull(headers);
284 Assert.assertEquals(1, headers.size());
285 final Header header = headers.get(0);
286 Assert.assertEquals("Cookie", header.getName());
287 Assert.assertEquals("name1=value; name2=\"some value\"; name3=\"\\\"\\\\\\\"\"", header.getValue());
288 }
289
290 @Test
291 public void testParseCookieMultipleAttributes() throws Exception {
292 final CommonCookieAttributeHandler h1 = Mockito.mock(CommonCookieAttributeHandler.class);
293 Mockito.when(h1.getAttributeName()).thenReturn("this");
294
295 final RFC6265CookieSpec cookiespec = new RFC6265CookieSpec(h1);
296
297 final Header header = new BasicHeader("Set-Cookie", "name = value ; this = stuff; this = morestuff;");
298 final CookieOrigin origin = new CookieOrigin("host", 80, "/path/", true);
299 cookiespec.parse(header, origin);
300
301 Mockito.verify(h1).parse(ArgumentMatchers.<SetCookie>any(), ArgumentMatchers.eq("morestuff"));
302 Mockito.verify(h1, Mockito.times(1)).parse(ArgumentMatchers.<SetCookie>any(), ArgumentMatchers.anyString());
303 }
304
305 @Test
306 public void testParseCookieMaxAgeOverExpires() throws Exception {
307 final CommonCookieAttributeHandler h1 = Mockito.mock(CommonCookieAttributeHandler.class);
308 Mockito.when(h1.getAttributeName()).thenReturn("Expires");
309 final CommonCookieAttributeHandler h2 = Mockito.mock(CommonCookieAttributeHandler.class);
310 Mockito.when(h2.getAttributeName()).thenReturn("Max-Age");
311
312 final RFC6265CookieSpec cookiespec = new RFC6265CookieSpec(h1, h2);
313
314 final Header header = new BasicHeader("Set-Cookie", "name = value ; expires = stuff; max-age = otherstuff;");
315 final CookieOrigin origin = new CookieOrigin("host", 80, "/path/", true);
316 cookiespec.parse(header, origin);
317
318 Mockito.verify(h1, Mockito.never()).parse(ArgumentMatchers.<SetCookie>any(), ArgumentMatchers.anyString());
319 Mockito.verify(h2).parse(ArgumentMatchers.<SetCookie>any(), ArgumentMatchers.eq("otherstuff"));
320 }
321
322 }