Name: dbT83986 Date: 02/17/99
------------------
When sending big amount of data to a OutputStream from a
URLConnection (POST method) in chunks of 5k (for example)
OutputStream does not flush, finishing with an OutOfMemory
Exception.
1. Exact steps to reproduce the problem
------------------------------------
a) Create a new URL object
b) Obtain its URLConnection
c) set doOutput and doInput to true
d) obtain URLConnection's output stream,
c) an try to send (write) big data in chunks of 5 k. with a loop
d) Try to flush inside the loop, unsuccessfully.
2. Java SOURCE CODE
----------------
import java.io.*;
import java.net.*;
class Prove extends Object
{
URL u = null; // URL of cgi that uploads the file
URLConnection urlCnx = null; // URLConnection of previous URL
FileInputStream fis = null; // File to send
String filename = "c:\\tmp\\comm404.exe"; // Size = 27 Mb !!
public Prove()
{
try {
u = new URL("http://150.1.1.15:8081/cgi-bin/upload.cgi");
System.out.println("URL = "+u);
fis = new FileInputStream(filename);
System.out.println("FIS = "+fis);
}catch(Exception e) {
System.err.println("ERROR in constructor:");
e.printStackTrace();
}
}
public void doUploadMultipart()
{
try {
urlCnx = u.openConnection(); // Get Connection
urlCnx.setDoInput(true); // RTS: read & write
urlCnx.setDoOutput(true); //
urlCnx.setUseCaches(false); // We doesn't want cache
urlCnx.setRequestProperty("Content-type","multipart/form-data; boundary=sendfile");
}
catch(Exception e)
{
System.err.println("Error: "+e+"\n");
}
// Now, send the parameters (the file)
try {
DataOutputStream printout = new DataOutputStream (urlCnx.getOutputStream());
writeMultipart(printout);
printout.close(); // Here is were it really flushes
}catch(IOException e) {
System.err.println("Error IOException: "+e.getMessage()+"\n");
e.printStackTrace();
}
// We don't reach here, because Exception inside in writeMultipart()
try
{
// Read the result (OK, BAD,...)
InputStream is = urlCnx.getInputStream();
BufferedReader d = new BufferedReader(new InputStreamReader(is));
String result = d.readLine();
System.out.println("Result = "+result);
}
catch(Exception e)
{
System.err.println(e);
e.printStackTrace();
}
}
protected void writeMultipart(DataOutputStream os)
{
try {
// Write headers
printBoundaryBegin(os);
printMPFieldName(os,"file1");
printMPFileName(os,filename);
printDoubleReturn(os);
}catch(IOException error) {
System.err.println("ERROR: Writing header Multipart");
System.err.println("MSG = "+error.getMessage());
System.err.println("E = "+error);
error.printStackTrace();
}
// Send the file content
int got;
byte [] buffer=new byte[1024*5]; // We alloc 5 kb buffer
try {
while((got=fis.read(buffer)) > 0) // While data is available, read ...
{
os.write(buffer,0,got); // ... then write
//***************** T H E P R O B L E M ****************
os.flush(); // ... AND FLUSH (DOES NOT WORK!!!)
//***************** T H E P R O B L E M ****************
}
}catch(IOException error){
System.err.println("ERROR reading & writing file");
System.err.println("MSG = "+error.getMessage());
System.err.println("E = "+error);
error.printStackTrace();
}
try {
// Imprime fin de boundary y cierra conexion
printBoundaryEnd(os);
os.flush();
}catch(IOException error) {
System.err.println("ERROR Writing end of boundary");
System.err.println("MSG = "+error.getMessage());
System.err.println("E = "+error);
error.printStackTrace();
}
}
protected void printBoundaryBegin(OutputStream os) throws IOException
{
os.write("--sendfile\r\n".getBytes());
os.flush();
}
protected void printBoundaryEnd(OutputStream os) throws IOException
{
os.write("\r\n--sendfile--\r\n".getBytes());
os.flush();
}
protected void printMPFieldName(OutputStream os,String fieldname) throws IOException
{
os.write(("Content-Disposition: form-data; name=\""+fieldname+"\"").getBytes());
os.flush();
}
protected void printMPFileName(OutputStream os, String filename) throws IOException
{
os.write(("; filename=\""+filename+"\"").getBytes());
os.flush();
}
protected void printDoubleReturn(OutputStream os) throws IOException
{
os.write("\r\n\r\n".getBytes());
os.flush();
}
public static void main(String argv[])
{
Prove p = new Prove();
p.doUploadMultipart();
}
}
3. Text Error Message
------------------
java.lang.OutOfMemoryError:
4. Trace info
----------
java.lang.OutOfMemoryError:
at java.io.ByteArrayOutputStream.write(ByteArrayOutputStream.java:95)
at java.io.DataOutputStream.write(DataOutputStream.java:83)
at Prove.writeMultipart(Prove.java:92)
at Prove.doUploadMultipart(Prove.java:47)
at Prove.main(Prove.java:151)
5. java -fullversion
-----------------
java full version "JDK1.1.6N"
6. Note
----
a) I have replaced the DataOutputStream with an BufferedOutputStream
with the same results.
b) CGI's hangs because header content-length noticed it to
send more bytes than it really can obtain. So, it hangs
waiting for read more bytes at fread in stdin.
(Review ID: 54262)
======================================================================
- relates to
-
JDK-5026745 Cannot flush output stream when writing to an HttpUrlConnection
- Resolved