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.utils;
28  
29  import java.net.URI;
30  import java.util.Arrays;
31  import java.util.Collections;
32  
33  import org.apache.hc.core5.http.HttpHost;
34  import org.apache.hc.core5.net.URIBuilder;
35  import org.junit.jupiter.api.Assertions;
36  import org.junit.jupiter.api.Test;
37  
38  /**
39   * This TestCase contains test methods for URI resolving according to RFC 3986.
40   * The examples are listed in section "5.4 Reference Resolution Examples"
41   */
42  public class TestURIUtils {
43  
44      private final URI baseURI = URI.create("http://a/b/c/d;p?q");
45  
46      @Test
47      public void testNormalization() {
48          Assertions.assertEquals("example://a/b/c/%7Bfoo%7D", URIUtils.resolve(this.baseURI, "eXAMPLE://a/./b/../b/%63/%7bfoo%7d").toString());
49          Assertions.assertEquals("http://www.example.com/%3C", URIUtils.resolve(this.baseURI, "http://www.example.com/%3c").toString());
50          Assertions.assertEquals("http://www.example.com/", URIUtils.resolve(this.baseURI, "HTTP://www.EXAMPLE.com/").toString());
51          Assertions.assertEquals("http://www.example.com/a%2F", URIUtils.resolve(this.baseURI, "http://www.example.com/a%2f").toString());
52          Assertions.assertEquals("http://www.example.com/?q=%26", URIUtils.resolve(this.baseURI, "http://www.example.com/?q=%26").toString());
53          Assertions.assertEquals("http://www.example.com/%23?q=%26", URIUtils.resolve(this.baseURI, "http://www.example.com/%23?q=%26").toString());
54          Assertions.assertEquals("http://www.example.com/blah-%28%20-blah-%20%26%20-blah-%20%29-blah/",
55                  URIUtils.resolve(this.baseURI, "http://www.example.com/blah-%28%20-blah-%20&%20-blah-%20)-blah/").toString());
56      }
57  
58      @Test
59      public void testResolve() {
60          Assertions.assertEquals("g:h", URIUtils.resolve(this.baseURI, "g:h").toString());
61          Assertions.assertEquals("http://a/b/c/g", URIUtils.resolve(this.baseURI, "g").toString());
62          Assertions.assertEquals("http://a/b/c/g", URIUtils.resolve(this.baseURI, "./g").toString());
63          Assertions.assertEquals("http://a/b/c/g/", URIUtils.resolve(this.baseURI, "g/").toString());
64          Assertions.assertEquals("http://a/g", URIUtils.resolve(this.baseURI, "/g").toString());
65          Assertions.assertEquals("http://g/", URIUtils.resolve(this.baseURI, "//g").toString());
66          Assertions.assertEquals("http://a/b/c/d;p?y", URIUtils.resolve(this.baseURI, "?y").toString());
67          Assertions.assertEquals("http://a/b/c/d;p?y#f", URIUtils.resolve(this.baseURI, "?y#f")
68                  .toString());
69          Assertions.assertEquals("http://a/b/c/g?y", URIUtils.resolve(this.baseURI, "g?y").toString());
70          Assertions.assertEquals("http://a/b/c/d%3Bp?q#s", URIUtils.resolve(this.baseURI, "#s")
71                  .toString());
72          Assertions.assertEquals("http://a/b/c/g#s", URIUtils.resolve(this.baseURI, "g#s").toString());
73          Assertions.assertEquals("http://a/b/c/g?y#s", URIUtils.resolve(this.baseURI, "g?y#s")
74                  .toString());
75          Assertions.assertEquals("http://a/b/c/%3Bx", URIUtils.resolve(this.baseURI, ";x").toString());
76          Assertions.assertEquals("http://a/b/c/g%3Bx", URIUtils.resolve(this.baseURI, "g;x").toString());
77          Assertions.assertEquals("http://a/b/c/g%3Bx?y#s", URIUtils.resolve(this.baseURI, "g;x?y#s")
78                  .toString());
79          Assertions.assertEquals("http://a/b/c/d%3Bp?q", URIUtils.resolve(this.baseURI, "").toString());
80          Assertions.assertEquals("http://a/b/c/", URIUtils.resolve(this.baseURI, ".").toString());
81          Assertions.assertEquals("http://a/b/c/", URIUtils.resolve(this.baseURI, "./").toString());
82          Assertions.assertEquals("http://a/b/", URIUtils.resolve(this.baseURI, "..").toString());
83          Assertions.assertEquals("http://a/b/", URIUtils.resolve(this.baseURI, "../").toString());
84          Assertions.assertEquals("http://a/b/g", URIUtils.resolve(this.baseURI, "../g").toString());
85          Assertions.assertEquals("http://a/", URIUtils.resolve(this.baseURI, "../..").toString());
86          Assertions.assertEquals("http://a/", URIUtils.resolve(this.baseURI, "../../").toString());
87          Assertions.assertEquals("http://a/g", URIUtils.resolve(this.baseURI, "../../g").toString());
88          Assertions.assertEquals("http://a/g", URIUtils.resolve(this.baseURI, "../../../g").toString());
89          Assertions.assertEquals("http://a/g", URIUtils.resolve(this.baseURI, "../../../../g")
90                  .toString());
91          Assertions.assertEquals("http://a/g", URIUtils.resolve(this.baseURI, "/./g").toString());
92          Assertions.assertEquals("http://a/g", URIUtils.resolve(this.baseURI, "/../g").toString());
93          Assertions.assertEquals("http://a/b/c/g.", URIUtils.resolve(this.baseURI, "g.").toString());
94          Assertions.assertEquals("http://a/b/c/.g", URIUtils.resolve(this.baseURI, ".g").toString());
95          Assertions.assertEquals("http://a/b/c/g..", URIUtils.resolve(this.baseURI, "g..").toString());
96          Assertions.assertEquals("http://a/b/c/..g", URIUtils.resolve(this.baseURI, "..g").toString());
97          Assertions.assertEquals("http://a/b/g", URIUtils.resolve(this.baseURI, "./../g").toString());
98          Assertions.assertEquals("http://a/b/c/g/", URIUtils.resolve(this.baseURI, "./g/.").toString());
99          Assertions.assertEquals("http://a/b/c/g/h", URIUtils.resolve(this.baseURI, "g/./h").toString());
100         Assertions.assertEquals("http://a/b/c/h", URIUtils.resolve(this.baseURI, "g/../h").toString());
101         Assertions.assertEquals("http://a/b/c/g%3Bx%3D1/y", URIUtils.resolve(this.baseURI, "g;x=1/./y")
102                 .toString());
103         Assertions.assertEquals("http://a/b/c/y", URIUtils.resolve(this.baseURI, "g;x=1/../y")
104                 .toString());
105         Assertions.assertEquals("http://a/b/c/g?y%2F.%2Fx", URIUtils.resolve(this.baseURI, "g?y/./x")
106                 .toString());
107         Assertions.assertEquals("http://a/b/c/g?y%2F..%2Fx", URIUtils.resolve(this.baseURI, "g?y/../x")
108                 .toString());
109         Assertions.assertEquals("http://a/b/c/g#s%2F.%2Fx", URIUtils.resolve(this.baseURI, "g#s/./x")
110                 .toString());
111         Assertions.assertEquals("http://a/b/c/g#s%2F..%2Fx", URIUtils.resolve(this.baseURI, "g#s/../x")
112                 .toString());
113         Assertions.assertEquals("http:g", URIUtils.resolve(this.baseURI, "http:g").toString());
114         // examples from section 5.2.4
115         Assertions.assertEquals("http://s/a/g", URIUtils.resolve(this.baseURI,
116                 "http://s/a/b/c/./../../g").toString());
117         Assertions.assertEquals("http://s/mid/6", URIUtils.resolve(this.baseURI,
118                 "http://s/mid/content=5/../6").toString());
119     }
120 
121     @Test
122     public void testResolveOpaque() {
123         Assertions.assertEquals("example://a/b/c/%7Bfoo%7D", URIUtils.resolve(this.baseURI, "eXAMPLE://a/./b/../b/%63/%7bfoo%7d").toString());
124         Assertions.assertEquals("file://localhost/etc/fstab", URIUtils.resolve(this.baseURI, "file://localhost/etc/fstab").toString());
125         Assertions.assertEquals("file:///etc/fstab", URIUtils.resolve(this.baseURI, "file:///etc/fstab").toString());
126         Assertions.assertEquals("file://localhost/c%3A/WINDOWS/clock.avi", URIUtils.resolve(this.baseURI, "file://localhost/c:/WINDOWS/clock.avi").toString());
127         Assertions.assertEquals("file:///c:/WINDOWS/clock.avi", URIUtils.resolve(this.baseURI, "file:///c:/WINDOWS/clock.avi").toString());
128         Assertions.assertEquals("file://hostname/path/to/the%20file.txt", URIUtils.resolve(this.baseURI, "file://hostname/path/to/the%20file.txt").toString());
129         Assertions.assertEquals("file:///c:/path/to/the%20file.txt", URIUtils.resolve(this.baseURI, "file:///c:/path/to/the%20file.txt").toString());
130         Assertions.assertEquals("urn:issn:1535-3613", URIUtils.resolve(this.baseURI, "urn:issn:1535-3613").toString());
131         Assertions.assertEquals("mailto:user@example.com", URIUtils.resolve(this.baseURI, "mailto:user@example.com").toString());
132         Assertions.assertEquals("ftp://example.org/resource.txt", URIUtils.resolve(this.baseURI, "ftp://example.org/resource.txt").toString());
133     }
134 
135     @Test
136     public void testExtractHost() throws Exception {
137         Assertions.assertEquals(new HttpHost("localhost"),
138                 URIUtils.extractHost(new URI("http://localhost/abcd")));
139         Assertions.assertEquals(new HttpHost("localhost"),
140                 URIUtils.extractHost(new URI("http://localhost/abcd%3A")));
141 
142         Assertions.assertEquals(new HttpHost("local_host"),
143                 URIUtils.extractHost(new URI("http://local_host/abcd")));
144         Assertions.assertEquals(new HttpHost("local_host"),
145                 URIUtils.extractHost(new URI("http://local_host/abcd%3A")));
146 
147         Assertions.assertEquals(new HttpHost("localhost",8),
148                 URIUtils.extractHost(new URI("http://localhost:8/abcd")));
149         Assertions.assertEquals(new HttpHost("local_host",8),
150                 URIUtils.extractHost(new URI("http://local_host:8/abcd")));
151 
152         // URI seems to OK with missing port number
153         Assertions.assertEquals(new HttpHost("localhost",-1),URIUtils.extractHost(
154                 new URI("http://localhost:/abcd")));
155         Assertions.assertEquals(new HttpHost("local_host",-1),URIUtils.extractHost(
156                 new URI("http://local_host:/abcd")));
157 
158         Assertions.assertEquals(new HttpHost("localhost",8080),
159                 URIUtils.extractHost(new URI("http://user:pass@localhost:8080/abcd")));
160         Assertions.assertEquals(new HttpHost("local_host",8080),
161                 URIUtils.extractHost(new URI("http://user:pass@local_host:8080/abcd")));
162 
163         Assertions.assertEquals(new HttpHost("localhost",8080),URIUtils.extractHost(
164                 new URI("http://@localhost:8080/abcd")));
165         Assertions.assertEquals(new HttpHost("local_host",8080),URIUtils.extractHost(
166                 new URI("http://@local_host:8080/abcd")));
167 
168         Assertions.assertEquals(new HttpHost("2a00:1450:400c:c01::69",8080),
169                 URIUtils.extractHost(new URI("http://[2a00:1450:400c:c01::69]:8080/")));
170 
171         Assertions.assertEquals(new HttpHost("localhost",8080),
172                 URIUtils.extractHost(new URI("http://localhost:8080/;sessionid=stuff/abcd")));
173         Assertions.assertNull(URIUtils.extractHost(new URI("http://localhost:8080;sessionid=stuff/abcd")));
174         Assertions.assertNull(URIUtils.extractHost(new URI("http://localhost:;sessionid=stuff/abcd")));
175         Assertions.assertNull(URIUtils.extractHost(new URI("http://:80/robots.txt")));
176         Assertions.assertNull(URIUtils.extractHost(new URI("http://some%20domain:80/robots.txt")));
177     }
178 
179     @Test
180     public void testHttpLocationWithRelativeFragment() throws Exception {
181         final HttpHost target = new HttpHost("http", "localhost", -1);
182         final URI requestURI = new URI("/stuff#blahblah");
183 
184         final URI location = URIUtils.resolve(requestURI, target, null);
185         final URI expectedURI = new URIBuilder(requestURI)
186                 .setHost(target.getHostName())
187                 .setScheme(target.getSchemeName())
188                 .build();
189         Assertions.assertEquals(expectedURI, location);
190     }
191 
192     @Test
193     public void testHttpLocationWithAbsoluteFragment() throws Exception {
194         final HttpHost target = new HttpHost("http", "localhost", 80);
195 
196         final URI requestURI = new URIBuilder()
197             .setHost(target.getHostName())
198             .setScheme(target.getSchemeName())
199             .setPath("/stuff")
200             .setFragment("blahblah")
201             .build();
202 
203         final URI location = URIUtils.resolve(requestURI, target, null);
204         final URI expectedURI = requestURI;
205         Assertions.assertEquals(expectedURI, location);
206     }
207 
208     @Test
209     public void testHttpLocationRedirect() throws Exception {
210         final HttpHost target = new HttpHost("http", "localhost", -1);
211         final URI requestURI = new URI("/People.htm#tim");
212 
213         final URI redirect = new URI("http://localhost/people.html");
214 
215         final URI location = URIUtils.resolve(requestURI, target, Collections.singletonList(redirect));
216         final URI expectedURI = new URIBuilder()
217                 .setHost(target.getHostName())
218                 .setScheme(target.getSchemeName())
219                 .setPath("/people.html")
220                 .setFragment("tim")
221                 .build();
222         Assertions.assertEquals(expectedURI, location);
223     }
224 
225     @Test
226     public void testHttpLocationWithRedirectFragment() throws Exception {
227         final HttpHost target = new HttpHost("http", "localhost", -1);
228         final URI requestURI = new URI("/~tim");
229 
230         final URI redirect1 = new URI("http://localhost/People.htm#tim");
231         final URI redirect2 = new URI("http://localhost/people.html");
232 
233         final URI location = URIUtils.resolve(requestURI, target, Arrays.asList(redirect1, redirect2));
234         final URI expectedURI = new URIBuilder()
235                 .setHost(target.getHostName())
236                 .setScheme(target.getSchemeName())
237                 .setPath("/people.html")
238                 .setFragment("tim")
239                 .build();
240         Assertions.assertEquals(expectedURI, location);
241     }
242 
243 }