This is the mail archive of the java-patches@gcc.gnu.org mailing list for the Java project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

FYI: Patch: http connection


Hi list,


I commited the attached patch to add HeaderFieldHelper and use it in 
gnu.java.net.protocol.java.Connection.


Michael
Index: ChangeLog
===================================================================
RCS file: /cvs/gcc/gcc/libjava/ChangeLog,v
retrieving revision 1.2496
diff -u -b -B -r1.2496 ChangeLog
--- ChangeLog	28 Dec 2003 11:54:17 -0000	1.2496
+++ ChangeLog	28 Dec 2003 21:28:48 -0000
@@ -1,3 +1,23 @@
+2003-12-28  Michael Koch  <konqueror@gmx.de>
+
+	* gnu/java/net/protocol/http/Connection.java
+	(inputStream): Made it a DataInputStream.
+	(requestProperties): Removed.
+	(hdrHash): Removed.
+	(hdrVec): Removed.
+	(headers): New field to store headers.
+	(connect): Initialize inputStream.
+	(receiveReply): Merged from classpath. The new algorithm is line based
+	instead of character based.
+	(getHeaderField): Use headers.
+	(getHeaderFields): Use headers.
+	(getKey): Removed.
+	(getField): Removed.
+	* gnu/java/net/HeaderFieldHelper.java: New file.
+	* Makefile.am (ordinary_java_source_files):
+	Added gnu/java/net/HeaderFieldHelper.java.
+	* Makefile.in: Regenerated.
+
 2003-12-28  Guilhem Lavaux <guilhem@kaffe.org>
 
 	* java/io/LineNumberReader.java
Index: Makefile.am
===================================================================
RCS file: /cvs/gcc/gcc/libjava/Makefile.am,v
retrieving revision 1.348
diff -u -b -B -r1.348 Makefile.am
--- Makefile.am	26 Dec 2003 16:25:57 -0000	1.348
+++ Makefile.am	28 Dec 2003 21:28:49 -0000
@@ -2238,6 +2238,7 @@
 gnu/java/locale/LocaleInformation_zh_SG.java \
 gnu/java/locale/LocaleInformation_zh_TW.java \
 gnu/java/math/MPN.java \
+gnu/java/net/HeaderFieldHelper.java \
 gnu/java/net/PlainDatagramSocketImpl.java \
 gnu/java/net/PlainSocketImpl.java \
 gnu/java/net/URLParseError.java \
Index: Makefile.in
===================================================================
RCS file: /cvs/gcc/gcc/libjava/Makefile.in,v
retrieving revision 1.372
diff -u -b -B -r1.372 Makefile.in
--- Makefile.in	26 Dec 2003 16:25:57 -0000	1.372
+++ Makefile.in	28 Dec 2003 21:28:51 -0000
@@ -1945,6 +1945,7 @@
 gnu/java/locale/LocaleInformation_zh_SG.java \
 gnu/java/locale/LocaleInformation_zh_TW.java \
 gnu/java/math/MPN.java \
+gnu/java/net/HeaderFieldHelper.java \
 gnu/java/net/PlainDatagramSocketImpl.java \
 gnu/java/net/PlainSocketImpl.java \
 gnu/java/net/URLParseError.java \
@@ -3085,7 +3086,8 @@
 .deps/gnu/java/locale/LocaleInformation_zh_HK.P \
 .deps/gnu/java/locale/LocaleInformation_zh_SG.P \
 .deps/gnu/java/locale/LocaleInformation_zh_TW.P \
-.deps/gnu/java/math/MPN.P .deps/gnu/java/net/PlainDatagramSocketImpl.P \
+.deps/gnu/java/math/MPN.P .deps/gnu/java/net/HeaderFieldHelper.P \
+.deps/gnu/java/net/PlainDatagramSocketImpl.P \
 .deps/gnu/java/net/PlainSocketImpl.P .deps/gnu/java/net/URLParseError.P \
 .deps/gnu/java/net/natPlainDatagramSocketImpl.P \
 .deps/gnu/java/net/natPlainSocketImpl.P \
Index: gnu/java/net/protocol/http/Connection.java
===================================================================
RCS file: /cvs/gcc/gcc/libjava/gnu/java/net/protocol/http/Connection.java,v
retrieving revision 1.9
diff -u -b -B -r1.9 Connection.java
--- gnu/java/net/protocol/http/Connection.java	27 Dec 2003 20:49:12 -0000	1.9
+++ gnu/java/net/protocol/http/Connection.java	28 Dec 2003 21:28:51 -0000
@@ -39,6 +39,7 @@
 package gnu.java.net.protocol.http;
 
 import java.io.BufferedInputStream;
+import java.io.DataInputStream;
 import java.io.InputStream;
 import java.io.IOException;
 import java.io.OutputStream;
