001/* 002 * Licensed to the Apache Software Foundation (ASF) under one or more 003 * contributor license agreements. See the NOTICE file distributed with 004 * this work for additional information regarding copyright ownership. 005 * The ASF licenses this file to You under the Apache License, Version 2.0 006 * (the "License"); you may not use this file except in compliance with 007 * the License. You may obtain a copy of the License at 008 * 009 * http://www.apache.org/licenses/LICENSE-2.0 010 * 011 * Unless required by applicable law or agreed to in writing, software 012 * distributed under the License is distributed on an "AS IS" BASIS, 013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 014 * See the License for the specific language governing permissions and 015 * limitations under the License. 016 */ 017 018package org.apache.commons.fileupload2.javax; 019 020import static org.junit.jupiter.api.Assertions.assertEquals; 021import static org.junit.jupiter.api.Assertions.assertTrue; 022 023import java.io.ByteArrayOutputStream; 024import java.io.IOException; 025import java.nio.charset.StandardCharsets; 026import java.util.List; 027 028import javax.servlet.http.HttpServletRequest; 029 030import org.apache.commons.fileupload2.core.AbstractFileUploadTest; 031import org.apache.commons.fileupload2.core.Constants; 032import org.apache.commons.fileupload2.core.DiskFileItem; 033import org.apache.commons.fileupload2.core.DiskFileItemFactory; 034import org.apache.commons.fileupload2.core.FileUploadException; 035import org.junit.jupiter.api.Test; 036 037/** 038 * Tests {@link JavaxServletFileUpload}. 039 * 040 * @see AbstractFileUploadTest 041 */ 042public class JavaxServletFileUploadTest 043 extends AbstractFileUploadTest<JavaxServletFileUpload<DiskFileItem, DiskFileItemFactory>, HttpServletRequest, DiskFileItem, DiskFileItemFactory> { 044 045 public JavaxServletFileUploadTest() { 046 super(new JavaxServletFileUpload<>(DiskFileItemFactory.builder().get())); 047 } 048 049 @Override 050 public List<DiskFileItem> parseUpload(final JavaxServletFileUpload<DiskFileItem, DiskFileItemFactory> upload, final byte[] bytes, final String contentType) 051 throws FileUploadException { 052 final HttpServletRequest request = new JavaxMockHttpServletRequest(bytes, contentType); 053 return upload.parseRequest(new JavaxServletRequestContext(request)); 054 } 055 056 /** 057 * Runs a test with varying file sizes. 058 */ 059 @Override 060 @Test 061 public void testFileUpload() throws IOException, FileUploadException { 062 final var baos = new ByteArrayOutputStream(); 063 var add = 16; 064 var num = 0; 065 for (var i = 0; i < 16384; i += add) { 066 if (++add == 32) { 067 add = 16; 068 } 069 final var header = "-----1234\r\n" + "Content-Disposition: form-data; name=\"field" + num++ + "\"\r\n" + "\r\n"; 070 baos.write(header.getBytes(StandardCharsets.US_ASCII)); 071 for (var j = 0; j < i; j++) { 072 baos.write((byte) j); 073 } 074 baos.write("\r\n".getBytes(StandardCharsets.US_ASCII)); 075 } 076 baos.write("-----1234--\r\n".getBytes(StandardCharsets.US_ASCII)); 077 078 final var fileItems = parseUpload(new JavaxServletFileUpload<>(DiskFileItemFactory.builder().get()), baos.toByteArray()); 079 final var fileIter = fileItems.iterator(); 080 add = 16; 081 num = 0; 082 for (var i = 0; i < 16384; i += add) { 083 if (++add == 32) { 084 add = 16; 085 } 086 final var item = fileIter.next(); 087 assertEquals("field" + num++, item.getFieldName()); 088 final var bytes = item.get(); 089 assertEquals(i, bytes.length); 090 for (var j = 0; j < i; j++) { 091 assertEquals((byte) j, bytes[j]); 092 } 093 } 094 assertTrue(!fileIter.hasNext()); 095 } 096 097 @Test 098 public void testParseImpliedUtf8() throws Exception { 099 // utf8 encoded form-data without explicit content-type encoding 100 // @formatter:off 101 final var text = "-----1234\r\n" + 102 "Content-Disposition: form-data; name=\"utf8Html\"\r\n" + 103 "\r\n" + 104 "Thís ís the coñteñt of the fíle\n" + 105 "\r\n" + 106 "-----1234--\r\n"; 107 // @formatter:on 108 109 final var bytes = text.getBytes(StandardCharsets.UTF_8); 110 final HttpServletRequest request = new JavaxMockHttpServletRequest(bytes, Constants.CONTENT_TYPE); 111 // @formatter:off 112 final var fileItemFactory = DiskFileItemFactory.builder() 113 .setCharset(StandardCharsets.UTF_8) 114 .get(); 115 // @formatter:on 116 final var upload = new JavaxServletFileUpload<>(fileItemFactory); 117 final var fileItems = upload.parseRequest(request); 118 final var fileItem = fileItems.get(0); 119 assertTrue(fileItem.getString().contains("coñteñt"), fileItem.getString()); 120 } 121 122 /* 123 * Test case for <a href="https://issues.apache.org/jira/browse/FILEUPLOAD-210"> 124 */ 125 @Test 126 public void testParseParameterMap() throws Exception { 127 // @formatter:off 128 final var text = "-----1234\r\n" + 129 "Content-Disposition: form-data; name=\"file\"; filename=\"foo.tab\"\r\n" + 130 "Content-Type: text/whatever\r\n" + 131 "\r\n" + 132 "This is the content of the file\n" + 133 "\r\n" + 134 "-----1234\r\n" + 135 "Content-Disposition: form-data; name=\"field\"\r\n" + 136 "\r\n" + 137 "fieldValue\r\n" + 138 "-----1234\r\n" + 139 "Content-Disposition: form-data; name=\"multi\"\r\n" + 140 "\r\n" + 141 "value1\r\n" + 142 "-----1234\r\n" + 143 "Content-Disposition: form-data; name=\"multi\"\r\n" + 144 "\r\n" + 145 "value2\r\n" + 146 "-----1234--\r\n"; 147 // @formatter:on 148 final var bytes = text.getBytes(StandardCharsets.US_ASCII); 149 final HttpServletRequest request = new JavaxMockHttpServletRequest(bytes, Constants.CONTENT_TYPE); 150 151 final var upload = new JavaxServletFileUpload<>(DiskFileItemFactory.builder().get()); 152 final var mappedParameters = upload.parseParameterMap(request); 153 assertTrue(mappedParameters.containsKey("file")); 154 assertEquals(1, mappedParameters.get("file").size()); 155 156 assertTrue(mappedParameters.containsKey("field")); 157 assertEquals(1, mappedParameters.get("field").size()); 158 159 assertTrue(mappedParameters.containsKey("multi")); 160 assertEquals(2, mappedParameters.get("multi").size()); 161 } 162 163}