View Javadoc
1   /*
2    * Copyright (c) 2002-2025 Gargoyle Software Inc.
3    *
4    * Licensed under the Apache License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    * https://www.apache.org/licenses/LICENSE-2.0
8    *
9    * Unless required by applicable law or agreed to in writing, software
10   * distributed under the License is distributed on an "AS IS" BASIS,
11   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12   * See the License for the specific language governing permissions and
13   * limitations under the License.
14   */
15  package org.htmlunit;
16  
17  import static org.htmlunit.WebTestCase.URL_FIRST;
18  import static org.junit.Assert.assertEquals;
19  import static org.junit.Assert.assertNotNull;
20  
21  import java.net.URL;
22  import java.nio.charset.StandardCharsets;
23  
24  import org.apache.commons.lang3.SerializationUtils;
25  import org.apache.http.auth.BasicUserPrincipal;
26  import org.apache.http.auth.Credentials;
27  import org.junit.Test;
28  
29  /**
30   * Tests for {@link WebRequest}.
31   *
32   * @author Ahmed Ashour
33   * @author Marc Guillemot
34   * @author Rodney Gitzel
35   * @author Ronald Brill
36   * @author Joerg Werner
37   * @author Michael Lueck
38   * @author Kristof Neirynck
39   */
40  public class WebRequestTest {
41  
42      /**
43       * @throws Exception if the test fails
44       */
45      @Test
46      public void headers() throws Exception {
47          final WebRequest request = new WebRequest(URL_FIRST);
48          final int initialSize = request.getAdditionalHeaders().size();
49          request.setAdditionalHeader("Accept", "nothing");
50          assertEquals(initialSize, request.getAdditionalHeaders().size());
51          request.setAdditionalHeader("ACCEPT", "compares");
52          assertEquals(initialSize, request.getAdditionalHeaders().size());
53          request.removeAdditionalHeader("ACcEpT");
54          assertEquals(initialSize - 1, request.getAdditionalHeaders().size());
55      }
56  
57      /**
58       * Tests for Bug #901.
59       *
60       * @throws Exception if the test fails
61       */
62      @Test
63      public void setUrl_eliminateDirUp() throws Exception {
64          final URL url1 = new URL("http://htmlunit.sf.net/foo.html");
65          final URL url2 = new URL("http://htmlunit.sf.net/dir/foo.html");
66          final URL url3 = new URL("http://htmlunit.sf.net/dir/foo.html?a=1&b=2");
67  
68          // with directory/..
69          WebRequest request = new WebRequest(new URL("http://htmlunit.sf.net/bla/../foo.html"));
70          assertEquals(url1, request.getUrl());
71  
72          // with /..
73          request = new WebRequest(new URL("http://htmlunit.sf.net/../foo.html"));
74          assertEquals(url1, request.getUrl());
75  
76          // with /(\w\w)/.. (c.f. 2854634)
77          request = new WebRequest(new URL("http://htmlunit.sf.net/dir/fu/../foo.html"));
78          assertEquals(url2, request.getUrl());
79  
80          // with /../..
81          request = new WebRequest(new URL("http://htmlunit.sf.net/../../foo.html"));
82          assertEquals(url1, request.getUrl());
83  
84          // with ../.. (c.f. 2854634)
85          request = new WebRequest(new URL("http://htmlunit.sf.net/dir/foo/bar/../../foo.html"));
86          assertEquals(url2, request.getUrl());
87  
88          request = new WebRequest(
89                            new URL("http://htmlunit.sf.net/dir/foo/bar/boo/hoo/silly/../../../../../foo.html"));
90          assertEquals(url2, request.getUrl());
91  
92          // with /.
93          request = new WebRequest(new URL("http://htmlunit.sf.net/./foo.html"));
94          assertEquals(url1, request.getUrl());
95  
96          // with /\w//. (c.f. 2854634)
97          request = new WebRequest(new URL("http://htmlunit.sf.net/a/./foo.html"));
98          assertEquals(new URL("http://htmlunit.sf.net/a/foo.html"), request.getUrl());
99  
100         // with /.
101         request = new WebRequest(new URL("http://htmlunit.sf.net/dir/./foo.html"));
102         assertEquals(url2, request.getUrl());
103 
104         // with /. and query
105         request = new WebRequest(new URL("http://htmlunit.sf.net/dir/./foo.html?a=1&b=2"));
106         assertEquals(url3, request.getUrl());
107 
108         // pathological
109         request = new WebRequest(
110                 new URL("http://htmlunit.sf.net/dir/foo/bar/./boo/hoo/silly/.././../../../.././foo.html?a=1&b=2"));
111         assertEquals(url3, request.getUrl());
112     }
113 
114     /**
115      * @throws Exception if the test fails
116      */
117     @Test
118     public void setUrl_removePort() throws Exception {
119         final URL url1 = new URL("http://htmlunit.sf.net/foo.html");
120         final URL url2 = new URL("https://htmlunit.sf.net/foo.html");
121 
122         WebRequest request = new WebRequest(new URL("http://htmlunit.sf.net:80/foo.html"));
123         assertEquals(url1, request.getUrl());
124 
125         request = new WebRequest(new URL("https://htmlunit.sf.net:443/foo.html"));
126         assertEquals(url2, request.getUrl());
127     }
128 
129     /**
130      * @throws Exception if the test fails
131      */
132     @Test
133     public void setUrl_preservePort() throws Exception {
134         final URL url1 = new URL("http://htmlunit.sf.net:8080/foo.html");
135         final URL url2 = new URL("https://htmlunit.sf.net:8443/foo.html");
136 
137         WebRequest request = new WebRequest(new URL("http://htmlunit.sf.net:8080/foo.html"));
138         assertEquals(url1, request.getUrl());
139 
140         request = new WebRequest(new URL("https://htmlunit.sf.net:8443/foo.html"));
141         assertEquals(url2, request.getUrl());
142     }
143 
144     /**
145      * @throws Exception if the test fails
146      */
147     @Test
148     public void credentials() throws Exception {
149         final URL url = new URL("http://john.smith:secret@localhost/");
150         final WebRequest request = new WebRequest(url);
151         final Credentials credentials = request.getUrlCredentials();
152         assertEquals(new BasicUserPrincipal("john.smith"), credentials.getUserPrincipal());
153         assertEquals("secret", credentials.getPassword());
154     }
155 
156     /**
157      * @throws Exception if the test fails
158      */
159     @Test
160     public void credentialsAndEmptyPath() throws Exception {
161         final URL url = new URL("http://john.smith:secret@localhost");
162         final WebRequest request = new WebRequest(url);
163         final Credentials credentials = request.getUrlCredentials();
164         assertNotNull("Credentials object is null", credentials);
165         assertEquals(new BasicUserPrincipal("john.smith"), credentials.getUserPrincipal());
166         assertEquals("secret", credentials.getPassword());
167     }
168 
169     /**
170      * @throws Exception if the test fails
171      */
172     @Test
173     public void credentialsAndPathWithDots() throws Exception {
174         final URL url = new URL("http://john.smith:secret@localhost/../foo.html");
175         final WebRequest request = new WebRequest(url);
176         final Credentials credentials = request.getUrlCredentials();
177         assertNotNull("Credentials object is null", credentials);
178         assertEquals(new BasicUserPrincipal("john.smith"), credentials.getUserPrincipal());
179         assertEquals("secret", credentials.getPassword());
180     }
181 
182     /**
183      * @throws Exception if the test fails
184      */
185     @Test
186     public void credentialsAndInternationalizedDomainName() throws Exception {
187         final URL url = new URL("http://john.smith:secret@löcälhöst/");
188         final WebRequest request = new WebRequest(url);
189         final Credentials credentials = request.getUrlCredentials();
190         assertNotNull("Credentials object is null", credentials);
191         assertEquals(new BasicUserPrincipal("john.smith"), credentials.getUserPrincipal());
192         assertEquals("secret", credentials.getPassword());
193     }
194 
195     /**
196      * @throws Exception if the test fails
197      */
198     @Test
199     public void credentialsOnlyUsernameInURL() throws Exception {
200         final URL url = new URL("http://john.smith@localhost/");
201         final WebRequest request = new WebRequest(url);
202         final Credentials credentials = request.getUrlCredentials();
203         assertEquals(new BasicUserPrincipal("john.smith"), credentials.getUserPrincipal());
204         assertEquals("", credentials.getPassword());
205     }
206 
207     /**
208      * @throws Exception if the test fails
209      */
210     @Test
211     public void credentialsOnlyPasswordInURL() throws Exception {
212         final URL url = new URL("http://:secret@localhost/");
213         final WebRequest request = new WebRequest(url);
214         final Credentials credentials = request.getUrlCredentials();
215         assertEquals(new BasicUserPrincipal(""), credentials.getUserPrincipal());
216         assertEquals("secret", credentials.getPassword());
217     }
218 
219     /**
220      * @throws Exception if the test fails
221      */
222     @Test
223     public void credentialsEmptyURL() throws Exception {
224         final URL url = new URL("http://:@localhost/");
225         final WebRequest request = new WebRequest(url);
226         final Credentials credentials = request.getUrlCredentials();
227         assertEquals(new BasicUserPrincipal(""), credentials.getUserPrincipal());
228         assertEquals("", credentials.getPassword());
229     }
230 
231     /**
232      * @throws Exception if the test fails
233      */
234     @Test
235     public void accept_encoding() throws Exception {
236         final URL url = new URL("http://localhost/");
237         final WebRequest request = new WebRequest(url);
238         assertEquals("gzip, deflate", request.getAdditionalHeaders().get(HttpHeader.ACCEPT_ENCODING));
239     }
240 
241     /**
242      * @throws Exception if the test fails
243      */
244     @Test
245     public void idn() throws Exception {
246         final String internationalized = "\u0645\u0635\u0631";
247         final URL url = new URL("http://" + internationalized + ".com/" + internationalized);
248         final WebRequest request = new WebRequest(url);
249         final URL expected = new URL("http://xn--wgbh1c.com/" + internationalized);
250         assertEquals(expected, request.getUrl());
251     }
252 
253     /**
254      * @throws Exception if the test fails
255      */
256     @Test
257     public void hiddenFileInWindows() throws Exception {
258         final URL url = new URL("file://c:/testing/.hidden/folder");
259         final WebRequest request = new WebRequest(url);
260         assertEquals(url.toExternalForm(), request.getUrl().toExternalForm());
261     }
262 
263     /**
264      * @throws Exception if the test fails
265      */
266     @Test
267     public void hiddenFileInWindows2() throws Exception {
268         final URL url = new URL("file:/c:/testing/.hidden/folder");
269         final WebRequest request = new WebRequest(url);
270         assertEquals(url.toExternalForm(), request.getUrl().toExternalForm());
271     }
272 
273     /**
274      * @throws Exception if the test fails
275      */
276     @Test
277     public void getRequestParametersNone() throws Exception {
278         final URL url = new URL("http://localhost/test");
279         final WebRequest request = new WebRequest(url);
280         assertEquals(0, request.getRequestParameters().size());
281     }
282 
283     /**
284      * @throws Exception if the test fails
285      */
286     @Test
287     public void getRequestParametersFromUrlGet() throws Exception {
288         final URL url = new URL("http://localhost/test?x=u");
289         final WebRequest request = new WebRequest(url);
290 
291         // parameters are not parsed from the url
292         assertEquals(0, request.getRequestParameters().size());
293     }
294 
295     /**
296      * @throws Exception if the test fails
297      */
298     @Test
299     public void getRequestParametersFromUrlKeyOnlyGet() throws Exception {
300         final URL url = new URL("http://localhost/test?x=");
301         final WebRequest request = new WebRequest(url);
302 
303         // parameters are not parsed from the url
304         assertEquals(0, request.getRequestParameters().size());
305     }
306 
307     /**
308      * @throws Exception if the test fails
309      */
310     @Test
311     public void getRequestParametersFromUrlPost() throws Exception {
312         final URL url = new URL("http://localhost/test?x=u");
313         final WebRequest request = new WebRequest(url);
314         request.setHttpMethod(HttpMethod.POST);
315 
316         assertEquals(0, request.getRequestParameters().size());
317     }
318 
319     /**
320      * @throws Exception if the test fails
321      */
322     @Test
323     public void getRequestParametersFromUrlEncodedBodyPost() throws Exception {
324         final URL url = new URL("http://localhost/test");
325         final WebRequest request = new WebRequest(url);
326         request.setHttpMethod(HttpMethod.POST);
327         request.setEncodingType(FormEncodingType.URL_ENCODED);
328         request.setRequestBody("x=u");
329 
330         assertEquals(0, request.getRequestParameters().size());
331     }
332 
333     /**
334      * @throws Exception if an error occurs
335      */
336     @Test
337     public void serialization() throws Exception {
338         final WebRequest request = new WebRequest(URL_FIRST);
339         request.setCharset(StandardCharsets.UTF_8);
340         request.setDefaultResponseContentCharset(StandardCharsets.US_ASCII);
341 
342         final byte[] bytes = SerializationUtils.serialize(request);
343         final WebRequest deserialized = (WebRequest) SerializationUtils.deserialize(bytes);
344 
345         assertEquals(URL_FIRST, deserialized.getUrl());
346         assertEquals(StandardCharsets.UTF_8, deserialized.getCharset());
347         assertEquals(StandardCharsets.US_ASCII, deserialized.getDefaultResponseContentCharset());
348     }
349 }