@@ -50,8 +51,7 @@
 import java.net.URLConnection;
 import java.util.Iterator;
 import java.util.Map;
-import java.util.Vector;
-import java.util.Hashtable;
+import gnu.java.net.HeaderFieldHelper;
 
 /**
  * This subclass of java.net.URLConnection models a URLConnection via
@@ -102,14 +102,12 @@
   /**
    * The InputStream for this connection.
    */
-  private BufferedInputStream inputStream;
+  private DataInputStream inputStream;
 
   /**
    * This is the object that holds the header field information
    */
-  private Hashtable requestProperties = new Hashtable();
-  private Hashtable hdrHash = new Hashtable();
-  private Vector hdrVec = new Vector();
+  private HeaderFieldHelper headers = new HeaderFieldHelper();
 
   /**
    * Calls superclass constructor to initialize
@@ -147,13 +145,8 @@
 	socket = new Socket(url.getHost(), port);
       }
 
-    // Originally tried using a BufferedReader here to take advantage of
-    // the readLine method and avoid the following, but the buffer read
-    // past the end of the headers so the first part of the content was lost.
-    // It is probably more robust than it needs to be, e.g. the byte[]
-    // is unlikely to overflow and a '\r' should always be followed by a '\n',
-    // but it is better to be safe just in case.
-    inputStream = new BufferedInputStream(socket.getInputStream());
+    inputStream =
+      new DataInputStream(new BufferedInputStream(socket.getInputStream()));
 
     sendRequest();
     receiveReply();
@@ -215,54 +208,94 @@
    */
   private void receiveReply() throws IOException
   {
-    int buflen = 100;
-    byte[] buf = new byte[buflen];
-    String line = "";
-    boolean gotnl = false;
-    byte[] ch = new byte[1];
-    ch[0] = (byte) '\n';
+    // Parse the reply
+    String line = inputStream.readLine();
+    String saveline = line;
+    int idx = line.indexOf (" ");
+
+    if ((idx == -1)
+        || (line.length() < (idx + 6)))
+      throw new IOException ("Server reply was unparseable: " + saveline);
 
-    while (true)
+    headers.addHeaderField (null, line);
+
+    line = line.substring (idx + 1);
+    String code = line.substring (0, 3);
+    
+    try
       {
-	// Check for leftover byte from non-'\n' after a '\r'.
-	if (ch[0] != '\n')
-	  line = line + '\r' + new String(ch, 0, 1);
-
-	int i;
-	// FIXME: This is rather inefficient.
-	for (i = 0; i < buflen; i++)
-	  {
-	    buf[i] = (byte) inputStream.read();
-	    if (buf[i] == -1)
-	      throw new IOException("Malformed HTTP header");
-	    if (buf[i] == '\r')
-	      {
-	        inputStream.read(ch, 0, 1);
-		if (ch[0] == '\n')
-		  gotnl = true;
-		break;
+        responseCode = Integer.parseInt (code);
 	      }
+    catch (NumberFormatException e)
+      {
+        throw new IOException ("Server reply was unparseable: " + saveline);
 	  }
-	line = line + new String(buf, 0, i);
 
-	// A '\r' '\n' combo indicates the end of the header entry.
-	// If it wasn't found, cycle back through the loop and append
-	// to 'line' until one is found.
-	if (gotnl)
+    responseMessage = line.substring (4);
+
+    // Now read the header lines
+    String key = null, value = null;
+    
+    while (true)
 	  {
-	    // A zero length entry signals the end of the headers.
-	    if (line.length() == 0)
+        line = inputStream.readLine();
+        
+        if (line.equals(""))
 	      break;
 
-	    // Store the header and reinitialize for next cycle.
-	    hdrVec.addElement(line);
-	    String key = getKey(line);
+        // Check for folded lines
+        if (line.startsWith (" ")
+            || line.startsWith("\t"))
+          {
+            // Trim off leading space
+            do
+              {
+                if (line.length() == 1)
+                  throw new IOException("Server header lines were unparseable: "
+                                        + line);
+
+                line = line.substring (1);
+              }
+            while (line.startsWith(" ")
+                   || line.startsWith("\t"));
+
+            value = value + " " + line;
+          }
+        else 
+          {
 	    if (key != null)
-	      hdrHash.put(key.toLowerCase(), getField(line));
-	    line = "";
-	    ch[0] = (byte) '\n';
-	    gotnl = false;
+              {
+                headers.addHeaderField (key.toLowerCase(), value);
+                key = null;
+                value = null;
+              }
+
+            // Parse out key and value
+            idx = line.indexOf (":");
+            if ((idx == -1)
+                || (line.length() < (idx + 2)))
+              throw new IOException ("Server header lines were unparseable: "
+                                     + line);
+
+            key = line.substring (0, idx);
+            value = line.substring (idx + 1);
+
+            // Trim off leading space
+            while (value.startsWith (" ")
+                   || value.startsWith ("\t"))
+              {
+                if (value.length() == 1)
+                  throw new IOException ("Server header lines were unparseable: "
+                                         + line);
+
+                value = value.substring (1);
+              }
+          }
 	  }
+    
+    if (key != null)
+      {
+        headers.addHeaderField (key.toLowerCase(), value.toLowerCase());
       }
   }
 
@@ -347,7 +380,7 @@
 	  return null;
 	}
 
-    return (String) hdrHash.get(name.toLowerCase());
+    return (String) headers.getHeaderFieldValueByKey(name.toLowerCase());
   }
 
   public Map getHeaderFields()
