summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--libjava/ChangeLog20
-rw-r--r--libjava/Makefile.am1
-rw-r--r--libjava/Makefile.in4
-rw-r--r--libjava/gnu/java/net/HeaderFieldHelper.java138
-rw-r--r--libjava/gnu/java/net/protocol/http/Connection.java183
5 files changed, 257 insertions, 89 deletions
diff --git a/libjava/ChangeLog b/libjava/ChangeLog
index 493c3bb3407..a0d172557ae 100644
--- a/libjava/ChangeLog
+++ b/libjava/ChangeLog
@@ -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
diff --git a/libjava/Makefile.am b/libjava/Makefile.am
index fd72074b138..70c9cb52a2e 100644
--- a/libjava/Makefile.am
+++ b/libjava/Makefile.am
@@ -2238,6 +2238,7 @@ gnu/java/locale/LocaleInformation_zh_HK.java \
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 \
diff --git a/libjava/Makefile.in b/libjava/Makefile.in
index 4456250cbb2..9702b28a3ec 100644
--- a/libjava/Makefile.in
+++ b/libjava/Makefile.in
@@ -1945,6 +1945,7 @@ gnu/java/locale/LocaleInformation_zh_HK.java \
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 @@ DEP_FILES = .deps/$(srcdir)/$(CONVERT_DIR)/gen-from-JIS.P \
.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 \
diff --git a/libjava/gnu/java/net/HeaderFieldHelper.java b/libjava/gnu/java/net/HeaderFieldHelper.java
new file mode 100644
index 00000000000..2bcfd17fd7d
--- /dev/null
+++ b/libjava/gnu/java/net/HeaderFieldHelper.java
@@ -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
+
diff --git a/libjava/gnu/java/net/protocol/http/Connection.java b/libjava/gnu/java/net/protocol/http/Connection.java
index 677ba7f1e65..5cced5cf0a2 100644
--- a/libjava/gnu/java/net/protocol/http/Connection.java
+++ b/libjava/gnu/java/net/protocol/http/Connection.java
@@ -39,6 +39,7 @@ exception statement from your version. */
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.URL;
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 @@ public final class Connection extends HttpURLConnection
/**
* 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 @@ public final class Connection extends HttpURLConnection
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 @@ public final class Connection extends HttpURLConnection
*/
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 (" ");
- while (true)
- {
- // Check for leftover byte from non-'\n' after a '\r'.
- if (ch[0] != '\n')
- line = line + '\r' + new String(ch, 0, 1);
+ if ((idx == -1)
+ || (line.length() < (idx + 6)))
+ throw new IOException ("Server reply was unparseable: " + saveline);
- 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;
- }
- }
- line = line + new String(buf, 0, i);
+ headers.addHeaderField (null, line);
- // 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)
- {
- // A zero length entry signals the end of the headers.
- if (line.length() == 0)
- break;
-
- // Store the header and reinitialize for next cycle.
- hdrVec.addElement(line);
- String key = getKey(line);
- if (key != null)
- hdrHash.put(key.toLowerCase(), getField(line));
- line = "";
- ch[0] = (byte) '\n';
- gotnl = false;
- }
+ line = line.substring (idx + 1);
+ String code = line.substring (0, 3);
+
+ try
+ {
+ responseCode = Integer.parseInt (code);
+ }
+ catch (NumberFormatException e)
+ {
+ throw new IOException ("Server reply was unparseable: " + saveline);
+ }
+
+ responseMessage = line.substring (4);
+
+ // Now read the header lines
+ String key = null, value = null;
+
+ while (true)
+ {
+ line = inputStream.readLine();
+
+ if (line.equals(""))
+ break;
+
+ // 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)
+ {
+ 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 @@ public final class Connection extends HttpURLConnection
return null;
}
- return (String) hdrHash.get(name.toLowerCase());
+ return (String) headers.getHeaderFieldValueByKey(name.toLowerCase());
}
public Map getHeaderFields()
@@ -362,7 +395,7 @@ public final class Connection extends HttpURLConnection
return null;
}
- return hdrHash;
+ return headers.getHeaderFields();
}
/**
@@ -386,9 +419,7 @@ public final class Connection extends HttpURLConnection
return null;
}
- if (n < hdrVec.size())
- return getField ((String) hdrVec.elementAt(n));
- return null;
+ return headers.getHeaderFieldValueByIndex (n);
}
/**
@@ -412,30 +443,6 @@ public final class Connection extends HttpURLConnection
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);
}
}
OpenPOWER on IntegriCloud