I finally got out from under some work and was able to make some test code. I'm attaching the client and servlet code. The code transfers a couple parameters, then a binary file (I was using a .jar). If you call the client with "BinTestClient localhost something.jar b", it uses byte-by-byte read on the server to spool the file to a temp file. If you call the client without the 'b', it uses the byte-array read that I was complaining about. Transfer a file, then try "jar tvf testXXXX.jar" to see if it works. I uses a jar that contains .jpg images and when using the byte array read method, it creats a corrupt jar file. If I apply my fix to the Ajp13ConnectorRequest class, it works fine. (I tried a jar that contained class files and it worked anyway...) I'd like for someone else to try this out to make sure I didn't screw something up. The code seems pretty simple. I discovered this when using JarIn/OutputStream to transfer data from client to servlet. David
import java.io.DataOutputStream; import java.io.File; import java.io.FileInputStream; import java.io.InputStream; import java.io.OutputStream; import java.net.URL; import java.net.URLConnection; // args[0] = hostname // args[1] = jarfile // args[2] = 'b' for single byte read. public class BinTestClient { public static void main(String [] args) { try { URL url = new URL("http://"+args[0]+"/examples/BinTest"); URLConnection connection = (URLConnection)url.openConnection(); connection.setDoOutput(true); connection.setUseCaches(false); DataOutputStream output = new DataOutputStream(connection.getOutputStream()); File jarFile = new File(args[1]); if (jarFile.exists()) { output.writeUTF(""+jarFile.length()); } if (args.length > 2 && args[2] != null && args[2].trim().equals("b")) output.writeChar('b'); else output.writeChar(' '); InputStream istr = new FileInputStream(jarFile); byte [] buf = new byte[8192]; int count = istr.read(buf); while (count != -1) { if (count > 0) output.write(buf, 0, count); count = istr.read(buf); } istr.close(); output.flush(); output.close(); istr = connection.getInputStream(); istr.read(); } catch (Exception ex) { ex.printStackTrace(); } } }
import java.io.DataInputStream; import java.io.File; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.InputStream; import java.io.IOException; import java.io.OutputStream; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; public class BinTestServlet extends HttpServlet{ public void doPost (HttpServletRequest request, HttpServletResponse response) { try { DataInputStream istr = new DataInputStream(request.getInputStream()); long fileLen = Long.parseLong(istr.readUTF()); char mode = istr.readChar(); File tmp = File.createTempFile("test", ".jar"); OutputStream fstr = new FileOutputStream(tmp); if (mode == 'b') { System.out.println("Using byte-by-byte read"); for (int i=0; i<fileLen; i++) fstr.write(istr.read()); } else { System.out.println("Using byte-array read"); byte [] buf = new byte[8192]; int count = istr.read(buf); while (count != -1) { if (count > 0) fstr.write(buf, 0, count); count = istr.read(buf); } } fstr.flush(); fstr.close(); OutputStream ostr = response.getOutputStream(); ostr.write(1); // positive response } catch (Exception ex) { ex.printStackTrace(); } } }