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 package org.apache.hc.client5.http.impl.auth;
28
29 import static org.hamcrest.MatcherAssert.assertThat;
30
31 import java.util.List;
32
33 import org.apache.hc.client5.http.NameValuePairMatcher;
34 import org.apache.hc.client5.http.auth.AuthChallenge;
35 import org.apache.hc.client5.http.auth.ChallengeType;
36 import org.apache.hc.client5.http.auth.StandardAuthScheme;
37 import org.apache.hc.core5.http.NameValuePair;
38 import org.apache.hc.core5.http.ParseException;
39 import org.apache.hc.core5.http.message.ParserCursor;
40 import org.apache.hc.core5.util.CharArrayBuffer;
41 import org.hamcrest.CoreMatchers;
42 import org.junit.jupiter.api.Assertions;
43 import org.junit.jupiter.api.BeforeEach;
44 import org.junit.jupiter.api.Test;
45
46 class TestAuthChallengeParser {
47
48 private AuthChallengeParser parser;
49
50 @BeforeEach
51 void setUp() {
52 this.parser = new AuthChallengeParser();
53 }
54
55 @Test
56 void testParseTokenTerminatedByBlank() {
57 final CharArrayBuffer buffer = new CharArrayBuffer(64);
58 buffer.append("aaabbbbccc ");
59 final ParserCursor cursor = new ParserCursor(0, buffer.length());
60 assertThat(parser.parseToken(buffer, cursor), CoreMatchers.equalTo("aaabbbbccc"));
61 }
62
63 @Test
64 void testParseTokenTerminatedByComma() {
65 final CharArrayBuffer buffer = new CharArrayBuffer(64);
66 buffer.append("aaabbbbccc, ");
67 final ParserCursor cursor = new ParserCursor(0, buffer.length());
68 assertThat(parser.parseToken(buffer, cursor), CoreMatchers.equalTo("aaabbbbccc"));
69 }
70
71 @Test
72 void testParseTokenTerminatedByEndOfStream() {
73 final CharArrayBuffer buffer = new CharArrayBuffer(64);
74 buffer.append("aaabbbbccc");
75 final ParserCursor cursor = new ParserCursor(0, buffer.length());
76 assertThat(parser.parseToken(buffer, cursor), CoreMatchers.equalTo("aaabbbbccc"));
77 }
78
79 @Test
80 void testParsePaddedToken68() {
81 final CharArrayBuffer buffer = new CharArrayBuffer(64);
82 buffer.append("aaabbbbccc==== ");
83 final ParserCursor cursor = new ParserCursor(0, buffer.length());
84 assertThat(parser.parseToken(buffer, cursor), CoreMatchers.equalTo("aaabbbbccc===="));
85 assertThat(cursor.atEnd(), CoreMatchers.equalTo(false));
86 assertThat(buffer.charAt(cursor.getPos()), CoreMatchers.equalTo(' '));
87 }
88
89 @Test
90 void testParsePaddedToken68SingleEqual() {
91 final CharArrayBuffer buffer = new CharArrayBuffer(64);
92 buffer.append("aaabbbbccc=");
93 final ParserCursor cursor = new ParserCursor(0, buffer.length());
94 assertThat(parser.parseToken(buffer, cursor), CoreMatchers.equalTo("aaabbbbccc="));
95 assertThat(cursor.atEnd(), CoreMatchers.equalTo(true));
96 }
97
98 @Test
99 void testParsePaddedToken68MultipleEquals() {
100 final CharArrayBuffer buffer = new CharArrayBuffer(16);
101 buffer.append("aaabbbbccc======");
102 final ParserCursor cursor = new ParserCursor(0, buffer.length());
103 assertThat(parser.parseToken(buffer, cursor), CoreMatchers.equalTo("aaabbbbccc======"));
104 assertThat(cursor.atEnd(), CoreMatchers.equalTo(true));
105 }
106
107 @Test
108 void testParsePaddedToken68TerminatedByComma() {
109 final CharArrayBuffer buffer = new CharArrayBuffer(64);
110 buffer.append("aaabbbbccc====,");
111 final ParserCursor cursor = new ParserCursor(0, buffer.length());
112 assertThat(parser.parseToken(buffer, cursor), CoreMatchers.equalTo("aaabbbbccc===="));
113 assertThat(cursor.atEnd(), CoreMatchers.equalTo(false));
114 assertThat(buffer.charAt(cursor.getPos()), CoreMatchers.equalTo(','));
115 }
116
117 @Test
118 void testParseTokenTerminatedByParameter() {
119 final CharArrayBuffer buffer = new CharArrayBuffer(64);
120 buffer.append("aaabbbbccc=blah");
121 final ParserCursor cursor = new ParserCursor(0, buffer.length());
122 assertThat(parser.parseToken(buffer, cursor), CoreMatchers.equalTo("aaabbbbccc"));
123 assertThat(cursor.atEnd(), CoreMatchers.equalTo(false));
124 assertThat(buffer.charAt(cursor.getPos()), CoreMatchers.equalTo('='));
125 }
126
127 @Test
128 void testParseBasicAuthChallenge() throws Exception {
129 final CharArrayBuffer buffer = new CharArrayBuffer(64);
130 buffer.append(StandardAuthScheme.BASIC + " realm=blah");
131 final ParserCursor cursor = new ParserCursor(0, buffer.length());
132 final List<AuthChallenge> challenges = parser.parse(ChallengeType.TARGET, buffer, cursor);
133 Assertions.assertNotNull(challenges);
134 Assertions.assertEquals(1, challenges.size());
135 final AuthChallenge challenge1 = challenges.get(0);
136 Assertions.assertEquals(StandardAuthScheme.BASIC, challenge1.getSchemeName());
137 Assertions.assertNull(challenge1.getValue());
138 final List<NameValuePair> params = challenge1.getParams();
139 Assertions.assertNotNull(params);
140 Assertions.assertEquals(1, params.size());
141 assertThat(params.get(0), NameValuePairMatcher.equals("realm", "blah"));
142 }
143
144 @Test
145 void testParseAuthChallengeWithBlanks() throws Exception {
146 final CharArrayBuffer buffer = new CharArrayBuffer(64);
147 buffer.append(" " + StandardAuthScheme.BASIC + " realm = blah ");
148 final ParserCursor cursor = new ParserCursor(0, buffer.length());
149 final List<AuthChallenge> challenges = parser.parse(ChallengeType.TARGET, buffer, cursor);
150 Assertions.assertNotNull(challenges);
151 Assertions.assertEquals(1, challenges.size());
152 final AuthChallenge challenge1 = challenges.get(0);
153 Assertions.assertEquals(StandardAuthScheme.BASIC, challenge1.getSchemeName());
154 Assertions.assertNull(challenge1.getValue());
155 final List<NameValuePair> params = challenge1.getParams();
156 Assertions.assertNotNull(params);
157 Assertions.assertEquals(1, params.size());
158 assertThat(params.get(0), NameValuePairMatcher.equals("realm", "blah"));
159 }
160
161 @Test
162 void testParseMultipleAuthChallenge() throws Exception {
163 final CharArrayBuffer buffer = new CharArrayBuffer(64);
164 buffer.append("This xxxxxxxxxxxxxxxxxxxxxx, " +
165 "That yyyyyyyyyyyyyyyyyyyyyy ");
166 final ParserCursor cursor = new ParserCursor(0, buffer.length());
167 final List<AuthChallenge> challenges = parser.parse(ChallengeType.TARGET, buffer, cursor);
168 Assertions.assertNotNull(challenges);
169 Assertions.assertEquals(2, challenges.size());
170
171 final AuthChallenge challenge1 = challenges.get(0);
172 Assertions.assertEquals("This", challenge1.getSchemeName());
173 Assertions.assertEquals("xxxxxxxxxxxxxxxxxxxxxx", challenge1.getValue());
174 Assertions.assertNull(challenge1.getParams());
175
176 final AuthChallenge challenge2 = challenges.get(1);
177 Assertions.assertEquals("That", challenge2.getSchemeName());
178 Assertions.assertEquals("yyyyyyyyyyyyyyyyyyyyyy", challenge2.getValue());
179 Assertions.assertNull(challenge2.getParams());
180 }
181
182 @Test
183 void testParseMultipleAuthChallengeWithParams() throws Exception {
184 final CharArrayBuffer buffer = new CharArrayBuffer(64);
185 buffer.append(StandardAuthScheme.BASIC + " realm=blah, param1 = this, param2=that, " +
186 StandardAuthScheme.BASIC + " realm=\"\\\"yada\\\"\", this, that=,this-and-that ");
187 final ParserCursor cursor = new ParserCursor(0, buffer.length());
188 final List<AuthChallenge> challenges = parser.parse(ChallengeType.TARGET, buffer, cursor);
189 Assertions.assertNotNull(challenges);
190 Assertions.assertEquals(2, challenges.size());
191
192 final AuthChallenge challenge1 = challenges.get(0);
193 Assertions.assertEquals(StandardAuthScheme.BASIC, challenge1.getSchemeName());
194 Assertions.assertNull(challenge1.getValue());
195 final List<NameValuePair> params1 = challenge1.getParams();
196 Assertions.assertNotNull(params1);
197 Assertions.assertEquals(3, params1.size());
198 assertThat(params1.get(0), NameValuePairMatcher.equals("realm", "blah"));
199 assertThat(params1.get(1), NameValuePairMatcher.equals("param1", "this"));
200 assertThat(params1.get(2), NameValuePairMatcher.equals("param2", "that"));
201
202 final AuthChallenge challenge2 = challenges.get(1);
203 Assertions.assertEquals(StandardAuthScheme.BASIC, challenge2.getSchemeName());
204 Assertions.assertNull(challenge2.getValue());
205 final List<NameValuePair> params2 = challenge2.getParams();
206 Assertions.assertNotNull(params2);
207 Assertions.assertEquals(4, params2.size());
208 assertThat(params2.get(0), NameValuePairMatcher.equals("realm", "\"yada\""));
209 assertThat(params2.get(1), NameValuePairMatcher.equals("this", null));
210 assertThat(params2.get(2), NameValuePairMatcher.equals("that", ""));
211 assertThat(params2.get(3), NameValuePairMatcher.equals("this-and-that", null));
212 }
213
214 @Test
215 void testParseMultipleAuthChallengeWithParamsContainingComma() throws Exception {
216 final CharArrayBuffer buffer = new CharArrayBuffer(64);
217 buffer.append(StandardAuthScheme.BASIC + " realm=blah, param1 = \"this, param2=that\", " +
218 StandardAuthScheme.BASIC + " realm=\"\\\"yada,,,,\\\"\"");
219 final ParserCursor cursor = new ParserCursor(0, buffer.length());
220 final List<AuthChallenge> challenges = parser.parse(ChallengeType.TARGET, buffer, cursor);
221 Assertions.assertNotNull(challenges);
222 Assertions.assertEquals(2, challenges.size());
223
224 final AuthChallenge challenge1 = challenges.get(0);
225 Assertions.assertEquals(StandardAuthScheme.BASIC, challenge1.getSchemeName());
226 Assertions.assertNull(challenge1.getValue());
227 final List<NameValuePair> params1 = challenge1.getParams();
228 Assertions.assertNotNull(params1);
229 Assertions.assertEquals(2, params1.size());
230 assertThat(params1.get(0), NameValuePairMatcher.equals("realm", "blah"));
231 assertThat(params1.get(1), NameValuePairMatcher.equals("param1", "this, param2=that"));
232
233 final AuthChallenge challenge2 = challenges.get(1);
234 Assertions.assertEquals(StandardAuthScheme.BASIC, challenge2.getSchemeName());
235 Assertions.assertNull(challenge2.getValue());
236 final List<NameValuePair> params2 = challenge2.getParams();
237 Assertions.assertNotNull(params2);
238 Assertions.assertEquals(1, params2.size());
239 assertThat(params2.get(0), NameValuePairMatcher.equals("realm", "\"yada,,,,\""));
240 }
241
242 @Test
243 void testParseEmptyAuthChallenge1() throws Exception {
244 final CharArrayBuffer buffer = new CharArrayBuffer(64);
245 buffer.append("This");
246 final ParserCursor cursor = new ParserCursor(0, buffer.length());
247 final List<AuthChallenge> challenges = parser.parse(ChallengeType.TARGET, buffer, cursor);
248 Assertions.assertNotNull(challenges);
249 Assertions.assertEquals(1, challenges.size());
250
251 final AuthChallenge challenge1 = challenges.get(0);
252 Assertions.assertEquals("This", challenge1.getSchemeName());
253 Assertions.assertNull(challenge1.getValue());
254 Assertions.assertNull(challenge1.getParams());
255 }
256
257 @Test
258 void testParseMalformedAuthChallenge1() {
259 final CharArrayBuffer buffer = new CharArrayBuffer(64);
260 buffer.append("This , ");
261 final ParserCursor cursor = new ParserCursor(0, buffer.length());
262 Assertions.assertThrows(ParseException.class, () ->
263 parser.parse(ChallengeType.TARGET, buffer, cursor));
264 }
265
266 @Test
267 void testParseMalformedAuthChallenge2() {
268 final CharArrayBuffer buffer = new CharArrayBuffer(64);
269 buffer.append("This = that");
270 final ParserCursor cursor = new ParserCursor(0, buffer.length());
271 Assertions.assertThrows(ParseException.class, () ->
272 parser.parse(ChallengeType.TARGET, buffer, cursor));
273 }
274
275 @Test
276 void testParseMalformedAuthChallenge3() {
277 final CharArrayBuffer buffer = new CharArrayBuffer(64);
278 buffer.append("blah blah blah");
279 final ParserCursor cursor = new ParserCursor(0, buffer.length());
280 Assertions.assertThrows(ParseException.class, () ->
281 parser.parse(ChallengeType.TARGET, buffer, cursor));
282 }
283
284 @Test
285 void testParseValidAuthChallenge1() throws Exception {
286 final CharArrayBuffer buffer = new CharArrayBuffer(64);
287 buffer.append("blah blah");
288 final ParserCursor cursor = new ParserCursor(0, buffer.length());
289 final List<AuthChallenge> challenges = parser.parse(ChallengeType.TARGET, buffer, cursor);
290 Assertions.assertNotNull(challenges);
291 Assertions.assertEquals(1, challenges.size());
292
293 final AuthChallenge challenge1 = challenges.get(0);
294 Assertions.assertEquals("blah", challenge1.getSchemeName());
295 Assertions.assertEquals("blah", challenge1.getValue());
296 Assertions.assertNull(challenge1.getParams());
297 }
298
299 @Test
300 void testParseValidAuthChallenge2() throws Exception {
301 final CharArrayBuffer buffer = new CharArrayBuffer(64);
302 buffer.append("blah blah, blah");
303 final ParserCursor cursor = new ParserCursor(0, buffer.length());
304 final List<AuthChallenge> challenges = parser.parse(ChallengeType.TARGET, buffer, cursor);
305 Assertions.assertNotNull(challenges);
306 Assertions.assertEquals(1, challenges.size());
307
308 final AuthChallenge challenge1 = challenges.get(0);
309 Assertions.assertEquals("blah", challenge1.getSchemeName());
310 Assertions.assertNull(challenge1.getValue());
311 final List<NameValuePair> params1 = challenge1.getParams();
312 Assertions.assertNotNull(params1);
313 Assertions.assertEquals(2, params1.size());
314 assertThat(params1.get(0), NameValuePairMatcher.equals("blah", null));
315 assertThat(params1.get(1), NameValuePairMatcher.equals("blah", null));
316 }
317
318 @Test
319 void testParseParameterAndToken68AuthChallengeMix() throws Exception {
320 final CharArrayBuffer buffer = new CharArrayBuffer(64);
321 buffer.append("scheme1 aaaa , scheme2 aaaa==, scheme3 aaaa=aaaa, scheme4 aaaa=");
322 final ParserCursor cursor = new ParserCursor(0, buffer.length());
323 final List<AuthChallenge> challenges = parser.parse(ChallengeType.TARGET, buffer, cursor);
324 Assertions.assertNotNull(challenges);
325 Assertions.assertEquals(4, challenges.size());
326 final AuthChallenge challenge1 = challenges.get(0);
327 assertThat(challenge1.getSchemeName(), CoreMatchers.equalTo("scheme1"));
328 assertThat(challenge1.getValue(), CoreMatchers.equalTo("aaaa"));
329 assertThat(challenge1.getParams(), CoreMatchers.nullValue());
330 final AuthChallenge challenge2 = challenges.get(1);
331 assertThat(challenge2.getSchemeName(), CoreMatchers.equalTo("scheme2"));
332 assertThat(challenge2.getValue(), CoreMatchers.equalTo("aaaa=="));
333 assertThat(challenge2.getParams(), CoreMatchers.nullValue());
334 final AuthChallenge challenge3 = challenges.get(2);
335 assertThat(challenge3.getSchemeName(), CoreMatchers.equalTo("scheme3"));
336 assertThat(challenge3.getValue(), CoreMatchers.nullValue());
337 assertThat(challenge3.getParams(), CoreMatchers.notNullValue());
338 assertThat(challenge3.getParams().size(), CoreMatchers.equalTo(1));
339 assertThat(challenge3.getParams().get(0), NameValuePairMatcher.equals("aaaa", "aaaa"));
340 final AuthChallenge challenge4 = challenges.get(3);
341 assertThat(challenge4.getSchemeName(), CoreMatchers.equalTo("scheme4"));
342 assertThat(challenge4.getValue(), CoreMatchers.equalTo("aaaa="));
343 assertThat(challenge4.getParams(), CoreMatchers.nullValue());
344 }
345
346 }