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 java.io.IOException;
18  import java.io.Writer;
19  import java.net.URL;
20  import java.util.ArrayList;
21  import java.util.Collections;
22  import java.util.HashMap;
23  import java.util.List;
24  import java.util.Map;
25  
26  import javax.servlet.Servlet;
27  import javax.servlet.ServletException;
28  import javax.servlet.http.HttpServlet;
29  import javax.servlet.http.HttpServletRequest;
30  import javax.servlet.http.HttpServletResponse;
31  
32  import org.htmlunit.junit.BrowserRunner;
33  import org.htmlunit.util.NameValuePair;
34  import org.junit.Before;
35  import org.junit.Test;
36  import org.junit.runner.RunWith;
37  
38  /**
39   * Tests for {@link WebRequest#getParameters()}.
40   * This method is used by Spring MVC test to shortcut the
41   * request processing (without involving a server). Therefore
42   * we have to make sure this works as expected in all cases.
43   *
44   * see https://github.com/spring-projects/spring-framework/issues/28240
45   * see https://github.com/HtmlUnit/htmlunit/pull/836
46   *
47   * @author Ronald Brill
48   */
49  @RunWith(BrowserRunner.class)
50  public class WebRequest2Test extends WebServerTestCase {
51  
52      /**
53       * Performs pre-test construction.
54       * @throws Exception if an error occurs
55       */
56      @Before
57      public void setup() throws Exception {
58          // we have to stop all servers running already to free the port
59          WebDriverTestCase.stopWebServers();
60  
61          final Map<String, Class<? extends Servlet>> servlets = new HashMap<>();
62          servlets.put("/", InspectServlet.class);
63          startWebServer("./", null, servlets);
64      }
65  
66      /**
67       * @throws Exception if the test fails
68       */
69      @Test
70      public void getParametersNone() throws Exception {
71          final WebRequest request = new WebRequest(URL_FIRST);
72  
73          final Page page = getWebClient().getPage(request);
74          assertTrue(page instanceof TextPage);
75          assertEquals("Parameters: \n", ((TextPage) page).getContent());
76  
77          final List<NameValuePair> parameters = request.getParameters();
78          assertEquals(0, parameters.size());
79      }
80  
81      /**
82       * @throws Exception if the test fails
83       */
84      @Test
85      public void getParametersOnePair() throws Exception {
86          final WebRequest request = new WebRequest(new URL(URL_FIRST, "?x=u"));
87          Page page = getWebClient().getPage(request);
88          assertTrue(page instanceof TextPage);
89          assertEquals("Parameters: \n  'x': 'u'\n", ((TextPage) page).getContent());
90  
91          List<NameValuePair> parameters = request.getParameters();
92          assertEquals(1, parameters.size());
93          assertEquals("x", parameters.get(0).getName());
94          assertEquals("u", parameters.get(0).getValue());
95  
96          final List<NameValuePair> pairs = new ArrayList<>();
97          pairs.add(new NameValuePair("hello", "world"));
98          request.setRequestParameters(pairs);
99          page = getWebClient().getPage(request);
100         assertTrue(page instanceof TextPage);
101         assertEquals("Parameters: \n  'hello': 'world'\n", ((TextPage) page).getContent());
102 
103         parameters = request.getParameters();
104         assertEquals(1, parameters.size());
105         assertEquals("x", parameters.get(0).getName());
106         assertEquals("u", parameters.get(0).getValue());
107     }
108 
109     /**
110      * @throws Exception if the test fails
111      */
112     @Test
113     public void getParametersOnePairKeyEquals() throws Exception {
114         final WebRequest request = new WebRequest(new URL(URL_FIRST, "?x="));
115         Page page = getWebClient().getPage(request);
116         assertTrue(page instanceof TextPage);
117         assertEquals("Parameters: \n  'x': ''\n", ((TextPage) page).getContent());
118 
119         List<NameValuePair> parameters = request.getParameters();
120         assertEquals(1, parameters.size());
121         assertEquals("x", parameters.get(0).getName());
122         assertEquals("", parameters.get(0).getValue());
123 
124         final List<NameValuePair> pairs = new ArrayList<>();
125         pairs.add(new NameValuePair("hello", ""));
126         request.setRequestParameters(pairs);
127         page = getWebClient().getPage(request);
128         assertTrue(page instanceof TextPage);
129         assertEquals("Parameters: \n  'hello': ''\n", ((TextPage) page).getContent());
130 
131         parameters = request.getParameters();
132         assertEquals(1, parameters.size());
133         assertEquals("x", parameters.get(0).getName());
134         assertEquals("", parameters.get(0).getValue());
135     }
136 
137     /**
138      * @throws Exception if the test fails
139      */
140     @Test
141     public void getParametersOnePairKeyOnly() throws Exception {
142         final WebRequest request = new WebRequest(new URL(URL_FIRST, "?x"));
143         Page page = getWebClient().getPage(request);
144         assertTrue(page instanceof TextPage);
145         assertEquals("Parameters: \n  'x': ''\n", ((TextPage) page).getContent());
146 
147         List<NameValuePair> parameters = request.getParameters();
148         assertEquals(1, parameters.size());
149         assertEquals("x", parameters.get(0).getName());
150         assertEquals("", parameters.get(0).getValue());
151 
152         final List<NameValuePair> pairs = new ArrayList<>();
153         pairs.add(new NameValuePair("hello", null));
154         request.setRequestParameters(pairs);
155         page = getWebClient().getPage(request);
156         assertTrue(page instanceof TextPage);
157         assertEquals("Parameters: \n  'hello': ''\n", ((TextPage) page).getContent());
158 
159         parameters = request.getParameters();
160         assertEquals(1, parameters.size());
161         assertEquals("x", parameters.get(0).getName());
162         assertEquals("", parameters.get(0).getValue());
163     }
164 
165     /**
166      * @throws Exception if the test fails
167      */
168     @Test
169     public void getParametersFromQueryAndUrlEncodedBodyPost() throws Exception {
170         final URL url = new URL(URL_FIRST, "?a=b");
171         final WebRequest request = new WebRequest(url);
172         request.setHttpMethod(HttpMethod.POST);
173         request.setEncodingType(FormEncodingType.URL_ENCODED);
174         request.setRequestBody("c=d");
175 
176         final Page page = getWebClient().getPage(request);
177         assertTrue(page instanceof TextPage);
178 
179         assertEquals("Parameters: \n  'a': 'b'\n  'c': 'd'\n", ((TextPage) page).getContent());
180 
181         final List<NameValuePair> parameters = request.getParameters();
182         assertEquals(2, parameters.size());
183         assertEquals("a", parameters.get(0).getName());
184         assertEquals("b", parameters.get(0).getValue());
185         assertEquals("c", parameters.get(1).getName());
186         assertEquals("d", parameters.get(1).getValue());
187     }
188 
189     /**
190      * @throws Exception if the test fails
191      */
192     @Test
193     public void getParametersFromQueryAndUrlEncodedBodyPostWhenEncodingTypeIsMultipart() throws Exception {
194         final URL url = new URL(URL_FIRST, "?a=b");
195         final WebRequest request = new WebRequest(url);
196         request.setHttpMethod(HttpMethod.POST);
197         request.setEncodingType(FormEncodingType.MULTIPART);
198         request.setRequestParameters(Collections.singletonList(new NameValuePair("c", "d")));
199 
200         final Page page = getWebClient().getPage(request);
201         assertTrue(page instanceof TextPage);
202         assertEquals("Parameters: \n  'a': 'b'\n", ((TextPage) page).getContent());
203 
204         final List<NameValuePair> parameters = request.getParameters();
205         assertEquals(2, parameters.size());
206         assertEquals("a", parameters.get(0).getName());
207         assertEquals("b", parameters.get(0).getValue());
208         assertEquals("c", parameters.get(1).getName());
209         assertEquals("d", parameters.get(1).getValue());
210     }
211 
212     /**
213      * @throws Exception if the test fails
214      */
215     @Test
216     public void getParametersUrlEncodedPostNoBody() throws Exception {
217         final URL url = new URL(URL_FIRST, "?a=b");
218         final WebRequest request = new WebRequest(url);
219         request.setHttpMethod(HttpMethod.POST);
220         request.setEncodingType(FormEncodingType.URL_ENCODED);
221 
222         final Page page = getWebClient().getPage(request);
223         assertTrue(page instanceof TextPage);
224         assertEquals("Parameters: \n  'a': 'b'\n", ((TextPage) page).getContent());
225 
226         final List<NameValuePair> parameters = request.getParameters();
227         assertEquals(1, parameters.size());
228         assertEquals("a", parameters.get(0).getName());
229         assertEquals("b", parameters.get(0).getValue());
230     }
231 
232     /**
233      * @throws Exception if the test fails
234      */
235     @Test
236     public void getParametersTextEncodedPostNoBody() throws Exception {
237         final URL url = new URL(URL_FIRST, "?a=b");
238         final WebRequest request = new WebRequest(url);
239         request.setHttpMethod(HttpMethod.POST);
240         request.setEncodingType(FormEncodingType.TEXT_PLAIN);
241 
242         final Page page = getWebClient().getPage(request);
243         assertTrue(page instanceof TextPage);
244         assertEquals("Parameters: \n  'a': 'b'\n", ((TextPage) page).getContent());
245 
246         final List<NameValuePair> parameters = request.getParameters();
247         assertEquals(1, parameters.size());
248         assertEquals("a", parameters.get(0).getName());
249         assertEquals("b", parameters.get(0).getValue());
250     }
251 
252     /**
253      * @throws Exception if the test fails
254      */
255     @Test
256     public void getParametersTextEncodedPostBody() throws Exception {
257         final URL url = new URL(URL_FIRST, "?a=b");
258         final WebRequest request = new WebRequest(url);
259         request.setHttpMethod(HttpMethod.POST);
260         request.setEncodingType(FormEncodingType.TEXT_PLAIN);
261         request.setRequestBody("c=d");
262 
263         final Page page = getWebClient().getPage(request);
264         assertTrue(page instanceof TextPage);
265         assertEquals("Parameters: \n  'a': 'b'\n", ((TextPage) page).getContent());
266 
267         final List<NameValuePair> parameters = request.getParameters();
268         assertEquals(1, parameters.size());
269         assertEquals("a", parameters.get(0).getName());
270         assertEquals("b", parameters.get(0).getValue());
271     }
272 
273     /**
274      * Servlet.
275      */
276     public static class InspectServlet extends HttpServlet {
277 
278         @Override
279         protected void doGet(final HttpServletRequest req, final HttpServletResponse resp)
280             throws ServletException, IOException {
281             bounce(req, resp);
282         }
283 
284         @Override
285         protected void doHead(final HttpServletRequest req, final HttpServletResponse resp)
286             throws ServletException, IOException {
287             bounce(req, resp);
288         }
289 
290         @Override
291         protected void doPost(final HttpServletRequest req, final HttpServletResponse resp)
292             throws ServletException, IOException {
293             bounce(req, resp);
294         }
295 
296         @Override
297         protected void doPut(final HttpServletRequest req, final HttpServletResponse resp)
298             throws ServletException, IOException {
299             bounce(req, resp);
300         }
301 
302         @Override
303         protected void doDelete(final HttpServletRequest req, final HttpServletResponse resp)
304             throws ServletException, IOException {
305             bounce(req, resp);
306         }
307 
308         @Override
309         protected void doOptions(final HttpServletRequest req, final HttpServletResponse resp)
310             throws ServletException, IOException {
311             bounce(req, resp);
312         }
313 
314         @Override
315         protected void doTrace(final HttpServletRequest req, final HttpServletResponse resp)
316             throws ServletException, IOException {
317             bounce(req, resp);
318         }
319 
320         private static void bounce(final HttpServletRequest req, final HttpServletResponse resp) throws IOException {
321             try (Writer writer = resp.getWriter()) {
322                 writer.write("Parameters: \n");
323                 for (final String key : req.getParameterMap().keySet()) {
324                     final String val = req.getParameter(key);
325                     if (val == null) {
326                         writer.write("  '" + key + "': '-null-'\n");
327                     }
328                     else {
329                         writer.write("  '" + key + "': '" + val + "'\n");
330                     }
331                 }
332             }
333         }
334     }
335 }