View Javadoc
1   /*
2    * ====================================================================
3    * Licensed to the Apache Software Foundation (ASF) under one
4    * or more contributor license agreements.  See the NOTICE file
5    * distributed with this work for additional information
6    * regarding copyright ownership.  The ASF licenses this file
7    * to you under the Apache License, Version 2.0 (the
8    * "License"); you may not use this file except in compliance
9    * with the License.  You may obtain a copy of the License at
10   *
11   *   http://www.apache.org/licenses/LICENSE-2.0
12   *
13   * Unless required by applicable law or agreed to in writing,
14   * software distributed under the License is distributed on an
15   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16   * KIND, either express or implied.  See the License for the
17   * specific language governing permissions and limitations
18   * under the License.
19   * ====================================================================
20   *
21   * This software consists of voluntary contributions made by many
22   * individuals on behalf of the Apache Software Foundation.  For more
23   * information on the Apache Software Foundation, please see
24   * <http://www.apache.org/>.
25   *
26   */
27  package org.apache.hc.client5.http.impl.auth;
28  
29  import java.util.List;
30  
31  import org.apache.hc.client5.http.NameValuePairMatcher;
32  import org.apache.hc.client5.http.auth.AuthChallenge;
33  import org.apache.hc.client5.http.auth.ChallengeType;
34  import org.apache.hc.client5.http.auth.StandardAuthScheme;
35  import org.apache.hc.core5.http.NameValuePair;
36  import org.apache.hc.core5.http.ParseException;
37  import org.apache.hc.core5.http.message.ParserCursor;
38  import org.apache.hc.core5.util.CharArrayBuffer;
39  import org.hamcrest.CoreMatchers;
40  import org.junit.Assert;
41  import org.junit.Before;
42  import org.junit.Test;
43  
44  public class TestAuthChallengeParser {
45  
46      private AuthChallengeParser parser;
47  
48      @Before
49      public void setUp() throws Exception {
50          this.parser = new AuthChallengeParser();
51      }
52  
53      @Test
54      public void testParseTokenTerminatedByBlank() throws Exception {
55          final CharArrayBuffer buffer = new CharArrayBuffer(64);
56          buffer.append("aaabbbbccc ");
57          final ParserCursor cursor = new ParserCursor(0, buffer.length());
58          Assert.assertThat(parser.parseToken(buffer, cursor), CoreMatchers.equalTo("aaabbbbccc"));
59      }
60  
61      @Test
62      public void testParseTokenTerminatedByComma() throws Exception {
63          final CharArrayBuffer buffer = new CharArrayBuffer(64);
64          buffer.append("aaabbbbccc, ");
65          final ParserCursor cursor = new ParserCursor(0, buffer.length());
66          Assert.assertThat(parser.parseToken(buffer, cursor), CoreMatchers.equalTo("aaabbbbccc"));
67      }
68  
69      @Test
70      public void testParseTokenTerminatedByEndOfStream() throws Exception {
71          final CharArrayBuffer buffer = new CharArrayBuffer(64);
72          buffer.append("aaabbbbccc");
73          final ParserCursor cursor = new ParserCursor(0, buffer.length());
74          Assert.assertThat(parser.parseToken(buffer, cursor), CoreMatchers.equalTo("aaabbbbccc"));
75      }
76  
77      @Test
78      public void testParsePaddedToken68() throws Exception {
79          final CharArrayBuffer buffer = new CharArrayBuffer(64);
80          buffer.append("aaabbbbccc==== ");
81          final ParserCursor cursor = new ParserCursor(0, buffer.length());
82          Assert.assertThat(parser.parseToken(buffer, cursor), CoreMatchers.equalTo("aaabbbbccc===="));
83          Assert.assertThat(cursor.atEnd(), CoreMatchers.equalTo(false));
84          Assert.assertThat(buffer.charAt(cursor.getPos()), CoreMatchers.equalTo(' '));
85      }
86  
87      @Test
88      public void testParsePaddedToken68SingleEqual() throws Exception {
89          final CharArrayBuffer buffer = new CharArrayBuffer(64);
90          buffer.append("aaabbbbccc=");
91          final ParserCursor cursor = new ParserCursor(0, buffer.length());
92          Assert.assertThat(parser.parseToken(buffer, cursor), CoreMatchers.equalTo("aaabbbbccc="));
93          Assert.assertThat(cursor.atEnd(), CoreMatchers.equalTo(true));
94      }
95  
96      @Test
97      public void testParsePaddedToken68MultipleEquals() throws Exception {
98          final CharArrayBuffer buffer = new CharArrayBuffer(16);
99          buffer.append("aaabbbbccc======");
100         final ParserCursor cursor = new ParserCursor(0, buffer.length());
101         Assert.assertThat(parser.parseToken(buffer, cursor), CoreMatchers.equalTo("aaabbbbccc======"));
102         Assert.assertThat(cursor.atEnd(), CoreMatchers.equalTo(true));
103     }
104 
105     @Test
106     public void testParsePaddedToken68TerminatedByComma() throws Exception {
107         final CharArrayBuffer buffer = new CharArrayBuffer(64);
108         buffer.append("aaabbbbccc====,");
109         final ParserCursor cursor = new ParserCursor(0, buffer.length());
110         Assert.assertThat(parser.parseToken(buffer, cursor), CoreMatchers.equalTo("aaabbbbccc===="));
111         Assert.assertThat(cursor.atEnd(), CoreMatchers.equalTo(false));
112         Assert.assertThat(buffer.charAt(cursor.getPos()), CoreMatchers.equalTo(','));
113     }
114 
115     @Test
116     public void testParseTokenTerminatedByParameter() throws Exception {
117         final CharArrayBuffer buffer = new CharArrayBuffer(64);
118         buffer.append("aaabbbbccc=blah");
119         final ParserCursor cursor = new ParserCursor(0, buffer.length());
120         Assert.assertThat(parser.parseToken(buffer, cursor), CoreMatchers.equalTo("aaabbbbccc"));
121         Assert.assertThat(cursor.atEnd(), CoreMatchers.equalTo(false));
122         Assert.assertThat(buffer.charAt(cursor.getPos()), CoreMatchers.equalTo('='));
123     }
124 
125     @Test
126     public void testParseBasicAuthChallenge() throws Exception {
127         final CharArrayBuffer buffer = new CharArrayBuffer(64);
128         buffer.append(StandardAuthScheme.BASIC + " realm=blah");
129         final ParserCursor cursor = new ParserCursor(0, buffer.length());
130         final List<AuthChallenge> challenges = parser.parse(ChallengeType.TARGET, buffer, cursor);
131         Assert.assertNotNull(challenges);
132         Assert.assertEquals(1, challenges.size());
133         final AuthChallenge challenge1 = challenges.get(0);
134         Assert.assertEquals(StandardAuthScheme.BASIC, challenge1.getSchemeName());
135         Assert.assertEquals(null, challenge1.getValue());
136         final List<NameValuePair> params = challenge1.getParams();
137         Assert.assertNotNull(params);
138         Assert.assertEquals(1, params.size());
139         Assert.assertThat(params.get(0), NameValuePairMatcher.equals("realm", "blah"));
140     }
141 
142     @Test
143     public void testParseAuthChallengeWithBlanks() throws Exception {
144         final CharArrayBuffer buffer = new CharArrayBuffer(64);
145         buffer.append("   " + StandardAuthScheme.BASIC + "  realm = blah   ");
146         final ParserCursor cursor = new ParserCursor(0, buffer.length());
147         final List<AuthChallenge> challenges = parser.parse(ChallengeType.TARGET, buffer, cursor);
148         Assert.assertNotNull(challenges);
149         Assert.assertEquals(1, challenges.size());
150         final AuthChallenge challenge1 = challenges.get(0);
151         Assert.assertEquals(StandardAuthScheme.BASIC, challenge1.getSchemeName());
152         Assert.assertEquals(null, challenge1.getValue());
153         final List<NameValuePair> params = challenge1.getParams();
154         Assert.assertNotNull(params);
155         Assert.assertEquals(1, params.size());
156         Assert.assertThat(params.get(0), NameValuePairMatcher.equals("realm", "blah"));
157     }
158 
159     @Test
160     public void testParseMultipleAuthChallenge() throws Exception {
161         final CharArrayBuffer buffer = new CharArrayBuffer(64);
162         buffer.append("This  xxxxxxxxxxxxxxxxxxxxxx, " +
163                 "That yyyyyyyyyyyyyyyyyyyyyy  ");
164         final ParserCursor cursor = new ParserCursor(0, buffer.length());
165         final List<AuthChallenge> challenges = parser.parse(ChallengeType.TARGET, buffer, cursor);
166         Assert.assertNotNull(challenges);
167         Assert.assertEquals(2, challenges.size());
168 
169         final AuthChallenge challenge1 = challenges.get(0);
170         Assert.assertEquals("This", challenge1.getSchemeName());
171         Assert.assertEquals("xxxxxxxxxxxxxxxxxxxxxx", challenge1.getValue());
172         Assert.assertNull(challenge1.getParams());
173 
174         final AuthChallenge challenge2 = challenges.get(1);
175         Assert.assertEquals("That", challenge2.getSchemeName());
176         Assert.assertEquals("yyyyyyyyyyyyyyyyyyyyyy", challenge2.getValue());
177         Assert.assertNull(challenge2.getParams());
178     }
179 
180     @Test
181     public void testParseMultipleAuthChallengeWithParams() throws Exception {
182         final CharArrayBuffer buffer = new CharArrayBuffer(64);
183         buffer.append(StandardAuthScheme.BASIC + " realm=blah, param1 = this, param2=that, " +
184                 StandardAuthScheme.BASIC + " realm=\"\\\"yada\\\"\", this, that=,this-and-that  ");
185         final ParserCursor cursor = new ParserCursor(0, buffer.length());
186         final List<AuthChallenge> challenges = parser.parse(ChallengeType.TARGET, buffer, cursor);
187         Assert.assertNotNull(challenges);
188         Assert.assertEquals(2, challenges.size());
189 
190         final AuthChallenge challenge1 = challenges.get(0);
191         Assert.assertEquals(StandardAuthScheme.BASIC, challenge1.getSchemeName());
192         Assert.assertEquals(null, challenge1.getValue());
193         final List<NameValuePair> params1 = challenge1.getParams();
194         Assert.assertNotNull(params1);
195         Assert.assertEquals(3, params1.size());
196         Assert.assertThat(params1.get(0), NameValuePairMatcher.equals("realm", "blah"));
197         Assert.assertThat(params1.get(1), NameValuePairMatcher.equals("param1", "this"));
198         Assert.assertThat(params1.get(2), NameValuePairMatcher.equals("param2", "that"));
199 
200         final AuthChallenge challenge2 = challenges.get(1);
201         Assert.assertEquals(StandardAuthScheme.BASIC, challenge2.getSchemeName());
202         Assert.assertEquals(null, challenge2.getValue());
203         final List<NameValuePair> params2 = challenge2.getParams();
204         Assert.assertNotNull(params2);
205         Assert.assertEquals(4, params2.size());
206         Assert.assertThat(params2.get(0), NameValuePairMatcher.equals("realm", "\"yada\""));
207         Assert.assertThat(params2.get(1), NameValuePairMatcher.equals("this", null));
208         Assert.assertThat(params2.get(2), NameValuePairMatcher.equals("that", ""));
209         Assert.assertThat(params2.get(3), NameValuePairMatcher.equals("this-and-that", null));
210     }
211 
212     @Test
213     public void testParseMultipleAuthChallengeWithParamsContainingComma() throws Exception {
214         final CharArrayBuffer buffer = new CharArrayBuffer(64);
215         buffer.append(StandardAuthScheme.BASIC + " realm=blah, param1 = \"this, param2=that\", " +
216                 StandardAuthScheme.BASIC + " realm=\"\\\"yada,,,,\\\"\"");
217         final ParserCursor cursor = new ParserCursor(0, buffer.length());
218         final List<AuthChallenge> challenges = parser.parse(ChallengeType.TARGET, buffer, cursor);
219         Assert.assertNotNull(challenges);
220         Assert.assertEquals(2, challenges.size());
221 
222         final AuthChallenge challenge1 = challenges.get(0);
223         Assert.assertEquals(StandardAuthScheme.BASIC, challenge1.getSchemeName());
224         Assert.assertEquals(null, challenge1.getValue());
225         final List<NameValuePair> params1 = challenge1.getParams();
226         Assert.assertNotNull(params1);
227         Assert.assertEquals(2, params1.size());
228         Assert.assertThat(params1.get(0), NameValuePairMatcher.equals("realm", "blah"));
229         Assert.assertThat(params1.get(1), NameValuePairMatcher.equals("param1", "this, param2=that"));
230 
231         final AuthChallenge challenge2 = challenges.get(1);
232         Assert.assertEquals(StandardAuthScheme.BASIC, challenge2.getSchemeName());
233         Assert.assertEquals(null, challenge2.getValue());
234         final List<NameValuePair> params2 = challenge2.getParams();
235         Assert.assertNotNull(params2);
236         Assert.assertEquals(1, params2.size());
237         Assert.assertThat(params2.get(0), NameValuePairMatcher.equals("realm", "\"yada,,,,\""));
238     }
239 
240     @Test
241     public void testParseEmptyAuthChallenge1() throws Exception {
242         final CharArrayBuffer buffer = new CharArrayBuffer(64);
243         buffer.append("This");
244         final ParserCursor cursor = new ParserCursor(0, buffer.length());
245         final List<AuthChallenge> challenges = parser.parse(ChallengeType.TARGET, buffer, cursor);
246         Assert.assertNotNull(challenges);
247         Assert.assertEquals(1, challenges.size());
248 
249         final AuthChallenge challenge1 = challenges.get(0);
250         Assert.assertEquals("This", challenge1.getSchemeName());
251         Assert.assertEquals(null, challenge1.getValue());
252         Assert.assertNull(challenge1.getParams());
253     }
254 
255     @Test(expected = ParseException.class)
256     public void testParseMalformedAuthChallenge1() throws Exception {
257         final CharArrayBuffer buffer = new CharArrayBuffer(64);
258         buffer.append("This , ");
259         final ParserCursor cursor = new ParserCursor(0, buffer.length());
260         parser.parse(ChallengeType.TARGET, buffer, cursor);
261     }
262 
263     @Test(expected = ParseException.class)
264     public void testParseMalformedAuthChallenge2() throws Exception {
265         final CharArrayBuffer buffer = new CharArrayBuffer(64);
266         buffer.append("This = that");
267         final ParserCursor cursor = new ParserCursor(0, buffer.length());
268         parser.parse(ChallengeType.TARGET, buffer, cursor);
269     }
270 
271     @Test(expected = ParseException.class)
272     public void testParseMalformedAuthChallenge3() throws Exception {
273         final CharArrayBuffer buffer = new CharArrayBuffer(64);
274         buffer.append("blah blah blah");
275         final ParserCursor cursor = new ParserCursor(0, buffer.length());
276         parser.parse(ChallengeType.TARGET, buffer, cursor);
277     }
278 
279     @Test
280     public void testParseValidAuthChallenge1() throws Exception {
281         final CharArrayBuffer buffer = new CharArrayBuffer(64);
282         buffer.append("blah blah");
283         final ParserCursor cursor = new ParserCursor(0, buffer.length());
284         final List<AuthChallenge> challenges = parser.parse(ChallengeType.TARGET, buffer, cursor);
285         Assert.assertNotNull(challenges);
286         Assert.assertEquals(1, challenges.size());
287 
288         final AuthChallenge challenge1 = challenges.get(0);
289         Assert.assertEquals("blah", challenge1.getSchemeName());
290         Assert.assertEquals("blah", challenge1.getValue());
291         Assert.assertNull(challenge1.getParams());
292     }
293 
294     @Test
295     public void testParseValidAuthChallenge2() throws Exception {
296         final CharArrayBuffer buffer = new CharArrayBuffer(64);
297         buffer.append("blah blah, blah");
298         final ParserCursor cursor = new ParserCursor(0, buffer.length());
299         final List<AuthChallenge> challenges = parser.parse(ChallengeType.TARGET, buffer, cursor);
300         Assert.assertNotNull(challenges);
301         Assert.assertEquals(1, challenges.size());
302 
303         final AuthChallenge challenge1 = challenges.get(0);
304         Assert.assertEquals("blah", challenge1.getSchemeName());
305         Assert.assertEquals(null, challenge1.getValue());
306         final List<NameValuePair> params1 = challenge1.getParams();
307         Assert.assertNotNull(params1);
308         Assert.assertEquals(2, params1.size());
309         Assert.assertThat(params1.get(0), NameValuePairMatcher.equals("blah", null));
310         Assert.assertThat(params1.get(1), NameValuePairMatcher.equals("blah", null));
311     }
312 
313     @Test
314     public void testParseEmptyNTLMAuthChallenge() throws Exception {
315         final CharArrayBuffer buffer = new CharArrayBuffer(64);
316         buffer.append(StandardAuthScheme.NTLM);
317         final ParserCursor cursor = new ParserCursor(0, buffer.length());
318         final List<AuthChallenge> challenges = parser.parse(ChallengeType.TARGET, buffer, cursor);
319         Assert.assertNotNull(challenges);
320         Assert.assertEquals(1, challenges.size());
321         final AuthChallenge challenge1 = challenges.get(0);
322         Assert.assertEquals(StandardAuthScheme.NTLM, challenge1.getSchemeName());
323         Assert.assertEquals(null, challenge1.getValue());
324     }
325 
326     @Test
327     public void testParseParameterAndToken68AuthChallengeMix() throws Exception {
328         final CharArrayBuffer buffer = new CharArrayBuffer(64);
329         buffer.append("scheme1 aaaa  , scheme2 aaaa==,  scheme3 aaaa=aaaa, scheme4 aaaa=");
330         final ParserCursor cursor = new ParserCursor(0, buffer.length());
331         final List<AuthChallenge> challenges = parser.parse(ChallengeType.TARGET, buffer, cursor);
332         Assert.assertNotNull(challenges);
333         Assert.assertEquals(4, challenges.size());
334         final AuthChallenge challenge1 = challenges.get(0);
335         Assert.assertThat(challenge1.getSchemeName(), CoreMatchers.equalTo("scheme1"));
336         Assert.assertThat(challenge1.getValue(), CoreMatchers.equalTo("aaaa"));
337         Assert.assertThat(challenge1.getParams(), CoreMatchers.nullValue());
338         final AuthChallenge challenge2 = challenges.get(1);
339         Assert.assertThat(challenge2.getSchemeName(), CoreMatchers.equalTo("scheme2"));
340         Assert.assertThat(challenge2.getValue(), CoreMatchers.equalTo("aaaa=="));
341         Assert.assertThat(challenge2.getParams(), CoreMatchers.nullValue());
342         final AuthChallenge challenge3 = challenges.get(2);
343         Assert.assertThat(challenge3.getSchemeName(), CoreMatchers.equalTo("scheme3"));
344         Assert.assertThat(challenge3.getValue(), CoreMatchers.nullValue());
345         Assert.assertThat(challenge3.getParams(), CoreMatchers.notNullValue());
346         Assert.assertThat(challenge3.getParams().size(), CoreMatchers.equalTo(1));
347         Assert.assertThat(challenge3.getParams().get(0), NameValuePairMatcher.equals("aaaa", "aaaa"));
348         final AuthChallenge challenge4 = challenges.get(3);
349         Assert.assertThat(challenge4.getSchemeName(), CoreMatchers.equalTo("scheme4"));
350         Assert.assertThat(challenge4.getValue(), CoreMatchers.equalTo("aaaa="));
351         Assert.assertThat(challenge4.getParams(), CoreMatchers.nullValue());
352     }
353 
354 }