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