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.javascript.host.xml;
16  
17  import java.nio.charset.Charset;
18  
19  import org.htmlunit.WebDriverTestCase;
20  import org.htmlunit.junit.annotation.Alerts;
21  import org.junit.jupiter.api.Test;
22  
23  /**
24   * Tests for {@link XMLHttpRequest} data url handling.
25   *
26   * @author Ronald Brill
27   */
28  public class XMLHttpRequest6Test extends WebDriverTestCase {
29  
30      /**
31       * @throws Exception if the test fails
32       */
33      @Test
34      @Alerts({"4", "200", "foo", "send done"})
35      public void sendDataUrl_Get() throws Exception {
36          startWebServer(getMockWebConnection(), Charset.defaultCharset());
37  
38          final String html = DOCTYPE_HTML
39                  + "<html>\n"
40                  + "<head>"
41                  + "</head>"
42                  + "<body>"
43                  + "<script>\n"
44                  + LOG_TITLE_FUNCTION
45                  + "  try {\n"
46                  + "    let xhr = new XMLHttpRequest();\n"
47                  + "    xhr.open('GET', 'data:text/plain;charset=utf-8,foo', false);\n"
48                  + "    xhr.onload = function() {\n"
49                  + "      log(xhr.readyState);\n"
50                  + "      log(xhr.status);\n"
51                  + "      log(xhr.responseText);\n"
52                  + "    };\n"
53                  + "    xhr.send();\n"
54                  + "    log('send done');\n"
55                  + "  } catch (e) { logEx(e); }\n"
56                  + "</script>\n"
57                  + "</body>\n"
58                  + "</html>";
59  
60          final int requestCount = getMockWebConnection().getRequestCount();
61          loadPageVerifyTitle2(html);
62  
63          assertEquals(requestCount + 1, getMockWebConnection().getRequestCount());
64      }
65  
66      /**
67       * @throws Exception if the test fails
68       */
69      @Test
70      @Alerts({"send done", "4", "200", "foo"})
71      public void sendDataUrl_GetAsync() throws Exception {
72          startWebServer(getMockWebConnection(), Charset.defaultCharset());
73  
74          final String html = DOCTYPE_HTML
75                  + "<html>\n"
76                  + "<head>"
77                  + "</head>"
78                  + "<body>"
79                  + "<script>\n"
80                  + LOG_TITLE_FUNCTION
81                  + "  try {\n"
82                  + "    let xhr = new XMLHttpRequest();\n"
83                  + "    xhr.open('GET', 'data:text/plain;charset=utf-8,foo', true);\n"
84                  + "    xhr.onload = function() {\n"
85                  + "      log(xhr.readyState);\n"
86                  + "      log(xhr.status);\n"
87                  + "      log(xhr.responseText);\n"
88                  + "    };\n"
89                  + "    xhr.send();\n"
90                  + "    log('send done');\n"
91                  + "  } catch (e) { logEx(e); }\n"
92                  + "</script>\n"
93                  + "</body>\n"
94                  + "</html>";
95  
96          final int requestCount = getMockWebConnection().getRequestCount();
97          loadPage2(html);
98          verifyTitle2(DEFAULT_WAIT_TIME, getWebDriver(), getExpectedAlerts());
99  
100         assertEquals(requestCount + 1, getMockWebConnection().getRequestCount());
101     }
102 
103     /**
104      * @throws Exception if the test fails
105      */
106     @Test
107     @Alerts({"4", "200", "foo"})
108     public void sendDataUrl_GetEncoded() throws Exception {
109         startWebServer(getMockWebConnection(), Charset.defaultCharset());
110 
111         final String html = DOCTYPE_HTML
112                 + "<html>\n"
113                 + "<head>"
114                 + "</head>"
115                 + "<body>"
116                 + "<script>\n"
117                 + LOG_TITLE_FUNCTION
118                 + "  try {\n"
119                 + "    let xhr = new XMLHttpRequest();\n"
120                 + "    xhr.open('GET', 'data:text/plain;base64,Zm9v', false);\n"
121                 + "    xhr.onload = function() {\n"
122                 + "      log(xhr.readyState);\n"
123                 + "      log(xhr.status);\n"
124                 + "      log(xhr.responseText);\n"
125                 + "    };\n"
126                 + "    xhr.send();\n"
127                 + "  } catch (e) { logEx(e); }\n"
128                 + "</script>\n"
129                 + "</body>\n"
130                 + "</html>";
131 
132         final int requestCount = getMockWebConnection().getRequestCount();
133         loadPageVerifyTitle2(html);
134 
135         assertEquals(requestCount + 1, getMockWebConnection().getRequestCount());
136     }
137 
138     /**
139      * @throws Exception if the test fails
140      */
141     @Test
142     @Alerts({"4", "200", "foo"})
143     public void sendDataUrl_GetSimpleTextUrl() throws Exception {
144         startWebServer(getMockWebConnection(), Charset.defaultCharset());
145 
146         final String html = DOCTYPE_HTML
147                 + "<html>\n"
148                 + "<head>"
149                 + "</head>"
150                 + "<body>"
151                 + "<script>\n"
152                 + LOG_TITLE_FUNCTION
153                 + "  try {\n"
154                 + "    let xhr = new XMLHttpRequest();\n"
155                 + "    xhr.open('GET', 'data:,foo', false);\n"
156                 + "    xhr.onload = function() {\n"
157                 + "      log(xhr.readyState);\n"
158                 + "      log(xhr.status);\n"
159                 + "      log(xhr.responseText);\n"
160                 + "    };\n"
161                 + "    xhr.send();\n"
162                 + "  } catch (e) { logEx(e); }\n"
163                 + "</script>\n"
164                 + "</body>\n"
165                 + "</html>";
166 
167         final int requestCount = getMockWebConnection().getRequestCount();
168         loadPageVerifyTitle2(html);
169 
170         assertEquals(requestCount + 1, getMockWebConnection().getRequestCount());
171     }
172 
173     /**
174      * @throws Exception if the test fails
175      */
176     @Test
177     @Alerts({"4", "200", "foo"})
178     public void sendDataUrl_GetSimpleTextUrlMediaType() throws Exception {
179         startWebServer(getMockWebConnection(), Charset.defaultCharset());
180 
181         final String html = DOCTYPE_HTML
182                 + "<html>\n"
183                 + "<head>"
184                 + "</head>"
185                 + "<body>"
186                 + "<script>\n"
187                 + LOG_TITLE_FUNCTION
188                 + "  try {\n"
189                 + "    let xhr = new XMLHttpRequest();\n"
190                 + "    xhr.open('GET', 'data:text/plain,foo', false);\n"
191                 + "    xhr.onload = function() {\n"
192                 + "      log(xhr.readyState);\n"
193                 + "      log(xhr.status);\n"
194                 + "      log(xhr.responseText);\n"
195                 + "    };\n"
196                 + "    xhr.send('text to get');\n"
197                 + "  } catch (e) { logEx(e); }\n"
198                 + "</script>\n"
199                 + "</body>\n"
200                 + "</html>";
201 
202         final int requestCount = getMockWebConnection().getRequestCount();
203         loadPageVerifyTitle2(html);
204 
205         assertEquals(requestCount + 1, getMockWebConnection().getRequestCount());
206     }
207 
208     /**
209      * @throws Exception if the test fails
210      */
211     @Test
212     @Alerts({"4", "200", "foo"})
213     public void sendDataUrl_Post() throws Exception {
214         startWebServer(getMockWebConnection(), Charset.defaultCharset());
215 
216         final String html = DOCTYPE_HTML
217                 + "<html>\n"
218                 + "<head>"
219                 + "</head>"
220                 + "<body>"
221                 + "<script>\n"
222                 + LOG_TITLE_FUNCTION
223                 + "  try {\n"
224                 + "    let xhr = new XMLHttpRequest();\n"
225                 + "    xhr.open('POST', 'data:text/plain;charset=utf-8,foo', false);\n"
226                 + "    xhr.onload = function() {\n"
227                 + "      log(xhr.readyState);\n"
228                 + "      log(xhr.status);\n"
229                 + "      log(xhr.responseText);\n"
230                 + "    };\n"
231                 + "    xhr.send('text to post');\n"
232                 + "  } catch (e) { logEx(e); }\n"
233                 + "</script>\n"
234                 + "</body>\n"
235                 + "</html>";
236 
237         final int requestCount = getMockWebConnection().getRequestCount();
238         loadPageVerifyTitle2(html);
239 
240         assertEquals(requestCount + 1, getMockWebConnection().getRequestCount());
241     }
242 
243     /**
244      * @throws Exception if the test fails
245      */
246     @Test
247     @Alerts({"4", "200", "foo"})
248     public void sendDataUrl_Put() throws Exception {
249         startWebServer(getMockWebConnection(), Charset.defaultCharset());
250 
251         final String html = DOCTYPE_HTML
252                 + "<html>\n"
253                 + "<head>"
254                 + "</head>"
255                 + "<body>"
256                 + "<script>\n"
257                 + LOG_TITLE_FUNCTION
258                 + "  try {\n"
259                 + "    let xhr = new XMLHttpRequest();\n"
260                 + "    xhr.open('PUT', 'data:text/plain;charset=utf-8,foo', false);\n"
261                 + "    xhr.onload = function() {\n"
262                 + "      log(xhr.readyState);\n"
263                 + "      log(xhr.status);\n"
264                 + "      log(xhr.responseText);\n"
265                 + "    };\n"
266                 + "    xhr.send('text to put');\n"
267                 + "  } catch (e) { logEx(e); }\n"
268                 + "</script>\n"
269                 + "</body>\n"
270                 + "</html>";
271 
272         final int requestCount = getMockWebConnection().getRequestCount();
273         loadPageVerifyTitle2(html);
274 
275         assertEquals(requestCount + 1, getMockWebConnection().getRequestCount());
276     }
277 
278     /**
279      * @throws Exception if the test fails
280      */
281     @Test
282     @Alerts({"4", "200", "foo"})
283     public void sendDataUrl_Delete() throws Exception {
284         startWebServer(getMockWebConnection(), Charset.defaultCharset());
285 
286         final String html = DOCTYPE_HTML
287                 + "<html>\n"
288                 + "<head>"
289                 + "</head>"
290                 + "<body>"
291                 + "<script>\n"
292                 + LOG_TITLE_FUNCTION
293                 + "  try {\n"
294                 + "    let xhr = new XMLHttpRequest();\n"
295                 + "    xhr.open('DELETE', 'data:text/plain;charset=utf-8,foo', false);\n"
296                 + "    xhr.onload = function() {\n"
297                 + "      log(xhr.readyState);\n"
298                 + "      log(xhr.status);\n"
299                 + "      log(xhr.responseText);\n"
300                 + "    };\n"
301                 + "    xhr.send('text to delete');\n"
302                 + "  } catch (e) { logEx(e); }\n"
303                 + "</script>\n"
304                 + "</body>\n"
305                 + "</html>";
306 
307         final int requestCount = getMockWebConnection().getRequestCount();
308         loadPageVerifyTitle2(html);
309 
310         assertEquals(requestCount + 1, getMockWebConnection().getRequestCount());
311     }
312 
313     /**
314      * @throws Exception if the test fails
315      */
316     @Test
317     @Alerts({"4", "200", "foo"})
318     public void sendDataUrl_Patch() throws Exception {
319         startWebServer(getMockWebConnection(), Charset.defaultCharset());
320 
321         final String html = DOCTYPE_HTML
322                 + "<html>\n"
323                 + "<head>"
324                 + "</head>"
325                 + "<body>"
326                 + "<script>\n"
327                 + LOG_TITLE_FUNCTION
328                 + "  try {\n"
329                 + "    let xhr = new XMLHttpRequest();\n"
330                 + "    xhr.open('PATCH', 'data:text/plain;charset=utf-8,foo', false);\n"
331                 + "    xhr.onload = function() {\n"
332                 + "      log(xhr.readyState);\n"
333                 + "      log(xhr.status);\n"
334                 + "      log(xhr.responseText);\n"
335                 + "    };\n"
336                 + "    xhr.send('text to patch');\n"
337                 + "  } catch (e) { logEx(e); }\n"
338                 + "</script>\n"
339                 + "</body>\n"
340                 + "</html>";
341 
342         final int requestCount = getMockWebConnection().getRequestCount();
343         loadPageVerifyTitle2(html);
344 
345         assertEquals(requestCount + 1, getMockWebConnection().getRequestCount());
346     }
347 
348     /**
349      * @throws Exception if the test fails
350      */
351     @Test
352     @Alerts({"4", "200", ""})
353     public void sendDataUrl_Head() throws Exception {
354         startWebServer(getMockWebConnection(), Charset.defaultCharset());
355 
356         final String html = DOCTYPE_HTML
357                 + "<html>\n"
358                 + "<head>"
359                 + "</head>"
360                 + "<body>"
361                 + "<script>\n"
362                 + LOG_TITLE_FUNCTION
363                 + "  try {\n"
364                 + "    let xhr = new XMLHttpRequest();\n"
365                 + "    xhr.open('HEAD', 'data:text/plain;charset=utf-8,foo', false);\n"
366                 + "    xhr.onload = function() {\n"
367                 + "      log(xhr.readyState);\n"
368                 + "      log(xhr.status);\n"
369                 + "      log(xhr.responseText);\n"
370                 + "    };\n"
371                 + "    xhr.send('text to head');\n"
372                 + "  } catch (e) { logEx(e); }\n"
373                 + "</script>\n"
374                 + "</body>\n"
375                 + "</html>";
376 
377         final int requestCount = getMockWebConnection().getRequestCount();
378         loadPageVerifyTitle2(html);
379 
380         assertEquals(requestCount + 1, getMockWebConnection().getRequestCount());
381     }
382 
383     /**
384      * @throws Exception if the test fails
385      */
386     @Test
387     @Alerts({"4", "200", "foo"})
388     public void sendDataUrl_Options() throws Exception {
389         startWebServer(getMockWebConnection(), Charset.defaultCharset());
390 
391         final String html = DOCTYPE_HTML
392                 + "<html>\n"
393                 + "<head>"
394                 + "</head>"
395                 + "<body>"
396                 + "<script>\n"
397                 + LOG_TITLE_FUNCTION
398                 + "  try {\n"
399                 + "    let xhr = new XMLHttpRequest();\n"
400                 + "    xhr.open('OPTIONS', 'data:text/plain;charset=utf-8,foo', false);\n"
401                 + "    xhr.onload = function() {\n"
402                 + "      log(xhr.readyState);\n"
403                 + "      log(xhr.status);\n"
404                 + "      log(xhr.responseText);\n"
405                 + "    };\n"
406                 + "    xhr.send('text to options');\n"
407                 + "  } catch (e) { logEx(e); }\n"
408                 + "</script>\n"
409                 + "</body>\n"
410                 + "</html>";
411 
412         final int requestCount = getMockWebConnection().getRequestCount();
413         loadPageVerifyTitle2(html);
414 
415         assertEquals(requestCount + 1, getMockWebConnection().getRequestCount());
416     }
417 }