> -----BEGIN PGP SIGNED MESSAGE-----
> Hash: SHA1
>
> Brian,
>
> On 10/4/2010 11:43 AM, Brian Pontarelli wrote:
>> I figured that the original File and the File written out by the
>> FileUpload would have different bytes at the start or end and it was
>> my mock input stream that was causing the issue. To test this theory
>> I opened both files in a HEX editor. What I found was that the files
>> differ by one a single byte and that byte is at position 305. The
>> other interesting thing I found was that the byte that exists in the
>> original and is missing from the FileUpload file is 'FF'.
>
> That's weird. Is the missing byte always at position 305? What variety
> of "test" files have you tried? Is it always 0xff that gets discarded?
>
> Could you post some of your test driver code, and some of the servlet
> code so we can see how they interact?
I'm back from my travels and wanted to circle back on this thread. There is
quite a bit of code for all of this stuff, but I'll post some of it. I'm going
to post the code we use to create the multipart request and some unit test code
we use to test it all:
public class MultipartInputStream extends ServletInputStream {
public static final byte[] BOUNDARY =
getBytes("--jcatapultmultipartuploadLKAlskld09309djoid");
public static final byte[] CLOSE_BOUNDARY = getBytes("--");
public static final byte[] CRLF = getBytes("\r\n");
public static final byte[] CONTENT_DISPOSITION =
getBytes("Content-Disposition: form-data; name=");
public static final byte[] CONTENT_TYPE = getBytes("Content-Type: ");
public static final byte[] CONTENT_TRANSFER_ENCODING =
getBytes("Content-Transfer-Encoding: binary");
public static final byte[] FILENAME = getBytes("; filename=");
public static final byte[] QUOTE = getBytes("\"");
private final byte[] bytes;
private int index = 0;
public MultipartInputStream(Map<String, List<String>> parameters,
Map<String, FileInfo> files) throws IOException {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
for (String key : parameters.keySet()) {
List<String> values = parameters.get(key);
for (String value : values) {
baos.write(BOUNDARY);
baos.write(CRLF);
// Content disposition header
baos.write(CONTENT_DISPOSITION);
baos.write(QUOTE);
baos.write(getBytes(key));
baos.write(QUOTE);
// Header end
baos.write(CRLF);
baos.write(CRLF);
// Data
baos.write(getBytes(value));
// End
baos.write(CRLF);
}
}
for (String key : files.keySet()) {
FileInfo file = files.get(key);
// Boundary
baos.write(BOUNDARY);
baos.write(CRLF);
// Content disposition header
baos.write(CONTENT_DISPOSITION);
baos.write(QUOTE);
baos.write(getBytes(key));
baos.write(QUOTE);
baos.write(FILENAME);
baos.write(QUOTE);
baos.write(getBytes(file.file.getName()));
baos.write(QUOTE);
// Content type header
baos.write(CRLF);
baos.write(CONTENT_TYPE);
baos.write(getBytes(file.contentType));
// Content transfer encoding header
baos.write(CRLF);
baos.write(CONTENT_TRANSFER_ENCODING);
// Header end
baos.write(CRLF);
baos.write(CRLF);
// Data
byte[] ba = new byte[4096];
InputStream is = new FileInputStream(file.file);
int len;
while ((len = is.read(ba)) != -1) {
baos.write(ba, 0, len);
}
is.close();
// End
baos.write(CRLF);
}
baos.write(BOUNDARY);
baos.write(CLOSE_BOUNDARY);
baos.write(CRLF);
baos.flush();
bytes = baos.toByteArray();
}
@Override
public int available() throws IOException {
return bytes.length;
}
public int read() throws IOException {
if (index == bytes.length) {
return -1;
}
return bytes[index++];
}
private static byte[] getBytes(String str) {
try {
return str.getBytes("US-ASCII");
} catch (UnsupportedEncodingException e) {
throw new RuntimeException(e);
}
}
}
public class FileInfo {
public final File file;
public final String name;
public final String contentType;
public FileInfo(File file, String name, String contentType) {
this.file = file;
this.name = name;
this.contentType = contentType;
}
public File getFile() {
return file;
}
public String getName() {
return name;
}
public String getContentType() {
return contentType;
}
}
Unit test code:
@Test
public void multipartJARFile() throws Exception {
MockHttpServletRequest request = new MockHttpServletRequest("/foo", new
MockServletContext());
request.addFile("file", new
File("src/java/test/unit/org/jcatapult/servlet/test.jar"),
"application/java-archive");
request.setParameter("test", "test");
FileItemFactory factory = new DiskFileItemFactory();
ServletFileUpload upload = new ServletFileUpload(factory);
List<FileItem> items = upload.parseRequest(request);
assertEquals(2, items.size());
assertTrue(items.get(0).isFormField());
assertEquals(items.get(0).getFieldName(), "test");
assertEquals(items.get(0).getString(), "test");
assertFalse(items.get(1).isFormField());
assertEquals(items.get(1).getFieldName(), "file");
assertEquals(items.get(1).getName(), "test.jar");
assertEquals(items.get(1).getContentType(), "application/java-archive");
File file = File.createTempFile("fileuploadtest", ".jar");
items.get(1).write(file);
byte[] orig = read(new
File("src/java/test/unit/org/jcatapult/servlet/test.jar"));
byte[] read = read(file);
assertEquals(orig.length, read.length);
for (int i = 0; i < orig.length; i++) {
assertEquals("Byte at index " + i + " was invalid", orig[i], read[i]);
}
}
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]