@@ -362,7 +395,7 @@
 	  return null;
 	}
 
-    return hdrHash;
+    return headers.getHeaderFields();
   }
 
   /**
@@ -386,9 +419,7 @@
 	  return null;
 	}
 
-    if (n < hdrVec.size())
-      return getField ((String) hdrVec.elementAt(n));
-    return null;
+    return headers.getHeaderFieldValueByIndex (n);
   }
 
   /**
@@ -412,30 +443,6 @@
 	  return null;
 	}
 
-    if (n < hdrVec.size())
-      return getKey ((String) hdrVec.elementAt(n));
-    return null;
-  }
-
-  private String getKey(String str)
-  {
-    if (str == null)
-      return null;
-    int index = str.indexOf(':');
-    if (index >= 0)
-      return str.substring(0, index);
-    else
-      return null;
-  }
-
-  private String getField(String str)
-  {
-    if (str == null)
-      return null;
-    int index = str.indexOf(':');
-    if (index >= 0)
-      return str.substring(index + 1).trim();
-    else
-      return str;
+    return headers.getHeaderFieldKeyByIndex (n);
   }
 }
Index: gnu/java/net/HeaderFieldHelper.java
===================================================================
RCS file: gnu/java/net/HeaderFieldHelper.java
diff -N gnu/java/net/HeaderFieldHelper.java
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ gnu/java/net/HeaderFieldHelper.java	28 Dec 2003 21:28:51 -0000
@@ -0,0 +1,138 @@
+/* HeaderFieldHelper.java -- Helps manage headers fields 
+   Copyright (C) 1998, 2003 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+ 
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING.  If not, write to the
+Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+02111-1307 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library.  Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module.  An independent module is a module which is not derived from
+or based on this library.  If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so.  If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package gnu.java.net;
+
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Vector;
+
+/**
+ * This class manages header field keys and values.
+ *
+ * @author Aaron M. Renn <arenn@urbanophile.com>
+ */
+public class HeaderFieldHelper
+{
+  private Vector headerFieldKeys;
+  private Vector headerFieldValues;
+
+  public HeaderFieldHelper()
+  {
+    this (10);
+  }
+
+  public HeaderFieldHelper (int size)
+  {
+    headerFieldKeys = new Vector (size);
+    headerFieldValues = new Vector (size);
+  }
+
+  public void addHeaderField (String key, String value)
+  {
+    headerFieldKeys.addElement (key);
+    headerFieldValues.addElement (value);
+  }
+
+  public String getHeaderFieldKeyByIndex (int index)
+  {
+    String key = null;
+
+    try
+      {
+        key = (String) headerFieldKeys.elementAt (index);
+      }
+    catch (ArrayIndexOutOfBoundsException e)
+      {
+      }
+
+    return key;
+  }
+
+  public String getHeaderFieldValueByIndex(int index)
+  {
+    String value = null;
+
+    try
+      {
+        value = (String) headerFieldValues.elementAt (index);
+      }
+    catch (ArrayIndexOutOfBoundsException e)
+      {
+      }
+
+    return value;
+  }
+
+  public String getHeaderFieldValueByKey(String key)
+  {
+    String value = null;
+
+    try
+      {
+	value = (String) headerFieldValues.elementAt
+			   (headerFieldKeys.indexOf(key));
+      }
+    catch (ArrayIndexOutOfBoundsException e)
+      {
+      }
+    
+    return value;
+  }
+
+  public Map getHeaderFields()
+  {
+    HashMap headers = new HashMap();
+    int max = headerFieldKeys.size();
+
+    for (int index = 0; index < max; index++)
+      {
+	headers.put(headerFieldKeys.elementAt(index),
+		    headerFieldValues.elementAt(index));
+      }
+
+    return headers;
+  }
+
+  public int getNumberOfEntries()
+  {
+    return headerFieldKeys.size();
+  }
+
+} // class HeaderFieldHelper
+

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]