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  
28  package org.apache.http.client.utils;
29  
30  import java.net.URI;
31  import java.util.ArrayList;
32  import java.util.List;
33  
34  import org.apache.http.Consts;
35  import org.apache.http.NameValuePair;
36  import org.apache.http.entity.ContentType;
37  import org.apache.http.entity.StringEntity;
38  import org.apache.http.message.BasicNameValuePair;
39  import org.apache.http.protocol.HTTP;
40  import org.junit.Assert;
41  import org.junit.Test;
42  
43  public class TestURLEncodedUtils {
44  
45      @Test
46      public void testParseURLCodedContent() throws Exception {
47          List <NameValuePair> result;
48  
49          result = parse("");
50          Assert.assertTrue(result.isEmpty());
51  
52          result = parse("Name0");
53          Assert.assertEquals(1, result.size());
54          assertNameValuePair(result.get(0), "Name0", null);
55  
56          result = parse("Name1=Value1");
57          Assert.assertEquals(1, result.size());
58          assertNameValuePair(result.get(0), "Name1", "Value1");
59  
60          result = parse("Name2=");
61          Assert.assertEquals(1, result.size());
62          assertNameValuePair(result.get(0), "Name2", "");
63  
64          result = parse("Name3");
65          Assert.assertEquals(1, result.size());
66          assertNameValuePair(result.get(0), "Name3", null);
67  
68          result = parse("Name4=Value%204%21");
69          Assert.assertEquals(1, result.size());
70          assertNameValuePair(result.get(0), "Name4", "Value 4!");
71  
72          result = parse("Name4=Value%2B4%21");
73          Assert.assertEquals(1, result.size());
74          assertNameValuePair(result.get(0), "Name4", "Value+4!");
75  
76          result = parse("Name4=Value%204%21%20%214");
77          Assert.assertEquals(1, result.size());
78          assertNameValuePair(result.get(0), "Name4", "Value 4! !4");
79  
80          result = parse("Name5=aaa&Name6=bbb");
81          Assert.assertEquals(2, result.size());
82          assertNameValuePair(result.get(0), "Name5", "aaa");
83          assertNameValuePair(result.get(1), "Name6", "bbb");
84  
85          result = parse("Name7=aaa&Name7=b%2Cb&Name7=ccc");
86          Assert.assertEquals(3, result.size());
87          assertNameValuePair(result.get(0), "Name7", "aaa");
88          assertNameValuePair(result.get(1), "Name7", "b,b");
89          assertNameValuePair(result.get(2), "Name7", "ccc");
90  
91          result = parse("Name8=xx%2C%20%20yy%20%20%2Czz");
92          Assert.assertEquals(1, result.size());
93          assertNameValuePair(result.get(0), "Name8", "xx,  yy  ,zz");
94  
95          result = parse("price=10%20%E2%82%AC");
96          Assert.assertEquals(1, result.size());
97          assertNameValuePair(result.get(0), "price", "10 \u20AC");
98      }
99  
100     @Test
101     public void testParseURLCodedContentString() throws Exception {
102         List <NameValuePair> result;
103 
104         result = parseString("");
105         Assert.assertTrue(result.isEmpty());
106 
107         result = parseString("Name0");
108         Assert.assertEquals(1, result.size());
109         assertNameValuePair(result.get(0), "Name0", null);
110 
111         result = parseString("Name1=Value1");
112         Assert.assertEquals(1, result.size());
113         assertNameValuePair(result.get(0), "Name1", "Value1");
114 
115         result = parseString("Name2=");
116         Assert.assertEquals(1, result.size());
117         assertNameValuePair(result.get(0), "Name2", "");
118 
119         result = parseString("Name3");
120         Assert.assertEquals(1, result.size());
121         assertNameValuePair(result.get(0), "Name3", null);
122 
123         result = parseString("Name4=Value%204%21");
124         Assert.assertEquals(1, result.size());
125         assertNameValuePair(result.get(0), "Name4", "Value 4!");
126 
127         result = parseString("Name4=Value%2B4%21");
128         Assert.assertEquals(1, result.size());
129         assertNameValuePair(result.get(0), "Name4", "Value+4!");
130 
131         result = parseString("Name4=Value%204%21%20%214");
132         Assert.assertEquals(1, result.size());
133         assertNameValuePair(result.get(0), "Name4", "Value 4! !4");
134 
135         result = parseString("Name5=aaa&Name6=bbb");
136         Assert.assertEquals(2, result.size());
137         assertNameValuePair(result.get(0), "Name5", "aaa");
138         assertNameValuePair(result.get(1), "Name6", "bbb");
139 
140         result = parseString("Name7=aaa&Name7=b%2Cb&Name7=ccc");
141         Assert.assertEquals(3, result.size());
142         assertNameValuePair(result.get(0), "Name7", "aaa");
143         assertNameValuePair(result.get(1), "Name7", "b,b");
144         assertNameValuePair(result.get(2), "Name7", "ccc");
145 
146         result = parseString("Name8=xx%2C%20%20yy%20%20%2Czz");
147         Assert.assertEquals(1, result.size());
148         assertNameValuePair(result.get(0), "Name8", "xx,  yy  ,zz");
149 
150         result = parseString("price=10%20%E2%82%AC");
151         Assert.assertEquals(1, result.size());
152         assertNameValuePair(result.get(0), "price", "10 \u20AC");
153     }
154 
155     @Test
156     public void testParseInvalidURLCodedContent() throws Exception {
157         List <NameValuePair> result;
158 
159         result = parse("name=%");
160         Assert.assertEquals(1, result.size());
161         assertNameValuePair(result.get(0), "name", "%");
162 
163         result = parse("name=%a");
164         Assert.assertEquals(1, result.size());
165         assertNameValuePair(result.get(0), "name", "%a");
166 
167         result = parse("name=%wa%20");
168         Assert.assertEquals(1, result.size());
169         assertNameValuePair(result.get(0), "name", "%wa ");
170     }
171 
172     @Test
173     public void testEmptyQuery() throws Exception {
174         final List<NameValuePair> result = URLEncodedUtils.parse("", Consts.UTF_8);
175         Assert.assertEquals(0, result.size());
176         // [HTTPCLIENT-1889]:
177         result.add(new BasicNameValuePair("key", "value"));
178     }
179 
180     @Test
181     public void testParseEntity() throws Exception {
182         final StringEntity entity = new StringEntity("Name1=Value1");
183 
184         entity.setContentType(URLEncodedUtils.CONTENT_TYPE);
185         final List <NameValuePair> result = URLEncodedUtils.parse(entity);
186         Assert.assertEquals(1, result.size());
187         assertNameValuePair(result.get(0), "Name1", "Value1");
188 
189         entity.setContentType("text/test");
190         Assert.assertTrue(URLEncodedUtils.parse(entity).isEmpty());
191     }
192 
193     private static final int SWISS_GERMAN_HELLO [] = {
194         0x47, 0x72, 0xFC, 0x65, 0x7A, 0x69, 0x5F, 0x7A, 0xE4, 0x6D, 0xE4
195     };
196 
197     private static final int RUSSIAN_HELLO [] = {
198         0x412, 0x441, 0x435, 0x43C, 0x5F, 0x43F, 0x440, 0x438,
199         0x432, 0x435, 0x442
200     };
201 
202     private static String constructString(final int [] unicodeChars) {
203         final StringBuilder buffer = new StringBuilder();
204         if (unicodeChars != null) {
205             for (final int unicodeChar : unicodeChars) {
206                 buffer.append((char)unicodeChar);
207             }
208         }
209         return buffer.toString();
210     }
211 
212     @Test
213     public void testParseUTF8Entity() throws Exception {
214         final String ru_hello = constructString(RUSSIAN_HELLO);
215         final String ch_hello = constructString(SWISS_GERMAN_HELLO);
216         final List <NameValuePair> parameters = new ArrayList<NameValuePair>();
217         parameters.add(new BasicNameValuePair("russian", ru_hello));
218         parameters.add(new BasicNameValuePair("swiss", ch_hello));
219 
220         final String s = URLEncodedUtils.format(parameters, Consts.UTF_8);
221 
222         Assert.assertEquals("russian=%D0%92%D1%81%D0%B5%D0%BC_%D0%BF%D1%80%D0%B8%D0%B2%D0%B5%D1%82" +
223                 "&swiss=Gr%C3%BCezi_z%C3%A4m%C3%A4", s);
224 
225         final StringEntity entity = new StringEntity(s, ContentType.create(
226                 URLEncodedUtils.CONTENT_TYPE, Consts.UTF_8));
227         final List <NameValuePair> result = URLEncodedUtils.parse(entity);
228         Assert.assertEquals(2, result.size());
229         assertNameValuePair(result.get(0), "russian", ru_hello);
230         assertNameValuePair(result.get(1), "swiss", ch_hello);
231     }
232 
233     @Test
234     public void testParseUTF8Ampersand1String() throws Exception {
235         final String ru_hello = constructString(RUSSIAN_HELLO);
236         final String ch_hello = constructString(SWISS_GERMAN_HELLO);
237         final List <NameValuePair> parameters = new ArrayList<NameValuePair>();
238         parameters.add(new BasicNameValuePair("russian", ru_hello));
239         parameters.add(new BasicNameValuePair("swiss", ch_hello));
240 
241         final String s = URLEncodedUtils.format(parameters, Consts.UTF_8);
242 
243         final List <NameValuePair> result = URLEncodedUtils.parse(s, Consts.UTF_8);
244         Assert.assertEquals(2, result.size());
245         assertNameValuePair(result.get(0), "russian", ru_hello);
246         assertNameValuePair(result.get(1), "swiss", ch_hello);
247     }
248 
249     @Test
250     public void testParseUTF8Ampersand2String() throws Exception {
251         testParseUTF8String('&');
252     }
253 
254     @Test
255     public void testParseUTF8SemicolonString() throws Exception {
256         testParseUTF8String(';');
257     }
258 
259     private void testParseUTF8String(final char parameterSeparator) throws Exception {
260         final String ru_hello = constructString(RUSSIAN_HELLO);
261         final String ch_hello = constructString(SWISS_GERMAN_HELLO);
262         final List <NameValuePair> parameters = new ArrayList<NameValuePair>();
263         parameters.add(new BasicNameValuePair("russian", ru_hello));
264         parameters.add(new BasicNameValuePair("swiss", ch_hello));
265 
266         final String s = URLEncodedUtils.format(parameters, parameterSeparator, Consts.UTF_8);
267 
268         final List <NameValuePair> result1 = URLEncodedUtils.parse(s, Consts.UTF_8);
269         Assert.assertEquals(2, result1.size());
270         assertNameValuePair(result1.get(0), "russian", ru_hello);
271         assertNameValuePair(result1.get(1), "swiss", ch_hello);
272 
273         final List <NameValuePair> result2 = URLEncodedUtils.parse(s, Consts.UTF_8, parameterSeparator);
274         Assert.assertEquals(result1, result2);
275     }
276 
277     @Test
278     public void testParseEntityDefaultContentType() throws Exception {
279         final String ch_hello = constructString(SWISS_GERMAN_HELLO);
280         final String us_hello = "hi there";
281         final List <NameValuePair> parameters = new ArrayList<NameValuePair>();
282         parameters.add(new BasicNameValuePair("english", us_hello));
283         parameters.add(new BasicNameValuePair("swiss", ch_hello));
284 
285         final String s = URLEncodedUtils.format(parameters, HTTP.DEF_CONTENT_CHARSET);
286 
287         Assert.assertEquals("english=hi+there&swiss=Gr%FCezi_z%E4m%E4", s);
288 
289         final StringEntity entity = new StringEntity(s, ContentType.create(
290                 URLEncodedUtils.CONTENT_TYPE, HTTP.DEF_CONTENT_CHARSET));
291         final List <NameValuePair> result = URLEncodedUtils.parse(entity);
292         Assert.assertEquals(2, result.size());
293         assertNameValuePair(result.get(0), "english", us_hello);
294         assertNameValuePair(result.get(1), "swiss", ch_hello);
295     }
296 
297     @Test
298     public void testIsEncoded() throws Exception {
299         final StringEntity entity = new StringEntity("...");
300 
301         entity.setContentType(URLEncodedUtils.CONTENT_TYPE);
302         Assert.assertTrue(URLEncodedUtils.isEncoded(entity));
303 
304         entity.setContentType(URLEncodedUtils.CONTENT_TYPE + "; charset=US-ASCII");
305         Assert.assertTrue(URLEncodedUtils.isEncoded(entity));
306 
307         entity.setContentType("text/test");
308         Assert.assertFalse(URLEncodedUtils.isEncoded(entity));
309     }
310 
311     @Test
312     public void testFormat() throws Exception {
313         final List <NameValuePair> params = new ArrayList <NameValuePair>();
314         Assert.assertEquals(0, URLEncodedUtils.format(params, Consts.ASCII).length());
315 
316         params.clear();
317         params.add(new BasicNameValuePair("Name0", null));
318         Assert.assertEquals("Name0", URLEncodedUtils.format(params, Consts.ASCII));
319 
320         params.clear();
321         params.add(new BasicNameValuePair("Name1", "Value1"));
322         Assert.assertEquals("Name1=Value1", URLEncodedUtils.format(params, Consts.ASCII));
323 
324         params.clear();
325         params.add(new BasicNameValuePair("Name2", ""));
326         Assert.assertEquals("Name2=", URLEncodedUtils.format(params, Consts.ASCII));
327 
328         params.clear();
329         params.add(new BasicNameValuePair("Name4", "Value 4&"));
330         Assert.assertEquals("Name4=Value+4%26", URLEncodedUtils.format(params, Consts.ASCII));
331 
332         params.clear();
333         params.add(new BasicNameValuePair("Name4", "Value+4&"));
334         Assert.assertEquals("Name4=Value%2B4%26", URLEncodedUtils.format(params, Consts.ASCII));
335 
336         params.clear();
337         params.add(new BasicNameValuePair("Name4", "Value 4& =4"));
338         Assert.assertEquals("Name4=Value+4%26+%3D4", URLEncodedUtils.format(params, Consts.ASCII));
339 
340         params.clear();
341         params.add(new BasicNameValuePair("Name5", "aaa"));
342         params.add(new BasicNameValuePair("Name6", "bbb"));
343         Assert.assertEquals("Name5=aaa&Name6=bbb", URLEncodedUtils.format(params, Consts.ASCII));
344 
345         params.clear();
346         params.add(new BasicNameValuePair("Name7", "aaa"));
347         params.add(new BasicNameValuePair("Name7", "b,b"));
348         params.add(new BasicNameValuePair("Name7", "ccc"));
349         Assert.assertEquals("Name7=aaa&Name7=b%2Cb&Name7=ccc", URLEncodedUtils.format(params, Consts.ASCII));
350         Assert.assertEquals("Name7=aaa&Name7=b%2Cb&Name7=ccc", URLEncodedUtils.format(params, '&', Consts.ASCII));
351         Assert.assertEquals("Name7=aaa;Name7=b%2Cb;Name7=ccc", URLEncodedUtils.format(params, ';', Consts.ASCII));
352 
353         params.clear();
354         params.add(new BasicNameValuePair("Name8", "xx,  yy  ,zz"));
355         Assert.assertEquals("Name8=xx%2C++yy++%2Czz", URLEncodedUtils.format(params, Consts.ASCII));
356     }
357 
358     @Test
359     public void testFormatString() throws Exception { // as above, using String
360         final List <NameValuePair> params = new ArrayList <NameValuePair>();
361         Assert.assertEquals(0, URLEncodedUtils.format(params, Consts.ASCII).length());
362 
363         params.clear();
364         params.add(new BasicNameValuePair("Name0", null));
365         Assert.assertEquals("Name0", URLEncodedUtils.format(params, Consts.ASCII));
366 
367         params.clear();
368         params.add(new BasicNameValuePair("Name1", "Value1"));
369         Assert.assertEquals("Name1=Value1", URLEncodedUtils.format(params, Consts.ASCII));
370 
371         params.clear();
372         params.add(new BasicNameValuePair("Name2", ""));
373         Assert.assertEquals("Name2=", URLEncodedUtils.format(params, Consts.ASCII));
374 
375         params.clear();
376         params.add(new BasicNameValuePair("Name4", "Value 4&"));
377         Assert.assertEquals("Name4=Value+4%26", URLEncodedUtils.format(params, Consts.ASCII));
378 
379         params.clear();
380         params.add(new BasicNameValuePair("Name4", "Value+4&"));
381         Assert.assertEquals("Name4=Value%2B4%26", URLEncodedUtils.format(params, Consts.ASCII));
382 
383         params.clear();
384         params.add(new BasicNameValuePair("Name4", "Value 4& =4"));
385         Assert.assertEquals("Name4=Value+4%26+%3D4", URLEncodedUtils.format(params, Consts.ASCII));
386 
387         params.clear();
388         params.add(new BasicNameValuePair("Name5", "aaa"));
389         params.add(new BasicNameValuePair("Name6", "bbb"));
390         Assert.assertEquals("Name5=aaa&Name6=bbb", URLEncodedUtils.format(params, Consts.ASCII));
391 
392         params.clear();
393         params.add(new BasicNameValuePair("Name7", "aaa"));
394         params.add(new BasicNameValuePair("Name7", "b,b"));
395         params.add(new BasicNameValuePair("Name7", "ccc"));
396         Assert.assertEquals("Name7=aaa&Name7=b%2Cb&Name7=ccc", URLEncodedUtils.format(params, Consts.ASCII));
397 
398         params.clear();
399         params.add(new BasicNameValuePair("Name8", "xx,  yy  ,zz"));
400         Assert.assertEquals("Name8=xx%2C++yy++%2Czz", URLEncodedUtils.format(params, Consts.ASCII));
401     }
402 
403     private List <NameValuePair> parse (final String params) {
404         return URLEncodedUtils.parse(params, Consts.UTF_8);
405     }
406 
407     private List <NameValuePair> parseString (final String uri) throws Exception {
408         return URLEncodedUtils.parse(new URI("?"+uri), Consts.UTF_8);
409     }
410 
411     private static void assertNameValuePair (
412             final NameValuePair parameter,
413             final String expectedName,
414             final String expectedValue) {
415         Assert.assertEquals(parameter.getName(), expectedName);
416         Assert.assertEquals(parameter.getValue(), expectedValue);
417     }
418 
419 }