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