1
2
3
4
5
6
7
8
9
10
11
12
13
14
15 package org.htmlunit.html;
16
17 import static java.nio.charset.StandardCharsets.UTF_8;
18
19 import java.io.File;
20 import java.io.IOException;
21 import java.io.Writer;
22 import java.util.HashMap;
23 import java.util.Map;
24
25 import javax.servlet.Servlet;
26 import javax.servlet.ServletException;
27 import javax.servlet.http.HttpServlet;
28 import javax.servlet.http.HttpServletRequest;
29 import javax.servlet.http.HttpServletResponse;
30
31 import org.apache.commons.fileupload.FileItem;
32 import org.apache.commons.fileupload.FileUploadBase;
33 import org.apache.commons.fileupload.disk.DiskFileItemFactory;
34 import org.apache.commons.fileupload.servlet.ServletFileUpload;
35 import org.htmlunit.WebDriverTestCase;
36 import org.htmlunit.junit.annotation.Alerts;
37 import org.htmlunit.util.MimeType;
38 import org.junit.jupiter.api.BeforeAll;
39 import org.junit.jupiter.api.Test;
40 import org.openqa.selenium.By;
41 import org.openqa.selenium.WebDriver;
42
43
44
45
46
47
48
49
50
51 public class HtmlFileInput3Test extends WebDriverTestCase {
52
53
54
55
56 @Test
57 @Alerts({"CONTENT_TYPE:application/octet-stream", "charset"})
58 public void contentTypeUnknown() throws Exception {
59 contentType("unknown");
60 }
61
62
63
64
65 @Test
66 @Alerts({"CONTENT_TYPE:text/html", "charset"})
67 public void contentTypeHtm() throws Exception {
68 contentType("htm");
69 }
70
71
72
73
74 @Test
75 @Alerts({"CONTENT_TYPE:text/html", "charset"})
76 public void contentTypeHtml() throws Exception {
77 contentType("html");
78 }
79
80
81
82
83 @Test
84 @Alerts({"CONTENT_TYPE:text/css", "charset"})
85 public void contentTypeCss() throws Exception {
86 contentType("css");
87 }
88
89
90
91
92 @Test
93 @Alerts({"CONTENT_TYPE:text/xml", "charset"})
94 public void contentTypeXml() throws Exception {
95 contentType("xml");
96 }
97
98
99
100
101 @Test
102 @Alerts({"CONTENT_TYPE:image/gif", "charset"})
103 public void contentTypeGif() throws Exception {
104 contentType("gif");
105 }
106
107
108
109
110 @Test
111 @Alerts({"CONTENT_TYPE:image/jpeg", "charset"})
112 public void contentTypeJpeg() throws Exception {
113 contentType("jpeg");
114 }
115
116
117
118
119 @Test
120 @Alerts({"CONTENT_TYPE:image/jpeg", "charset"})
121 public void contentTypeJpg() throws Exception {
122 contentType("jpg");
123 }
124
125
126
127
128 @Test
129 @Alerts({"CONTENT_TYPE:image/png", "charset"})
130 public void contentTypePng() throws Exception {
131 contentType("png");
132 }
133
134
135
136
137 @Test
138 @Alerts({"CONTENT_TYPE:image/webp", "charset"})
139 public void contentTypeWebp() throws Exception {
140 contentType("webp");
141 }
142
143
144
145
146 @Test
147 @Alerts({"CONTENT_TYPE:video/mp4", "charset"})
148 public void contentTypeMp4() throws Exception {
149 contentType("mp4");
150 }
151
152
153
154
155 @Test
156 @Alerts({"CONTENT_TYPE:video/mp4", "charset"})
157 public void contentTypeM4v() throws Exception {
158 contentType("m4v");
159 }
160
161
162
163
164 @Test
165 @Alerts(DEFAULT = {"CONTENT_TYPE:audio/mp4", "charset"},
166 CHROME = {"CONTENT_TYPE:audio/x-m4a", "charset"},
167 EDGE = {"CONTENT_TYPE:audio/x-m4a", "charset"})
168 public void contentTypeM4a() throws Exception {
169 contentType("m4a");
170 }
171
172
173
174
175 @Test
176 @Alerts({"CONTENT_TYPE:audio/mpeg", "charset"})
177 public void contentTypeMp3() throws Exception {
178 contentType("mp3");
179 }
180
181
182
183
184 @Test
185 @Alerts({"CONTENT_TYPE:video/ogg", "charset"})
186 public void contentTypeOgv() throws Exception {
187 contentType("ogv");
188 }
189
190
191
192
193 @Test
194 @Alerts({"CONTENT_TYPE:video/ogg", "charset"})
195 public void contentTypeOgm() throws Exception {
196 contentType("ogm");
197 }
198
199
200
201
202 @Test
203 @Alerts(DEFAULT = {"CONTENT_TYPE:audio/ogg", "charset"},
204 FF = {"CONTENT_TYPE:application/ogg", "charset"},
205 FF_ESR = {"CONTENT_TYPE:video/ogg", "charset"})
206 public void contentTypeOgg() throws Exception {
207 contentType("ogg");
208 }
209
210
211
212
213 @Test
214 @Alerts({"CONTENT_TYPE:audio/ogg", "charset"})
215 public void contentTypeOga() throws Exception {
216 contentType("oga");
217 }
218
219
220
221
222 @Test
223 @Alerts({"CONTENT_TYPE:audio/ogg", "charset"})
224 public void contentTypeOpus() throws Exception {
225 contentType("opus");
226 }
227
228
229
230
231 @Test
232 @Alerts({"CONTENT_TYPE:video/webm", "charset"})
233 public void contentTypeWebm() throws Exception {
234 contentType("webm");
235 }
236
237
238
239
240 @Test
241 @Alerts({"CONTENT_TYPE:application/pdf", "charset"})
242 public void contentTypePdf() throws Exception {
243 contentType("pdf");
244 }
245
246
247
248
249 @Test
250 @Alerts({"CONTENT_TYPE:audio/wav", "charset"})
251 public void contentTypeWav() throws Exception {
252 contentType("wav");
253 }
254
255
256
257
258 @Test
259 @Alerts(DEFAULT = {"CONTENT_TYPE:audio/flac", "charset"},
260 FF = {"CONTENT_TYPE:audio/x-flac", "charset"},
261 FF_ESR = {"CONTENT_TYPE:audio/x-flac", "charset"})
262 public void contentTypeFlac() throws Exception {
263 contentType("flac");
264 }
265
266
267
268
269 @Test
270 @Alerts({"CONTENT_TYPE:application/xhtml+xml", "charset"})
271 public void contentTypeXhtml() throws Exception {
272 contentType("xhtml");
273 }
274
275
276
277
278 @Test
279 @Alerts({"CONTENT_TYPE:application/xhtml+xml", "charset"})
280 public void contentTypeXht() throws Exception {
281 contentType("xht");
282 }
283
284
285
286
287 @Test
288 @Alerts(DEFAULT = {"CONTENT_TYPE:application/octet-stream", "charset"},
289 CHROME = {"CONTENT_TYPE:application/xhtml+xml", "charset"},
290 EDGE = {"CONTENT_TYPE:application/xhtml+xml", "charset"})
291 public void contentTypeXhtm() throws Exception {
292 contentType("xhtm");
293 }
294
295
296
297
298 @Test
299 @Alerts({"CONTENT_TYPE:text/plain", "charset"})
300 public void contentTypeText() throws Exception {
301 contentType("text");
302 }
303
304
305
306
307 @Test
308 @Alerts({"CONTENT_TYPE:text/plain", "charset"})
309 public void contentTypeTxt() throws Exception {
310 contentType("txt");
311 }
312
313
314
315
316 @Test
317 @Alerts({"CONTENT_TYPE:text/html", "charset"})
318 public void contentTypeCaseInsensitive() throws Exception {
319 contentType("HtmL");
320 }
321
322
323
324
325 @BeforeAll
326 public static void before() {
327 try {
328 final Map<String, Class<? extends Servlet>> servlets = new HashMap<>();
329 servlets.put("/upload1", Upload1Servlet.class);
330 servlets.put("/upload2", ContentTypeUpload2Servlet.class);
331 startWebServer("./", new String[0], servlets);
332 }
333 catch (final Exception e) {
334 throw new RuntimeException(e);
335 }
336 }
337
338 private void contentType(final String extension) throws Exception {
339 final WebDriver driver = getWebDriver();
340 driver.get(URL_FIRST + "upload1");
341
342 final File tmpFile = File.createTempFile("htmlunit-test", "." + extension);
343 try {
344 final String path = tmpFile.getAbsolutePath();
345 driver.findElement(By.name("myInput")).sendKeys(path);
346 driver.findElement(By.id("mySubmit")).submit();
347 }
348 finally {
349 assertTrue(tmpFile.delete());
350 }
351
352 final long maxWait = System.currentTimeMillis() + DEFAULT_WAIT_TIME.toMillis();
353
354 while (System.currentTimeMillis() < maxWait) {
355 try {
356 final String pageSource = driver.getPageSource();
357 assertNotNull(pageSource);
358 assertTrue(pageSource, pageSource.contains(getExpectedAlerts()[0]));
359 assertFalse(pageSource, pageSource.contains(getExpectedAlerts()[1]));
360 return;
361 }
362 catch (final AssertionError e) {
363
364 }
365 }
366
367 final String pageSource = driver.getPageSource();
368 assertTrue("\"" + pageSource + "\" does not contain \""
369 + getExpectedAlerts()[0] + "\"", pageSource.contains(getExpectedAlerts()[0]));
370 assertFalse("\"" + pageSource + "\" contains \""
371 + getExpectedAlerts()[0] + "\" but should not", pageSource.contains(getExpectedAlerts()[1]));
372 }
373
374
375
376
377 public static class Upload1Servlet extends HttpServlet {
378
379
380
381
382 @Override
383 protected void doGet(final HttpServletRequest request, final HttpServletResponse response)
384 throws ServletException, IOException {
385 response.setCharacterEncoding(UTF_8.name());
386 response.setContentType(MimeType.TEXT_HTML);
387 response.getWriter().write("<html>\n"
388 + "<body>\n"
389 + "<form action='upload2' method='post' enctype='multipart/form-data'>\n"
390 + "Name: <input name='myInput' type='file'><br>\n"
391 + "Name 2 (should stay empty): <input name='myInput2' type='file'><br>\n"
392 + "<input type='submit' value='Upload' id='mySubmit'>\n"
393 + "</form>\n"
394 + "</body></html>\n");
395 }
396 }
397
398
399
400
401 public static class ContentTypeUpload2Servlet extends HttpServlet {
402
403
404
405
406 @Override
407 protected void doPost(final HttpServletRequest request, final HttpServletResponse response)
408 throws ServletException, IOException {
409 request.setCharacterEncoding(UTF_8.name());
410 response.setContentType(MimeType.TEXT_HTML);
411 try (Writer writer = response.getWriter()) {
412 if (ServletFileUpload.isMultipartContent(request)) {
413 try {
414 final ServletFileUpload upload = new ServletFileUpload(new DiskFileItemFactory());
415 for (final FileItem item : upload.parseRequest(request)) {
416 if ("myInput".equals(item.getFieldName())) {
417 writer.write("CONTENT_TYPE:" + item.getContentType());
418 }
419 }
420 }
421 catch (final FileUploadBase.SizeLimitExceededException e) {
422 writer.write("SizeLimitExceeded");
423 }
424 catch (final Exception e) {
425 writer.write("error");
426 }
427 }
428 }
429 }
430 }
431 }