1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.apache.commons.fileupload;
18
19 import static org.junit.Assert.assertEquals;
20 import static org.junit.Assert.assertFalse;
21 import static org.junit.Assert.assertTrue;
22 import static org.junit.Assert.fail;
23 import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
24 import static org.junit.jupiter.api.Assertions.assertThrows;
25
26 import java.io.ByteArrayOutputStream;
27 import java.io.IOException;
28 import java.io.InputStream;
29 import java.util.Iterator;
30 import java.util.List;
31
32 import javax.servlet.http.HttpServletRequest;
33
34 import org.apache.commons.fileupload.FileUploadBase.FileUploadIOException;
35 import org.apache.commons.fileupload.MultipartStream.MalformedStreamException;
36 import org.apache.commons.fileupload.disk.DiskFileItemFactory;
37 import org.apache.commons.fileupload.servlet.ServletFileUpload;
38 import org.apache.commons.fileupload.util.Streams;
39 import org.junit.Test;
40
41
42
43
44 public class SizesTest {
45
46
47
48 @Test
49 public void testFileSizeLimit()
50 throws IOException, FileUploadException {
51 final String request =
52 "-----1234\r\n" +
53 "Content-Disposition: form-data; name=\"file\"; filename=\"foo.tab\"\r\n" +
54 "Content-Type: text/whatever\r\n" +
55 "\r\n" +
56 "This is the content of the file\n" +
57 "\r\n" +
58 "-----1234--\r\n";
59
60 ServletFileUpload upload = new ServletFileUpload(new DiskFileItemFactory());
61 upload.setFileSizeMax(-1);
62 HttpServletRequest req = new MockHttpServletRequest(
63 request.getBytes("US-ASCII"), Constants.CONTENT_TYPE);
64 List<FileItem> fileItems = upload.parseRequest(req);
65 assertEquals(1, fileItems.size());
66 FileItem item = fileItems.get(0);
67 assertEquals("This is the content of the file\n", new String(item.get()));
68
69 upload = new ServletFileUpload(new DiskFileItemFactory());
70 upload.setFileSizeMax(40);
71 req = new MockHttpServletRequest(request.getBytes("US-ASCII"), Constants.CONTENT_TYPE);
72 fileItems = upload.parseRequest(req);
73 assertEquals(1, fileItems.size());
74 item = fileItems.get(0);
75 assertEquals("This is the content of the file\n", new String(item.get()));
76
77 upload = new ServletFileUpload(new DiskFileItemFactory());
78 upload.setFileSizeMax(30);
79 req = new MockHttpServletRequest(request.getBytes("US-ASCII"), Constants.CONTENT_TYPE);
80 try {
81 upload.parseRequest(req);
82 fail("Expected exception.");
83 } catch (final FileUploadBase.FileSizeLimitExceededException e) {
84 assertEquals(30, e.getPermittedSize());
85 }
86 }
87
88
89
90 @Test
91 public void testFileSizeLimitWithFakedContentLength()
92 throws IOException, FileUploadException {
93 final String request =
94 "-----1234\r\n" +
95 "Content-Disposition: form-data; name=\"file\"; filename=\"foo.tab\"\r\n" +
96 "Content-Type: text/whatever\r\n" +
97 "Content-Length: 10\r\n" +
98 "\r\n" +
99 "This is the content of the file\n" +
100 "\r\n" +
101 "-----1234--\r\n";
102
103 ServletFileUpload upload = new ServletFileUpload(new DiskFileItemFactory());
104 upload.setFileSizeMax(-1);
105 HttpServletRequest req = new MockHttpServletRequest(
106 request.getBytes("US-ASCII"), Constants.CONTENT_TYPE);
107 List<FileItem> fileItems = upload.parseRequest(req);
108 assertEquals(1, fileItems.size());
109 FileItem item = fileItems.get(0);
110 assertEquals("This is the content of the file\n", new String(item.get()));
111
112 upload = new ServletFileUpload(new DiskFileItemFactory());
113 upload.setFileSizeMax(40);
114 req = new MockHttpServletRequest(request.getBytes("US-ASCII"), Constants.CONTENT_TYPE);
115 fileItems = upload.parseRequest(req);
116 assertEquals(1, fileItems.size());
117 item = fileItems.get(0);
118 assertEquals("This is the content of the file\n", new String(item.get()));
119
120
121 upload = new ServletFileUpload(new DiskFileItemFactory());
122 upload.setFileSizeMax(5);
123 req = new MockHttpServletRequest(request.getBytes("US-ASCII"), Constants.CONTENT_TYPE);
124 try {
125 upload.parseRequest(req);
126 fail("Expected exception.");
127 } catch (final FileUploadBase.FileSizeLimitExceededException e) {
128 assertEquals(5, e.getPermittedSize());
129 }
130
131
132 upload = new ServletFileUpload(new DiskFileItemFactory());
133 upload.setFileSizeMax(15);
134 req = new MockHttpServletRequest(request.getBytes("US-ASCII"), Constants.CONTENT_TYPE);
135 try {
136 upload.parseRequest(req);
137 fail("Expected exception.");
138 } catch (final FileUploadBase.FileSizeLimitExceededException e) {
139 assertEquals(15, e.getPermittedSize());
140 }
141 }
142
143
144
145
146 @Test
147 public void testFileUpload()
148 throws IOException, FileUploadException {
149 final ByteArrayOutputStream baos = new ByteArrayOutputStream();
150 int add = 16;
151 int num = 0;
152 for (int i = 0; i < 16384; i += add) {
153 if (++add == 32) {
154 add = 16;
155 }
156 final String header = "-----1234\r\n"
157 + "Content-Disposition: form-data; name=\"field" + num++ + "\"\r\n"
158 + "\r\n";
159 baos.write(header.getBytes("US-ASCII"));
160 for (int j = 0; j < i; j++) {
161 baos.write((byte) j);
162 }
163 baos.write("\r\n".getBytes("US-ASCII"));
164 }
165 baos.write("-----1234--\r\n".getBytes("US-ASCII"));
166
167 final List<FileItem> fileItems =
168 Util.parseUpload(new ServletFileUpload(new DiskFileItemFactory()), baos.toByteArray());
169 final Iterator<FileItem> fileIter = fileItems.iterator();
170 add = 16;
171 num = 0;
172 for (int i = 0; i < 16384; i += add) {
173 if (++add == 32) {
174 add = 16;
175 }
176 final FileItem item = fileIter.next();
177 assertEquals("field" + num++, item.getFieldName());
178 final byte[] bytes = item.get();
179 assertEquals(i, bytes.length);
180 for (int j = 0; j < i; j++) {
181 assertEquals((byte) j, bytes[j]);
182 }
183 }
184 assertTrue(!fileIter.hasNext());
185 }
186
187
188
189 @Test
190 public void testMaxSizeLimit()
191 throws IOException, FileUploadException {
192 final String request =
193 "-----1234\r\n" +
194 "Content-Disposition: form-data; name=\"file1\"; filename=\"foo1.tab\"\r\n" +
195 "Content-Type: text/whatever\r\n" +
196 "Content-Length: 10\r\n" +
197 "\r\n" +
198 "This is the content of the file\n" +
199 "\r\n" +
200 "-----1234\r\n" +
201 "Content-Disposition: form-data; name=\"file2\"; filename=\"foo2.tab\"\r\n" +
202 "Content-Type: text/whatever\r\n" +
203 "\r\n" +
204 "This is the content of the file\n" +
205 "\r\n" +
206 "-----1234--\r\n";
207
208 final ServletFileUpload upload = new ServletFileUpload(new DiskFileItemFactory());
209 upload.setFileSizeMax(-1);
210 upload.setSizeMax(200);
211
212 final MockHttpServletRequest req = new MockHttpServletRequest(request.getBytes("US-ASCII"), Constants.CONTENT_TYPE);
213 assertEquals(200, assertThrows(FileUploadBase.SizeLimitExceededException.class, () -> upload.parseRequest(req)).getPermittedSize());
214 }
215
216 @Test
217 public void testMaxSizeLimitUnknownContentLength()
218 throws IOException, FileUploadException {
219 final String request =
220 "-----1234\r\n" +
221 "Content-Disposition: form-data; name=\"file1\"; filename=\"foo1.tab\"\r\n" +
222 "Content-Type: text/whatever\r\n" +
223 "Content-Length: 10\r\n" +
224 "\r\n" +
225 "This is the content of the file\n" +
226 "\r\n" +
227 "-----1234\r\n" +
228 "Content-Disposition: form-data; name=\"file2\"; filename=\"foo2.tab\"\r\n" +
229 "Content-Type: text/whatever\r\n" +
230 "\r\n" +
231 "This is the content of the file\n" +
232 "\r\n" +
233 "-----1234--\r\n";
234
235 final ServletFileUpload upload = new ServletFileUpload(new DiskFileItemFactory());
236 upload.setFileSizeMax(-1);
237 upload.setSizeMax(300);
238
239
240
241
242
243 final MockHttpServletRequest req = new MockHttpServletRequest(
244 request.getBytes("US-ASCII"), Constants.CONTENT_TYPE);
245 req.setContentLength(-1);
246 req.setReadLimit(10);
247
248 final FileItemIterator it = upload.getItemIterator(req);
249 assertTrue(it.hasNext());
250
251 FileItemStream item = it.next();
252 assertFalse(item.isFormField());
253 assertEquals("file1", item.getFieldName());
254 assertEquals("foo1.tab", item.getName());
255
256 try (InputStream stream = item.openStream()) {
257 final ByteArrayOutputStream baos = new ByteArrayOutputStream();
258 Streams.copy(stream, baos, true);
259 }
260
261
262
263 assertDoesNotThrow(it::hasNext);
264
265 item = it.next();
266
267 try (InputStream stream = item.openStream()) {
268 final ByteArrayOutputStream baos = new ByteArrayOutputStream();
269 assertThrows(FileUploadIOException.class, () -> Streams.copy(stream, baos, true));
270 assertThrows(MalformedStreamException.class, stream::close);
271 } catch (final MalformedStreamException e) {
272
273 }
274 }
275
276
277
278 @Test
279 public void testPartHeaderSizeMaxLimit()
280 throws IOException, FileUploadException {
281 final String request =
282 "-----1234\r\n" +
283 "Content-Disposition: form-data; name=\"file1\"; filename=\"foo1.tab\"\r\n" +
284 "Content-Type: text/whatever\r\n" +
285 "Content-Length: 10\r\n" +
286 "\r\n" +
287 "This is the content of the file\n" +
288 "\r\n" +
289 "-----1234\r\n" +
290 "Content-Disposition: form-data; name=\"file2\"; filename=\"foo2.tab\"\r\n" +
291 "Content-Type: text/whatever\r\n" +
292 "\r\n" +
293 "This is the content of the file\n" +
294 "\r\n" +
295 "-----1234--\r\n";
296
297 final ServletFileUpload upload = new ServletFileUpload(new DiskFileItemFactory());
298 upload.setFileSizeMax(-1);
299 upload.setSizeMax(-1);
300 upload.setPartHeaderSizeMax(100);
301
302 final MockHttpServletRequest req = new MockHttpServletRequest(request.getBytes("US-ASCII"), Constants.CONTENT_TYPE);
303 assertEquals(100, assertThrows(FileUploadBase.SizeLimitExceededException.class, () -> upload.parseRequest(req)).getPermittedSize());
304 }
305 }