blob: 047cda376a0c29018696651cb5624d36fc6737a5 [file] [log] [blame]
/*
* ====================================================================
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation. For more
* information on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*
*/
package org.apache.hc.core5.net;
import java.net.URI;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import org.apache.hc.core5.http.NameValuePair;
import org.apache.hc.core5.http.message.BasicNameValuePair;
import org.hamcrest.CoreMatchers;
import org.junit.Assert;
import org.junit.Test;
public class TestURLEncodedUtils {
@Test
public void testParseURLCodedContent() throws Exception {
List <NameValuePair> result;
result = parse("");
Assert.assertTrue(result.isEmpty());
result = parse("Name0");
Assert.assertEquals(1, result.size());
assertNameValuePair(result.get(0), "Name0", null);
result = parse("Name1=Value1");
Assert.assertEquals(1, result.size());
assertNameValuePair(result.get(0), "Name1", "Value1");
result = parse("Name2=");
Assert.assertEquals(1, result.size());
assertNameValuePair(result.get(0), "Name2", "");
result = parse("Name3");
Assert.assertEquals(1, result.size());
assertNameValuePair(result.get(0), "Name3", null);
result = parse("Name4=Value%204%21");
Assert.assertEquals(1, result.size());
assertNameValuePair(result.get(0), "Name4", "Value 4!");
result = parse("Name4=Value%2B4%21");
Assert.assertEquals(1, result.size());
assertNameValuePair(result.get(0), "Name4", "Value+4!");
result = parse("Name4=Value%204%21%20%214");
Assert.assertEquals(1, result.size());
assertNameValuePair(result.get(0), "Name4", "Value 4! !4");
result = parse("Name5=aaa&Name6=bbb");
Assert.assertEquals(2, result.size());
assertNameValuePair(result.get(0), "Name5", "aaa");
assertNameValuePair(result.get(1), "Name6", "bbb");
result = parse("Name7=aaa&Name7=b%2Cb&Name7=ccc");
Assert.assertEquals(3, result.size());
assertNameValuePair(result.get(0), "Name7", "aaa");
assertNameValuePair(result.get(1), "Name7", "b,b");
assertNameValuePair(result.get(2), "Name7", "ccc");
result = parse("Name8=xx%2C%20%20yy%20%20%2Czz");
Assert.assertEquals(1, result.size());
assertNameValuePair(result.get(0), "Name8", "xx, yy ,zz");
result = parse("price=10%20%E2%82%AC");
Assert.assertEquals(1, result.size());
assertNameValuePair(result.get(0), "price", "10 \u20AC");
}
@Test
public void testParseSegments() throws Exception {
Assert.assertThat(URLEncodedUtils.parsePathSegments("/this/that"),
CoreMatchers.equalTo(Arrays.asList("this", "that")));
Assert.assertThat(URLEncodedUtils.parsePathSegments("this/that"),
CoreMatchers.equalTo(Arrays.asList("this", "that")));
Assert.assertThat(URLEncodedUtils.parsePathSegments("this//that"),
CoreMatchers.equalTo(Arrays.asList("this", "", "that")));
Assert.assertThat(URLEncodedUtils.parsePathSegments("this//that/"),
CoreMatchers.equalTo(Arrays.asList("this", "", "that", "")));
Assert.assertThat(URLEncodedUtils.parsePathSegments("this//that/%2fthis%20and%20that"),
CoreMatchers.equalTo(Arrays.asList("this", "", "that", "/this and that")));
Assert.assertThat(URLEncodedUtils.parsePathSegments("this///that//"),
CoreMatchers.equalTo(Arrays.asList("this", "", "", "that", "", "")));
Assert.assertThat(URLEncodedUtils.parsePathSegments("/"),
CoreMatchers.equalTo(Collections.singletonList("")));
Assert.assertThat(URLEncodedUtils.parsePathSegments(""),
CoreMatchers.equalTo(Collections.<String>emptyList()));
}
@Test
public void testFormatSegments() throws Exception {
Assert.assertThat(URLEncodedUtils.formatSegments("this", "that"),
CoreMatchers.equalTo("/this/that"));
Assert.assertThat(URLEncodedUtils.formatSegments("this", "", "that"),
CoreMatchers.equalTo("/this//that"));
Assert.assertThat(URLEncodedUtils.formatSegments("this", "", "that", "/this and that"),
CoreMatchers.equalTo("/this//that/%2Fthis%20and%20that"));
Assert.assertThat(URLEncodedUtils.formatSegments("this", "", "", "that", "", ""),
CoreMatchers.equalTo("/this///that//"));
Assert.assertThat(URLEncodedUtils.formatSegments(""),
CoreMatchers.equalTo("/"));
Assert.assertThat(URLEncodedUtils.formatSegments(),
CoreMatchers.equalTo(""));
}
@Test
public void testParseURLCodedContentString() throws Exception {
List <NameValuePair> result;
result = parseString("");
Assert.assertTrue(result.isEmpty());
result = parseString("Name0");
Assert.assertEquals(1, result.size());
assertNameValuePair(result.get(0), "Name0", null);
result = parseString("Name1=Value1");
Assert.assertEquals(1, result.size());
assertNameValuePair(result.get(0), "Name1", "Value1");
result = parseString("Name2=");
Assert.assertEquals(1, result.size());
assertNameValuePair(result.get(0), "Name2", "");
result = parseString("Name3");
Assert.assertEquals(1, result.size());
assertNameValuePair(result.get(0), "Name3", null);
result = parseString("Name4=Value%204%21");
Assert.assertEquals(1, result.size());
assertNameValuePair(result.get(0), "Name4", "Value 4!");
result = parseString("Name4=Value%2B4%21");
Assert.assertEquals(1, result.size());
assertNameValuePair(result.get(0), "Name4", "Value+4!");
result = parseString("Name4=Value%204%21%20%214");
Assert.assertEquals(1, result.size());
assertNameValuePair(result.get(0), "Name4", "Value 4! !4");
result = parseString("Name5=aaa&Name6=bbb");
Assert.assertEquals(2, result.size());
assertNameValuePair(result.get(0), "Name5", "aaa");
assertNameValuePair(result.get(1), "Name6", "bbb");
result = parseString("Name7=aaa&Name7=b%2Cb&Name7=ccc");
Assert.assertEquals(3, result.size());
assertNameValuePair(result.get(0), "Name7", "aaa");
assertNameValuePair(result.get(1), "Name7", "b,b");
assertNameValuePair(result.get(2), "Name7", "ccc");
result = parseString("Name8=xx%2C%20%20yy%20%20%2Czz");
Assert.assertEquals(1, result.size());
assertNameValuePair(result.get(0), "Name8", "xx, yy ,zz");
result = parseString("price=10%20%E2%82%AC");
Assert.assertEquals(1, result.size());
assertNameValuePair(result.get(0), "price", "10 \u20AC");
result = parse("a=b\"c&d=e");
Assert.assertEquals(2, result.size());
assertNameValuePair(result.get(0), "a", "b\"c");
assertNameValuePair(result.get(1), "d", "e");
}
@Test
public void testParseInvalidURLCodedContent() throws Exception {
List <NameValuePair> result;
result = parse("name=%");
Assert.assertEquals(1, result.size());
assertNameValuePair(result.get(0), "name", "%");
result = parse("name=%a");
Assert.assertEquals(1, result.size());
assertNameValuePair(result.get(0), "name", "%a");
result = parse("name=%wa%20");
Assert.assertEquals(1, result.size());
assertNameValuePair(result.get(0), "name", "%wa ");
}
private static final int SWISS_GERMAN_HELLO [] = {
0x47, 0x72, 0xFC, 0x65, 0x7A, 0x69, 0x5F, 0x7A, 0xE4, 0x6D, 0xE4
};
private static final int RUSSIAN_HELLO [] = {
0x412, 0x441, 0x435, 0x43C, 0x5F, 0x43F, 0x440, 0x438,
0x432, 0x435, 0x442
};
private static String constructString(final int [] unicodeChars) {
final StringBuilder buffer = new StringBuilder();
if (unicodeChars != null) {
for (final int unicodeChar : unicodeChars) {
buffer.append((char)unicodeChar);
}
}
return buffer.toString();
}
@Test
public void testParseUTF8Ampersand1String() throws Exception {
final String ru_hello = constructString(RUSSIAN_HELLO);
final String ch_hello = constructString(SWISS_GERMAN_HELLO);
final List <NameValuePair> parameters = new ArrayList<>();
parameters.add(new BasicNameValuePair("russian", ru_hello));
parameters.add(new BasicNameValuePair("swiss", ch_hello));
final String s = URLEncodedUtils.format(parameters, StandardCharsets.UTF_8);
final List <NameValuePair> result = URLEncodedUtils.parse(s, StandardCharsets.UTF_8);
Assert.assertEquals(2, result.size());
assertNameValuePair(result.get(0), "russian", ru_hello);
assertNameValuePair(result.get(1), "swiss", ch_hello);
}
@Test
public void testParseUTF8Ampersand2String() throws Exception {
testParseUTF8String('&');
}
@Test
public void testParseUTF8SemicolonString() throws Exception {
testParseUTF8String(';');
}
private void testParseUTF8String(final char parameterSeparator) throws Exception {
final String ru_hello = constructString(RUSSIAN_HELLO);
final String ch_hello = constructString(SWISS_GERMAN_HELLO);
final List <NameValuePair> parameters = new ArrayList<>();
parameters.add(new BasicNameValuePair("russian", ru_hello));
parameters.add(new BasicNameValuePair("swiss", ch_hello));
final String s = URLEncodedUtils.format(parameters, parameterSeparator, StandardCharsets.UTF_8);
final List<NameValuePair> result1 = URLEncodedUtils.parse(s, StandardCharsets.UTF_8);
Assert.assertEquals(2, result1.size());
assertNameValuePair(result1.get(0), "russian", ru_hello);
assertNameValuePair(result1.get(1), "swiss", ch_hello);
final List<NameValuePair> result2 = URLEncodedUtils.parse(s, StandardCharsets.UTF_8, parameterSeparator);
Assert.assertEquals(2, result2.size());
assertNameValuePair(result2.get(0), "russian", ru_hello);
assertNameValuePair(result2.get(1), "swiss", ch_hello);
}
@Test
public void testEmptyQuery() throws Exception {
final List<NameValuePair> result = URLEncodedUtils.parse("", StandardCharsets.UTF_8);
Assert.assertEquals(0, result.size());
// [HTTPCLIENT-1889]:
result.add(new BasicNameValuePair("key", "value"));
}
@Test
public void testFormat() throws Exception {
final List <NameValuePair> params = new ArrayList<>();
Assert.assertEquals(0, URLEncodedUtils.format(params, StandardCharsets.US_ASCII).length());
params.clear();
params.add(new BasicNameValuePair("Name0", null));
Assert.assertEquals("Name0", URLEncodedUtils.format(params, StandardCharsets.US_ASCII));
params.clear();
params.add(new BasicNameValuePair("Name1", "Value1"));
Assert.assertEquals("Name1=Value1", URLEncodedUtils.format(params, StandardCharsets.US_ASCII));
params.clear();
params.add(new BasicNameValuePair("Name2", ""));
Assert.assertEquals("Name2=", URLEncodedUtils.format(params, StandardCharsets.US_ASCII));
params.clear();
params.add(new BasicNameValuePair("Name4", "Value 4&"));
Assert.assertEquals("Name4=Value+4%26", URLEncodedUtils.format(params, StandardCharsets.US_ASCII));
params.clear();
params.add(new BasicNameValuePair("Name4", "Value+4&"));
Assert.assertEquals("Name4=Value%2B4%26", URLEncodedUtils.format(params, StandardCharsets.US_ASCII));
params.clear();
params.add(new BasicNameValuePair("Name4", "Value 4& =4"));
Assert.assertEquals("Name4=Value+4%26+%3D4", URLEncodedUtils.format(params, StandardCharsets.US_ASCII));
params.clear();
params.add(new BasicNameValuePair("Name5", "aaa"));
params.add(new BasicNameValuePair("Name6", "bbb"));
Assert.assertEquals("Name5=aaa&Name6=bbb", URLEncodedUtils.format(params, StandardCharsets.US_ASCII));
params.clear();
params.add(new BasicNameValuePair("Name7", "aaa"));
params.add(new BasicNameValuePair("Name7", "b,b"));
params.add(new BasicNameValuePair("Name7", "ccc"));
Assert.assertEquals("Name7=aaa&Name7=b%2Cb&Name7=ccc", URLEncodedUtils.format(params, StandardCharsets.US_ASCII));
Assert.assertEquals("Name7=aaa&Name7=b%2Cb&Name7=ccc", URLEncodedUtils.format(params, '&', StandardCharsets.US_ASCII));
Assert.assertEquals("Name7=aaa;Name7=b%2Cb;Name7=ccc", URLEncodedUtils.format(params, ';', StandardCharsets.US_ASCII));
params.clear();
params.add(new BasicNameValuePair("Name8", "xx, yy ,zz"));
Assert.assertEquals("Name8=xx%2C++yy++%2Czz", URLEncodedUtils.format(params, StandardCharsets.US_ASCII));
}
@Test
public void testFormatString() throws Exception { // as above, using String
final List <NameValuePair> params = new ArrayList<>();
Assert.assertEquals(0, URLEncodedUtils.format(params, StandardCharsets.US_ASCII).length());
params.clear();
params.add(new BasicNameValuePair("Name0", null));
Assert.assertEquals("Name0", URLEncodedUtils.format(params, StandardCharsets.US_ASCII));
params.clear();
params.add(new BasicNameValuePair("Name1", "Value1"));
Assert.assertEquals("Name1=Value1", URLEncodedUtils.format(params, StandardCharsets.US_ASCII));
params.clear();
params.add(new BasicNameValuePair("Name2", ""));
Assert.assertEquals("Name2=", URLEncodedUtils.format(params, StandardCharsets.US_ASCII));
params.clear();
params.add(new BasicNameValuePair("Name4", "Value 4&"));
Assert.assertEquals("Name4=Value+4%26", URLEncodedUtils.format(params, StandardCharsets.US_ASCII));
params.clear();
params.add(new BasicNameValuePair("Name4", "Value+4&"));
Assert.assertEquals("Name4=Value%2B4%26", URLEncodedUtils.format(params, StandardCharsets.US_ASCII));
params.clear();
params.add(new BasicNameValuePair("Name4", "Value 4& =4"));
Assert.assertEquals("Name4=Value+4%26+%3D4", URLEncodedUtils.format(params, StandardCharsets.US_ASCII));
params.clear();
params.add(new BasicNameValuePair("Name5", "aaa"));
params.add(new BasicNameValuePair("Name6", "bbb"));
Assert.assertEquals("Name5=aaa&Name6=bbb", URLEncodedUtils.format(params, StandardCharsets.US_ASCII));
params.clear();
params.add(new BasicNameValuePair("Name7", "aaa"));
params.add(new BasicNameValuePair("Name7", "b,b"));
params.add(new BasicNameValuePair("Name7", "ccc"));
Assert.assertEquals("Name7=aaa&Name7=b%2Cb&Name7=ccc", URLEncodedUtils.format(params, StandardCharsets.US_ASCII));
params.clear();
params.add(new BasicNameValuePair("Name8", "xx, yy ,zz"));
Assert.assertEquals("Name8=xx%2C++yy++%2Czz", URLEncodedUtils.format(params, StandardCharsets.US_ASCII));
}
private List <NameValuePair> parse (final String params) {
return URLEncodedUtils.parse(params, StandardCharsets.UTF_8);
}
private List <NameValuePair> parseString (final String uri) throws Exception {
return URLEncodedUtils.parse(new URI("?"+uri), StandardCharsets.UTF_8);
}
private static void assertNameValuePair (
final NameValuePair parameter,
final String expectedName,
final String expectedValue) {
Assert.assertEquals(parameter.getName(), expectedName);
Assert.assertEquals(parameter.getValue(), expectedValue);
}
}