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