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 java.io.ByteArrayInputStream;
20 import java.io.ByteArrayOutputStream;
21 import java.io.FilterInputStream;
22 import java.io.IOException;
23 import java.io.InputStream;
24 import java.io.OutputStreamWriter;
25 import java.util.Iterator;
26 import java.util.List;
27 import javax.servlet.http.HttpServletRequest;
28
29 import org.apache.commons.fileupload.FileUploadBase.IOFileUploadException;
30 import org.apache.commons.fileupload.disk.DiskFileItemFactory;
31 import org.apache.commons.fileupload.servlet.ServletFileUpload;
32 import org.apache.commons.fileupload.servlet.ServletRequestContext;
33
34 import junit.framework.TestCase;
35
36
37
38
39 public class StreamingTest extends TestCase {
40
41
42
43
44 public void testFileUpload()
45 throws IOException, FileUploadException {
46 byte[] request = newRequest();
47 List<FileItem> fileItems = parseUpload(request);
48 Iterator<FileItem> fileIter = fileItems.iterator();
49 int add = 16;
50 int num = 0;
51 for (int i = 0; i < 16384; i += add) {
52 if (++add == 32) {
53 add = 16;
54 }
55 FileItem item = fileIter.next();
56 assertEquals("field" + (num++), item.getFieldName());
57 byte[] bytes = item.get();
58 assertEquals(i, bytes.length);
59 for (int j = 0; j < i; j++) {
60 assertEquals((byte) j, bytes[j]);
61 }
62 }
63 assertTrue(!fileIter.hasNext());
64 }
65
66
67
68
69
70 public void testFileUploadException()
71 throws IOException, FileUploadException {
72 byte[] request = newRequest();
73 byte[] invalidRequest = new byte[request.length-11];
74 System.arraycopy(request, 0, invalidRequest, 0, request.length-11);
75 try {
76 parseUpload(invalidRequest);
77 fail("Expected EndOfStreamException");
78 } catch (IOFileUploadException e) {
79 assertTrue(e.getCause() instanceof MultipartStream.MalformedStreamException);
80 }
81 }
82
83
84
85
86 public void testIOException()
87 throws IOException {
88 byte[] request = newRequest();
89 InputStream stream = new FilterInputStream(new ByteArrayInputStream(request)){
90 private int num;
91 @Override
92 public int read() throws IOException {
93 if (++num > 123) {
94 throw new IOException("123");
95 }
96 return super.read();
97 }
98 @Override
99 public int read(byte[] pB, int pOff, int pLen)
100 throws IOException {
101 for (int i = 0; i < pLen; i++) {
102 int res = read();
103 if (res == -1) {
104 return i == 0 ? -1 : i;
105 }
106 pB[pOff+i] = (byte) res;
107 }
108 return pLen;
109 }
110 };
111 try {
112 parseUpload(stream, request.length);
113 fail("Expected IOException");
114 } catch (FileUploadException e) {
115 assertTrue(e.getCause() instanceof IOException);
116 assertEquals("123", e.getCause().getMessage());
117 }
118 }
119
120
121
122
123 public void testFILEUPLOAD135()
124 throws IOException, FileUploadException {
125 byte[] request = newShortRequest();
126 final ByteArrayInputStream bais = new ByteArrayInputStream(request);
127 List<FileItem> fileItems = parseUpload(new InputStream() {
128 @Override
129 public int read()
130 throws IOException
131 {
132 return bais.read();
133 }
134 @Override
135 public int read(byte b[], int off, int len) throws IOException
136 {
137 return bais.read(b, off, Math.min(len, 3));
138 }
139
140 }, request.length);
141 Iterator<FileItem> fileIter = fileItems.iterator();
142 assertTrue(fileIter.hasNext());
143 FileItem item = fileIter.next();
144 assertEquals("field", item.getFieldName());
145 byte[] bytes = item.get();
146 assertEquals(3, bytes.length);
147 assertEquals((byte)'1', bytes[0]);
148 assertEquals((byte)'2', bytes[1]);
149 assertEquals((byte)'3', bytes[2]);
150 assertTrue(!fileIter.hasNext());
151 }
152
153 private List<FileItem> parseUpload(byte[] bytes) throws FileUploadException {
154 return parseUpload(new ByteArrayInputStream(bytes), bytes.length);
155 }
156
157 private FileItemIterator parseUpload(int pLength, InputStream pStream)
158 throws FileUploadException, IOException {
159 String contentType = "multipart/form-data; boundary=---1234";
160
161 FileUploadBase upload = new ServletFileUpload();
162 upload.setFileItemFactory(new DiskFileItemFactory());
163 HttpServletRequest request = new MockHttpServletRequest(pStream,
164 pLength, contentType);
165
166 return upload.getItemIterator(new ServletRequestContext(request));
167 }
168
169 private List<FileItem> parseUpload(InputStream pStream, int pLength)
170 throws FileUploadException {
171 String contentType = "multipart/form-data; boundary=---1234";
172
173 FileUploadBase upload = new ServletFileUpload();
174 upload.setFileItemFactory(new DiskFileItemFactory());
175 HttpServletRequest request = new MockHttpServletRequest(pStream,
176 pLength, contentType);
177
178 List<FileItem> fileItems = upload.parseRequest(new ServletRequestContext(request));
179 return fileItems;
180 }
181
182 private String getHeader(String pField) {
183 return "-----1234\r\n"
184 + "Content-Disposition: form-data; name=\"" + pField + "\"\r\n"
185 + "\r\n";
186
187 }
188
189 private String getFooter() {
190 return "-----1234--\r\n";
191 }
192
193 private byte[] newShortRequest() throws IOException {
194 final ByteArrayOutputStream baos = new ByteArrayOutputStream();
195 final OutputStreamWriter osw = new OutputStreamWriter(baos, "US-ASCII");
196 osw.write(getHeader("field"));
197 osw.write("123");
198 osw.write("\r\n");
199 osw.write(getFooter());
200 osw.close();
201 return baos.toByteArray();
202 }
203
204 private byte[] newRequest() throws IOException {
205 final ByteArrayOutputStream baos = new ByteArrayOutputStream();
206 final OutputStreamWriter osw = new OutputStreamWriter(baos, "US-ASCII");
207 int add = 16;
208 int num = 0;
209 for (int i = 0; i < 16384; i += add) {
210 if (++add == 32) {
211 add = 16;
212 }
213 osw.write(getHeader("field" + (num++)));
214 osw.flush();
215 for (int j = 0; j < i; j++) {
216 baos.write((byte) j);
217 }
218 osw.write("\r\n");
219 }
220 osw.write(getFooter());
221 osw.close();
222 return baos.toByteArray();
223 }
224
225
226
227
228 public void testInvalidFileNameException() throws Exception {
229 final String fileName = "foo.exe\u0000.png";
230 final String request =
231 "-----1234\r\n" +
232 "Content-Disposition: form-data; name=\"file\"; filename=\"" + fileName + "\"\r\n" +
233 "Content-Type: text/whatever\r\n" +
234 "\r\n" +
235 "This is the content of the file\n" +
236 "\r\n" +
237 "-----1234\r\n" +
238 "Content-Disposition: form-data; name=\"field\"\r\n" +
239 "\r\n" +
240 "fieldValue\r\n" +
241 "-----1234\r\n" +
242 "Content-Disposition: form-data; name=\"multi\"\r\n" +
243 "\r\n" +
244 "value1\r\n" +
245 "-----1234\r\n" +
246 "Content-Disposition: form-data; name=\"multi\"\r\n" +
247 "\r\n" +
248 "value2\r\n" +
249 "-----1234--\r\n";
250 final byte[] reqBytes = request.getBytes("US-ASCII");
251
252 FileItemIterator fileItemIter = parseUpload(reqBytes.length, new ByteArrayInputStream(reqBytes));
253 final FileItemStream fileItemStream = fileItemIter.next();
254 try {
255 fileItemStream.getName();
256 fail("Expected exception");
257 } catch (InvalidFileNameException e) {
258 assertEquals(fileName, e.getName());
259 assertTrue(e.getMessage().indexOf(fileName) == -1);
260 assertTrue(e.getMessage().indexOf("foo.exe\\0.png") != -1);
261 }
262
263 List<FileItem> fileItems = parseUpload(reqBytes);
264 final FileItem fileItem = fileItems.get(0);
265 try {
266 fileItem.getName();
267 fail("Expected exception");
268 } catch (InvalidFileNameException e) {
269 assertEquals(fileName, e.getName());
270 assertTrue(e.getMessage().indexOf(fileName) == -1);
271 assertTrue(e.getMessage().indexOf("foo.exe\\0.png") != -1);
272 }
273 }
274
275 }