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.core5.net;
28  
29  import java.net.InetAddress;
30  import java.net.URI;
31  import java.net.URLEncoder;
32  import java.nio.charset.Charset;
33  import java.nio.charset.StandardCharsets;
34  import java.util.ArrayList;
35  import java.util.Arrays;
36  import java.util.List;
37  
38  import org.apache.hc.core5.http.NameValuePair;
39  import org.apache.hc.core5.http.message.BasicNameValuePair;
40  import org.junit.Assert;
41  import org.junit.Test;
42  
43  public class TestURIBuilder {
44  
45      @Test
46      public void testHierarchicalUri() throws Exception {
47          final URI uri = new URI("http", "stuff", "localhost", 80, "/some stuff", "param=stuff", "fragment");
48          final URIBuilder uribuilder = new URIBuilder(uri);
49          final URI result = uribuilder.build();
50          Assert.assertEquals(new URI("http://stuff@localhost:80/some%20stuff?param=stuff#fragment"), result);
51      }
52  
53      @Test
54      public void testMutationToRelativeUri() throws Exception {
55          final URI uri = new URI("http://stuff@localhost:80/stuff?param=stuff#fragment");
56          final URIBuilder uribuilder = new URIBuilder(uri).setHost((String) null);
57          final URI result = uribuilder.build();
58          Assert.assertEquals(new URI("http:///stuff?param=stuff#fragment"), result);
59      }
60  
61      @Test
62      public void testMutationRemoveFragment() throws Exception {
63          final URI uri = new URI("http://stuff@localhost:80/stuff?param=stuff#fragment");
64          final URI result = new URIBuilder(uri).setFragment(null).build();
65          Assert.assertEquals(new URI("http://stuff@localhost:80/stuff?param=stuff"), result);
66      }
67  
68      @Test
69      public void testMutationRemoveUserInfo() throws Exception {
70          final URI uri = new URI("http://stuff@localhost:80/stuff?param=stuff#fragment");
71          final URI result = new URIBuilder(uri).setUserInfo(null).build();
72          Assert.assertEquals(new URI("http://localhost:80/stuff?param=stuff#fragment"), result);
73      }
74  
75      @Test
76      public void testMutationRemovePort() throws Exception {
77          final URI uri = new URI("http://stuff@localhost:80/stuff?param=stuff#fragment");
78          final URI result = new URIBuilder(uri).setPort(-1).build();
79          Assert.assertEquals(new URI("http://stuff@localhost/stuff?param=stuff#fragment"), result);
80      }
81  
82      @Test
83      public void testOpaqueUri() throws Exception {
84          final URI uri = new URI("stuff", "some-stuff", "fragment");
85          final URIBuilder uribuilder = new URIBuilder(uri);
86          final URI result = uribuilder.build();
87          Assert.assertEquals(uri, result);
88      }
89  
90      @Test
91      public void testOpaqueUriMutation() throws Exception {
92          final URI uri = new URI("stuff", "some-stuff", "fragment");
93          final URIBuilder uribuilder = new URIBuilder(uri).setCustomQuery("param1&param2=stuff").setFragment(null);
94          Assert.assertEquals(new URI("stuff:?param1&param2=stuff"), uribuilder.build());
95      }
96  
97      @Test
98      public void testHierarchicalUriMutation() throws Exception {
99          final URIBuilder uribuilder = new URIBuilder("/").setScheme("http").setHost("localhost").setPort(80).setPath("/stuff");
100         Assert.assertEquals(new URI("http://localhost:80/stuff"), uribuilder.build());
101     }
102 
103     @Test
104    public void testLocalhost() throws Exception {
105        // Check that the URI generated by URI builder agrees with that generated by using URI directly
106        final String scheme="https";
107        final InetAddress host=InetAddress.getLocalHost();
108        final String specials="/abcd!$&*()_-+.,=:;'~@[]?<>|#^%\"{}\\\u00a3`\u00ac\u00a6xyz"; // N.B. excludes space
109        final URI uri = new URI(scheme, specials, host.getHostAddress(), 80, specials, specials, specials);
110 
111        final URI bld = URIBuilder.localhost()
112                .setScheme(scheme)
113                .setUserInfo(specials)
114                .setPath(specials)
115                .setCustomQuery(specials)
116                .setFragment(specials)
117                .build();
118 
119        Assert.assertEquals(uri.getHost(), bld.getHost());
120 
121        Assert.assertEquals(uri.getUserInfo(), bld.getUserInfo());
122 
123        Assert.assertEquals(uri.getPath(), bld.getPath());
124 
125        Assert.assertEquals(uri.getQuery(), bld.getQuery());
126 
127        Assert.assertEquals(uri.getFragment(), bld.getFragment());
128    }
129 
130     @Test
131    public void testLoopbackAddress() throws Exception {
132        // Check that the URI generated by URI builder agrees with that generated by using URI directly
133        final String scheme="https";
134        final InetAddress host=InetAddress.getLoopbackAddress();
135        final String specials="/abcd!$&*()_-+.,=:;'~@[]?<>|#^%\"{}\\\u00a3`\u00ac\u00a6xyz"; // N.B. excludes space
136        final URI uri = new URI(scheme, specials, host.getHostAddress(), 80, specials, specials, specials);
137 
138        final URI bld = URIBuilder.loopbackAddress()
139                .setScheme(scheme)
140                .setUserInfo(specials)
141                .setPath(specials)
142                .setCustomQuery(specials)
143                .setFragment(specials)
144                .build();
145 
146        Assert.assertEquals(uri.getHost(), bld.getHost());
147 
148        Assert.assertEquals(uri.getUserInfo(), bld.getUserInfo());
149 
150        Assert.assertEquals(uri.getPath(), bld.getPath());
151 
152        Assert.assertEquals(uri.getQuery(), bld.getQuery());
153 
154        Assert.assertEquals(uri.getFragment(), bld.getFragment());
155    }
156 
157     @Test
158     public void testEmpty() throws Exception {
159         final URIBuilder uribuilder = new URIBuilder();
160         final URI result = uribuilder.build();
161         Assert.assertEquals(new URI(""), result);
162     }
163 
164     @Test
165     public void testSetUserInfo() throws Exception {
166         final URI uri = new URI("http", null, "localhost", 80, "/", "param=stuff", null);
167         final URIBuilder uribuilder = new URIBuilder(uri).setUserInfo("user", "password");
168         final URI result = uribuilder.build();
169         Assert.assertEquals(new URI("http://user:password@localhost:80/?param=stuff"), result);
170     }
171 
172     @Test
173     public void testRemoveParameters() throws Exception {
174         final URI uri = new URI("http", null, "localhost", 80, "/", "param=stuff", null);
175         final URIBuilder uribuilder = new URIBuilder(uri).removeQuery();
176         final URI result = uribuilder.build();
177         Assert.assertEquals(new URI("http://localhost:80/"), result);
178     }
179 
180     @Test
181     public void testSetParameter() throws Exception {
182         final URI uri = new URI("http", null, "localhost", 80, "/", "param=stuff&blah&blah", null);
183         final URIBuilder uribuilder = new URIBuilder(uri).setParameter("param", "some other stuff")
184             .setParameter("blah", "blah");
185         final URI result = uribuilder.build();
186         Assert.assertEquals(new URI("http://localhost:80/?param=some+other+stuff&blah=blah"), result);
187     }
188 
189     @Test
190     public void testSetParametersWithEmptyArg() throws Exception {
191         final URI uri = new URI("http", null, "localhost", 80, "/test", "param=test", null);
192         final URIBuilder uribuilder = new URIBuilder(uri).setParameters();
193         final URI result = uribuilder.build();
194         Assert.assertEquals(new URI("http://localhost:80/test"), result);
195     }
196 
197     @Test
198     public void testSetParametersWithEmptyList() throws Exception {
199         final URI uri = new URI("http", null, "localhost", 80, "/test", "param=test", null);
200         final URIBuilder uribuilder = new URIBuilder(uri).setParameters(Arrays.<NameValuePair>asList());
201         final URI result = uribuilder.build();
202         Assert.assertEquals(new URI("http://localhost:80/test"), result);
203     }
204 
205     @Test
206     public void testParameterWithSpecialChar() throws Exception {
207         final URI uri = new URI("http", null, "localhost", 80, "/", "param=stuff", null);
208         final URIBuilder uribuilder = new URIBuilder(uri).addParameter("param", "1 + 1 = 2")
209             .addParameter("param", "blah&blah");
210         final URI result = uribuilder.build();
211         Assert.assertEquals(new URI("http://localhost:80/?param=stuff&param=1+%2B+1+%3D+2&" +
212                 "param=blah%26blah"), result);
213     }
214 
215     @Test
216     public void testAddParameter() throws Exception {
217         final URI uri = new URI("http", null, "localhost", 80, "/", "param=stuff&blah&blah", null);
218         final URIBuilder uribuilder = new URIBuilder(uri).addParameter("param", "some other stuff")
219             .addParameter("blah", "blah");
220         final URI result = uribuilder.build();
221         Assert.assertEquals(new URI("http://localhost:80/?param=stuff&blah&blah&" +
222                 "param=some+other+stuff&blah=blah"), result);
223     }
224 
225     @Test
226     public void testQueryEncoding() throws Exception {
227         final URI uri1 = new URI("https://somehost.com/stuff?client_id=1234567890" +
228                 "&redirect_uri=https%3A%2F%2Fsomehost.com%2Fblah+blah%2F");
229         final URI uri2 = new URIBuilder("https://somehost.com/stuff")
230             .addParameter("client_id","1234567890")
231             .addParameter("redirect_uri","https://somehost.com/blah blah/").build();
232         Assert.assertEquals(uri1, uri2);
233     }
234 
235     @Test
236     public void testQueryAndParameterEncoding() throws Exception {
237         final URI uri1 = new URI("https://somehost.com/stuff?param1=12345&param2=67890");
238         final URI uri2 = new URIBuilder("https://somehost.com/stuff")
239             .setCustomQuery("this&that")
240             .addParameter("param1","12345")
241             .addParameter("param2","67890").build();
242         Assert.assertEquals(uri1, uri2);
243     }
244 
245     @Test
246     public void testPathEncoding() throws Exception {
247         final URI uri1 = new URI("https://somehost.com/some%20path%20with%20blanks/");
248         final URI uri2 = new URIBuilder()
249             .setScheme("https")
250             .setHost("somehost.com")
251             .setPath("/some path with blanks/")
252             .build();
253         Assert.assertEquals(uri1, uri2);
254     }
255 
256     @Test
257     public void testAgainstURI() throws Exception {
258         // Check that the URI generated by URI builder agrees with that generated by using URI directly
259         final String scheme="https";
260         final String host="localhost";
261         final String specials="/abcd!$&*()_-+.,=:;'~@[]?<>|#^%\"{}\\\u00a3`\u00ac\u00a6xyz"; // N.B. excludes space
262         final URI uri = new URI(scheme, specials, host, 80, specials, specials, specials);
263 
264         final URI bld = new URIBuilder()
265                 .setScheme(scheme)
266                 .setHost(host)
267                 .setUserInfo(specials)
268                 .setPath(specials)
269                 .setCustomQuery(specials)
270                 .setFragment(specials)
271                 .build();
272 
273         Assert.assertEquals(uri.getHost(), bld.getHost());
274 
275         Assert.assertEquals(uri.getUserInfo(), bld.getUserInfo());
276 
277         Assert.assertEquals(uri.getPath(), bld.getPath());
278 
279         Assert.assertEquals(uri.getQuery(), bld.getQuery());
280 
281         Assert.assertEquals(uri.getFragment(), bld.getFragment());
282 
283     }
284 
285     @Test
286     public void testAgainstURIEncoded() throws Exception {
287         // Check that the encoded URI generated by URI builder agrees with that generated by using URI directly
288         final String scheme="https";
289         final String host="localhost";
290         final String specials="/ abcd!$&*()_-+.,=:;'~<>/@[]|#^%\"{}\\`xyz"; // N.B. excludes \u00a3\u00ac\u00a6
291         final URI uri = new URI(scheme, specials, host, 80, specials, specials, specials);
292 
293         final URI bld = new URIBuilder()
294                 .setScheme(scheme)
295                 .setHost(host)
296                 .setUserInfo(specials)
297                 .setPath(specials)
298                 .setCustomQuery(specials)
299                 .setFragment(specials)
300                 .build();
301 
302         Assert.assertEquals(uri.getHost(), bld.getHost());
303 
304         Assert.assertEquals(uri.getRawUserInfo(), bld.getRawUserInfo());
305 
306         Assert.assertEquals(uri.getRawPath(), bld.getRawPath());
307 
308         Assert.assertEquals(uri.getRawQuery(), bld.getRawQuery());
309 
310         Assert.assertEquals(uri.getRawFragment(), bld.getRawFragment());
311 
312     }
313 
314     @Test
315     public void testBuildAddParametersUTF8() throws Exception {
316         assertAddParameters(StandardCharsets.UTF_8);
317     }
318 
319     @Test
320     public void testBuildAddParametersISO88591() throws Exception {
321         assertAddParameters(StandardCharsets.ISO_8859_1);
322     }
323 
324     public void assertAddParameters(final Charset charset) throws Exception {
325         final URI uri = new URIBuilder("https://somehost.com/stuff")
326                 .setCharset(charset)
327                 .addParameters(createParameters()).build();
328 
329         assertBuild(charset, uri);
330     }
331 
332     @Test
333     public void testBuildSetParametersUTF8() throws Exception {
334         assertSetParameters(StandardCharsets.UTF_8);
335     }
336 
337     @Test
338     public void testBuildSetParametersISO88591() throws Exception {
339         assertSetParameters(StandardCharsets.ISO_8859_1);
340     }
341 
342     public void assertSetParameters(final Charset charset) throws Exception {
343         final URI uri = new URIBuilder("https://somehost.com/stuff")
344                 .setCharset(charset)
345                 .setParameters(createParameters()).build();
346 
347         assertBuild(charset, uri);
348     }
349 
350     public void assertBuild(final Charset charset, final URI uri) throws Exception {
351         final String encodedData1 = URLEncoder.encode("\"1\u00aa position\"", charset.displayName());
352         final String encodedData2 = URLEncoder.encode("Jos\u00e9 Abra\u00e3o", charset.displayName());
353 
354         final String uriExpected = String.format("https://somehost.com/stuff?parameter1=value1&parameter2=%s&parameter3=%s", encodedData1, encodedData2);
355 
356         Assert.assertEquals(uriExpected, uri.toString());
357     }
358 
359     private List<NameValuePair> createParameters() {
360         final List<NameValuePair> parameters = new ArrayList<>();
361         parameters.add(new BasicNameValuePair("parameter1", "value1"));
362         parameters.add(new BasicNameValuePair("parameter2", "\"1\u00aa position\""));
363         parameters.add(new BasicNameValuePair("parameter3", "Jos\u00e9 Abra\u00e3o"));
364         return parameters;
365     }
366 
367     @Test
368     public void testMalformedPath() throws Exception {
369         final String path = "@notexample.com/mypath";
370         final URI uri = new URIBuilder(path).setHost("example.com").build();
371         Assert.assertEquals("example.com", uri.getHost());
372     }
373 
374     @Test
375     public void testRelativePath() throws Exception {
376         final URI uri = new URIBuilder("./mypath").build();
377         Assert.assertEquals(new URI("./mypath"), uri);
378     }
379 
380     @Test
381     public void testRelativePathWithAuthority() throws Exception {
382         final URI uri = new URIBuilder("./mypath").setHost("somehost").setScheme("http").build();
383         Assert.assertEquals(new URI("http://somehost/./mypath"), uri);
384     }
385 
386 }