[kaffe] fixes to HttpURLConnection, etc

Ito Kazumitsu ito.kazumitsu@hitachi-cable.co.jp
Thu May 8 04:43:01 2003


While testing HSQLDB Web Server
(http://hsqldb.sourceforge.net/doc/hsqlGuide.html), I found
that kaffe's HttpURLConnection did not work properly.

  - As soon as java.net.URL.openConnection() opens a HttpURLConnection,
    it calls connect(),  without giving the user time for setting
    HttpURLConnection options.

  - Kaffe's HttpURLConnection does not support getOutputStream().

and here are my patches.

--- java/net/URL.java.orig	Tue Apr 16 00:09:39 2002
+++ java/net/URL.java	Thu May  8 20:11:42 2003
@@ -229,7 +229,17 @@
 	// We *ALWAYS* open a new connection even if we already have
 	// one open.
 	conn = handler.openConnection(this);
-	conn.connect();
+	if (protocol.equals("http")) {
+		// It is too early to do connect() here. connect() should be
+		// called when really needed.
+	}
+	else {
+		// As for protocols other than "http", connect() should be
+		// called when really needed,  but in reality,  not calling
+		// connect() here may cause some problem.  For example,
+		// not connected JarURLConnection is a dangerous thing.
+		conn.connect();
+	}
 	return (conn);
 }
 
--- kaffe/net/www/protocol/http/HttpURLConnection.java.orig	Fri Oct 25 17:22:42 2002
+++ kaffe/net/www/protocol/http/HttpURLConnection.java	Thu May  8 20:36:06 2003
@@ -13,9 +13,13 @@
 
 import java.io.IOException;
 import java.io.InputStream;
+import java.io.OutputStream;
 import java.io.DataOutputStream;
 import java.io.DataInputStream;
 import java.io.BufferedInputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
 import java.util.Vector;
 import java.net.URL;
 import java.net.Socket;
@@ -34,6 +38,8 @@
 private Socket sock;
 private InputStream in;
 private DataOutputStream out;
+private File tmpFile;
+private OutputStream tmpOut;
 private boolean redir = getFollowRedirects();
 
 static {
@@ -64,9 +70,14 @@
 
 public HttpURLConnection(URL url) {
 	super(url);
+	connected = false;
 }
 
 public void connect() throws IOException {
+	if(connected) return;
+	connected = true;
+
+	if (tmpOut != null) tmpOut.close();
 	for (;;) {
 	    	// reset response data
 		responseCode = -1;
@@ -111,6 +122,7 @@
 				file = "/";
 			}
 		}
+		if (doOutput) method = "POST";
 		// HTTP/1.0 request line
 		out.writeBytes(method + " " + file + " HTTP/1.0\r\n");
 		// HTTP/1.1 Host header field, required for virtual server name
@@ -121,9 +133,27 @@
 		else {
 			out.writeBytes("Host: " + url.getHost() + ":" + port + "\r\n");
 		}
+		if(doOutput) {
+			long l = (tmpFile != null ? tmpFile.length() : 0L);
+			out.writeBytes("Content-Length: " + l + "\r\n");
+		}
 		// TODO: emit all RequestHeaders see setRequestProperty
 		// header end
 		out.writeBytes("\r\n");
+		if(doOutput) {
+			if (tmpFile != null) {
+				InputStream tmpIn = new FileInputStream(
+					tmpFile);
+				byte[] buf = new byte[4096];
+				while (true) {
+					int l = tmpIn.read(buf, 0, buf.length);
+					if (l < 0) break;
+					out.write(buf,0,l);
+				}
+				tmpIn.close();
+				tmpFile.delete();
+			}
+		}
 		out.flush();
 
 		DataInputStream inp = new DataInputStream(in);
@@ -190,11 +220,36 @@
 	}
 }
 
+private void doConnect() throws IOException {
+	if (!connected) connect();
+}
+
+private void tryConnect() {
+	if (!connected) {
+		try {
+			connect();
+		}
+		catch (IOException e) {
+			//  I don't know what to do
+		}
+	}
+}
+
 public InputStream getInputStream() throws IOException {
+	doConnect();
 	return (in);
 }
 
+public OutputStream getOutputStream() throws IOException {
+	if (tmpOut != null) return tmpOut;
+	tmpFile = File.createTempFile("POST",".tmp");
+	tmpFile.deleteOnExit();
+	tmpOut = new FileOutputStream(tmpFile);
+	return tmpOut;
+}
+
 public String getHeaderField(String name) {
+	tryConnect();
 	// Ignore field 0, it's the Status-Line
 	for (int i = headerFields.size() - 2; i > 0; i -= 2) {
 		if (((String)headerFields.elementAt(i)).equalsIgnoreCase(name)) {
@@ -205,6 +260,7 @@
 }
 
 public String getHeaderField(int pos) {
+	tryConnect();
 	if (pos < 0 || pos >= (headerFields.size() >> 1)) {
 		return (null);
 	}
@@ -212,6 +268,7 @@
 }
 
 public String getHeaderFieldKey(int pos) {
+	tryConnect();
 	if (pos < 0 || pos >= (headerFields.size() >> 1)) {
 		return (null);
 	}
@@ -232,6 +289,7 @@
 }
 
 public Object getContent() throws IOException {
+	tryConnect();
     	String ct = getContentType();
 	if (ct == null) {
 		return (in);